gmicloud 0.1.3__py3-none-any.whl → 0.1.4__py3-none-any.whl

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.
@@ -2,7 +2,6 @@ import requests
2
2
  from .._exceptions import APIError
3
3
  from .._exceptions import UnauthorizedError
4
4
  from .._constants import *
5
- from .._config import *
6
5
 
7
6
 
8
7
  class HTTPClient:
@@ -34,12 +34,35 @@ class IAMClient:
34
34
  custom_headers = {
35
35
  CLIENT_ID_HEADER: self._client_id
36
36
  }
37
- req = LoginRequest(email=self._email, password=self._password)
38
- result = self.client.post("/me/sessions", custom_headers, req.model_dump())
39
-
40
- resp = LoginResponse.model_validate(result)
41
- self._access_token = resp.accessToken
42
- self._refresh_token = resp.refreshToken
37
+ req = AuthTokenRequest(email=self._email, password=self._password)
38
+ auth_tokens_result = self.client.post("/me/auth-tokens", custom_headers, req.model_dump())
39
+ auth_tokens_resp = AuthTokenResponse.model_validate(auth_tokens_result)
40
+
41
+ create_session_result = None
42
+ if auth_tokens_resp.is2FARequired:
43
+ max_attempts = 3
44
+ for attempt in range(max_attempts):
45
+ code = input(f"Attempt {attempt + 1}/{max_attempts}: Please enter the 2FA code: ")
46
+
47
+ create_session_req = CreateSessionRequest(
48
+ type="native", authToken=auth_tokens_resp.authToken, otpCode=code
49
+ )
50
+ try:
51
+ create_session_result = self.client.post(
52
+ "/me/sessions", custom_headers, create_session_req.model_dump()
53
+ )
54
+ break
55
+ except Exception as e:
56
+ print("Invalid 2FA code, please try again.")
57
+ if attempt == max_attempts - 1:
58
+ raise Exception("Failed to create session after 3 incorrect 2FA attempts.") from e
59
+ else:
60
+ create_session_req = CreateSessionRequest(type="native", authToken=auth_tokens_resp.authToken, otpCode=None)
61
+ create_session_result = self.client.post("/me/sessions", custom_headers, create_session_req.model_dump())
62
+
63
+ create_session_resp = CreateSessionResponse.model_validate(create_session_result)
64
+ self._access_token = create_session_resp.accessToken
65
+ self._refresh_token = create_session_resp.refreshToken
43
66
  self._user_id = self.parse_user_id()
44
67
 
45
68
  def refresh_token(self):
@@ -51,7 +74,7 @@ class IAMClient:
51
74
  }
52
75
  result = self.client.patch("/me/sessions", custom_headers, {"refreshToken": self._refresh_token})
53
76
 
54
- resp = LoginResponse.model_validate(result)
77
+ resp = CreateSessionResponse.model_validate(result)
55
78
  self._access_token = resp.accessToken
56
79
  self._refresh_token = resp.refreshToken
57
80
 
@@ -307,10 +307,35 @@ class CreateTaskResponse(BaseModel):
307
307
  upload_link: str # URL to upload the task data.
308
308
 
309
309
 
310
- class LoginResponse(BaseModel):
310
+ class AuthTokenRequest(BaseModel):
311
+ """
312
+ Request object for user login.
313
+ """
314
+ email: str # User email.
315
+ password: str # User password.
316
+
317
+
318
+ class AuthTokenResponse(BaseModel):
311
319
  """
312
320
  Response object for user login.
313
321
  """
322
+ authToken: str # Access token for the user session.
323
+ is2FARequired: bool # Indicates if 2FA is required for the user.
324
+
325
+
326
+ class CreateSessionRequest(BaseModel):
327
+ """
328
+ Request object for creating a user session.
329
+ """
330
+ type: str # Type of the session (e.g., native).
331
+ authToken: str # Access token for the user session.
332
+ otpCode: Optional[str] # 2FA code for the user session.
333
+
334
+
335
+ class CreateSessionResponse(BaseModel):
336
+ """
337
+ Response object for creating a user session.
338
+ """
314
339
  accessToken: str # Access token for the user session.
315
340
  refreshToken: str # Refresh token for the user session.
316
341
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: gmicloud
3
- Version: 0.1.3
3
+ Version: 0.1.4
4
4
  Summary: GMI Cloud Python SDK
5
5
  Author-email: GMI <gmi@gmitec.net>
6
6
  License: MIT
@@ -14,7 +14,8 @@ Description-Content-Type: text/markdown
14
14
 
15
15
  ## Overview
16
16
 
17
- Before you start: Our service and GPU resource is currenly invite-only so please contact our team (getstarted@gmicloud.ai) to get invited if you don't have one yet.
17
+ Before you start: Our service and GPU resource is currenly invite-only so please contact our team (
18
+ getstarted@gmicloud.ai) to get invited if you don't have one yet.
18
19
 
19
20
  The GMI Inference Engine SDK provides a Python interface for deploying and managing machine learning models in
20
21
  production environments. It allows users to create model artifacts, schedule tasks for serving models, and call
@@ -64,7 +65,18 @@ client = Client(client_id="<YOUR_CLIENT_ID>", email="<YOUR_EMAIL>", password="<Y
64
65
 
65
66
  ## Quick Start
66
67
 
67
- ### 1. Create a Task from an Artifact Template
68
+ ### 1. How to run the code in the example folder
69
+ ```bash
70
+ cd path/to/gmicloud-sdk
71
+ # Create a virtual environment
72
+ python -m venv venv
73
+ source venv/bin/activate
74
+
75
+ pip install -r requirements.txt
76
+ python -m examples.<example_name>
77
+ ```
78
+
79
+ ### 2. Create a Task from an Artifact Template
68
80
 
69
81
  This is the simplest example to deploy an existing artifact template:
70
82
 
@@ -93,24 +105,30 @@ response = call_chat_completion(client, task.task_id)
93
105
  print(response)
94
106
  ```
95
107
 
96
- ### 2. Step-by-Step Example: Create Artifact, Task, and Query the Endpoint
108
+ ### 3. Step-by-Step Example: Create Artifact, Task, and Query the Endpoint
97
109
 
98
110
  #### (a) Create an Artifact from a Template
99
111
 
100
112
  First, you’ll retrieve all templates and create an artifact based on the desired template (e.g., "Llama3.1 8B"):
101
113
 
102
114
  ```python
103
- def create_artifact_from_template(client):
115
+ from gmicloud import *
116
+
117
+ def create_artifact_from_template(client: Client) -> str:
104
118
  artifact_manager = client.artifact_manager
105
119
 
106
- # List all available templates
120
+ # Get all artifact templates
107
121
  templates = artifact_manager.get_artifact_templates()
108
122
  for template in templates:
109
123
  if template.artifact_template_id == "qwen_2.5_14b_instruct_template_001":
110
- return artifact_manager.create_artifact_from_template(
111
- artifact_template_id=template.artifact_template_id
124
+ # Create an artifact from a template
125
+ artifact_id = artifact_manager.create_artifact_from_template(
126
+ artifact_template_id=template.artifact_template_id,
112
127
  )
113
- return None
128
+
129
+ return artifact_id
130
+
131
+ return ""
114
132
  ```
115
133
 
116
134
  #### (b) Create a Task from the Artifact
@@ -118,43 +136,55 @@ def create_artifact_from_template(client):
118
136
  Wait until the artifact becomes "ready" and then deploy it using task scheduling:
119
137
 
120
138
  ```python
121
- def create_task_and_start(client, artifact_id):
122
- artifact_manager = client.artifact_manager
139
+ from gmicloud import *
140
+ import time
141
+ from datetime import datetime
123
142
 
124
- # Wait until the artifact is ready
143
+ def create_task_and_start(client: Client, artifact_id: str) -> str:
144
+ artifact_manager = client.artifact_manager
145
+ # Wait for the artifact to be ready
125
146
  while True:
126
- artifact = artifact_manager.get_artifact(artifact_id)
127
- if artifact.build_status == "SUCCESS":
128
- break
129
- print("Waiting for artifact to be ready...")
147
+ try:
148
+ artifact = artifact_manager.get_artifact(artifact_id)
149
+ print(f"Artifact status: {artifact.build_status}")
150
+ # Wait until the artifact is ready
151
+ if artifact.build_status == BuildStatus.SUCCESS:
152
+ break
153
+ except Exception as e:
154
+ raise e
155
+ # Wait for 2 seconds
130
156
  time.sleep(2)
131
-
132
- # Configure and start the task
133
- task_manager = client.task_manager
134
- task = task_manager.create_task(Task(
135
- config=TaskConfig(
136
- ray_task_config=RayTaskConfig(
137
- ray_version="2.40.0-py310-gpu",
138
- file_path="serve",
139
- artifact_id=artifact_id,
140
- deployment_name="app",
141
- replica_resource=ReplicaResource(
142
- cpu=10,
143
- ram_gb=100,
144
- gpu=1,
157
+ try:
158
+ task_manager = client.task_manager
159
+ # Create a task
160
+ task = task_manager.create_task(Task(
161
+ config=TaskConfig(
162
+ ray_task_config=RayTaskConfig(
163
+ ray_version="2.40.0-py310-gpu",
164
+ file_path="serve",
165
+ artifact_id=artifact_id,
166
+ deployment_name="app",
167
+ replica_resource=ReplicaResource(
168
+ cpu=10,
169
+ ram_gb=100,
170
+ gpu=1,
171
+ ),
172
+ ),
173
+ task_scheduling=TaskScheduling(
174
+ scheduling_oneoff=OneOffScheduling(
175
+ trigger_timestamp=int(datetime.now().timestamp()) + 10,
176
+ min_replicas=1,
177
+ max_replicas=10,
178
+ )
145
179
  ),
146
180
  ),
147
- task_scheduling=TaskScheduling(
148
- scheduling_oneoff=OneOffScheduling(
149
- trigger_timestamp=int(datetime.now().timestamp()) + 10,
150
- min_replicas=1,
151
- max_replicas=10,
152
- )
153
- ),
154
- ),
155
- ))
181
+ ))
182
+
183
+ # Start the task
184
+ task_manager.start_task(task.task_id)
185
+ except Exception as e:
186
+ raise e
156
187
 
157
- task_manager.start_task(task.task_id)
158
188
  return task.task_id
159
189
  ```
160
190
 
@@ -163,14 +193,20 @@ def create_task_and_start(client, artifact_id):
163
193
  Once the task is running, use the endpoint for inference:
164
194
 
165
195
  ```python
196
+ from gmicloud import *
166
197
  from examples.completion import call_chat_completion
167
198
 
168
- client = Client()
169
- artifact_id = create_artifact_from_template(client)
170
- task_id = create_task_and_start(client, artifact_id)
199
+ # Initialize the Client
200
+ cli = Client()
171
201
 
172
- response = call_chat_completion(client, task_id)
173
- print(response)
202
+ # Create an artifact from a template
203
+ artifact_id = create_artifact_from_template(cli)
204
+
205
+ # Create a task and start it
206
+ task_id = create_task_and_start(cli, artifact_id)
207
+
208
+ # Call chat completion
209
+ print(call_chat_completion(cli, task_id))
174
210
  ```
175
211
 
176
212
  ## API Reference
@@ -5,13 +5,13 @@ gmicloud/_internal/_config.py,sha256=qIH76TSyS3MQWe62LHI46RJhDnklNFisdajY75oUAqE
5
5
  gmicloud/_internal/_constants.py,sha256=Y085dwFlqdFkCf39iBfxz39QiiB7lX59ayNJjB86_m4,378
6
6
  gmicloud/_internal/_enums.py,sha256=C4oy6Ps7OGdYd3tK-Wcpi6uXMyAKbOZW8_KykYAKsgw,510
7
7
  gmicloud/_internal/_exceptions.py,sha256=hScBq7n2fOit4_umlkabZJchY8zVbWSRfWM2Y0rLCbw,306
8
- gmicloud/_internal/_models.py,sha256=1yUk1yIyfXybIeR8guwYLbXc8gAKzXRpIZ7_6SOId28,13212
8
+ gmicloud/_internal/_models.py,sha256=4YT1MI2V1YEBWBFEvrA6pRcmxkZCgi6rzTxYMRgfeWs,13880
9
9
  gmicloud/_internal/_client/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
10
  gmicloud/_internal/_client/_artifact_client.py,sha256=py6SQ1tVoK365hIIxnla433mpCapActZ6KE6Yakds-8,5588
11
11
  gmicloud/_internal/_client/_decorator.py,sha256=sy4gxzsUB6ORXHw5pqmMf7TTlK41Nmu1fhIhK2AIsbY,670
12
12
  gmicloud/_internal/_client/_file_upload_client.py,sha256=1JRs4X57S3EScPIP9w2DC1Uo6_Wbcjumcw3nVM7uIGM,4667
13
- gmicloud/_internal/_client/_http_client.py,sha256=F7qpq6WLp6PJkqusWojdi483LijWBsSIY43NjJcyXNU,5704
14
- gmicloud/_internal/_client/_iam_client.py,sha256=D7PhQerSzjGGerXsd5Si-e-Wa5f-fJpOACkfWOnkPJg,2979
13
+ gmicloud/_internal/_client/_http_client.py,sha256=JZvw7HnCwyk6_5-Ja-KZuYY0JBJApx9I3jZ0G_J2kWw,5680
14
+ gmicloud/_internal/_client/_iam_client.py,sha256=xEDiwwpj1dAHmAOzcu9Jz7x1F3TRJLrCAqNXPQ-wyoU,4310
15
15
  gmicloud/_internal/_client/_task_client.py,sha256=JgYewfDy2iblRVrc9sdA8RbcooXyAho79ESuCK8PRWI,3842
16
16
  gmicloud/_internal/_manager/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
17
17
  gmicloud/_internal/_manager/_artifact_manager.py,sha256=cc367Kd-W9Zn2d_wUcG6tT06544HRItIZ5IsFfA5_RQ,12201
@@ -20,7 +20,7 @@ gmicloud/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
20
20
  gmicloud/tests/test_artifacts.py,sha256=YiC1HBMS7g491Ra4acTLI9AdwyjXZfnY9f-fNKn2azQ,17108
21
21
  gmicloud/tests/test_tasks.py,sha256=AY90zTJdsXk1cxn6Jxhi4TDdwXRiGxz_r_aRk_Jkl8Y,10956
22
22
  gmicloud/utils/uninstall_packages.py,sha256=zzuuaJPf39oTXWZ_7tUAGseoxocuCbbkoglJSD5yDrE,1127
23
- gmicloud-0.1.3.dist-info/METADATA,sha256=OuNXnrFTE_tTDuArqevbW81fKwB--E23YUv6-uj91u0,6808
24
- gmicloud-0.1.3.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
25
- gmicloud-0.1.3.dist-info/top_level.txt,sha256=AZimLw3y0WPpLiSiOidZ1gD0dxALh-jQNk4fxC05hYE,9
26
- gmicloud-0.1.3.dist-info/RECORD,,
23
+ gmicloud-0.1.4.dist-info/METADATA,sha256=hwFbxM2blSJZQnRT-9x6y-ilfcgFL6_tdQP2f12TloQ,7689
24
+ gmicloud-0.1.4.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
25
+ gmicloud-0.1.4.dist-info/top_level.txt,sha256=AZimLw3y0WPpLiSiOidZ1gD0dxALh-jQNk4fxC05hYE,9
26
+ gmicloud-0.1.4.dist-info/RECORD,,