unitypredict 0.1.18__tar.gz → 1.1.43__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.
@@ -0,0 +1,41 @@
1
+ Metadata-Version: 2.1
2
+ Name: unitypredict
3
+ Version: 1.1.43
4
+ Summary:
5
+ Home-page: https://unitypredict.com
6
+ Author: UnityPredict
7
+ License:
8
+ Platform: UNKNOWN
9
+ Description-Content-Type: text/markdown
10
+
11
+ # UnityPredict API SDK
12
+
13
+
14
+ ## Installation
15
+ * You can use pip to install the ```unitypredict``` library.
16
+ ```bash
17
+ pip install unitypredict
18
+ ```
19
+
20
+ ## Usage
21
+
22
+ TFor detailed instructions on how to use the SDK, please refer to [Unitypredict API SDK](https://docs.unitypredict.com/sdk).
23
+
24
+
25
+
26
+
27
+ ## License
28
+ Copyright 2024 Unified Predictive Technologies
29
+
30
+ Licensed under the Apache License, Version 2.0 (the "License");
31
+ you may not use this file except in compliance with the License.
32
+ You may obtain a copy of the License at
33
+
34
+ http://www.apache.org/licenses/LICENSE-2.0
35
+
36
+ Unless required by applicable law or agreed to in writing, software
37
+ distributed under the License is distributed on an "AS IS" BASIS,
38
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
39
+ See the License for the specific language governing permissions and
40
+ limitations under the License.
41
+
@@ -0,0 +1,30 @@
1
+ # UnityPredict API SDK
2
+
3
+
4
+ ## Installation
5
+ * You can use pip to install the ```unitypredict``` library.
6
+ ```bash
7
+ pip install unitypredict
8
+ ```
9
+
10
+ ## Usage
11
+
12
+ TFor detailed instructions on how to use the SDK, please refer to [Unitypredict API SDK](https://docs.unitypredict.com/sdk).
13
+
14
+
15
+
16
+
17
+ ## License
18
+ Copyright 2024 Unified Predictive Technologies
19
+
20
+ Licensed under the Apache License, Version 2.0 (the "License");
21
+ you may not use this file except in compliance with the License.
22
+ You may obtain a copy of the License at
23
+
24
+ http://www.apache.org/licenses/LICENSE-2.0
25
+
26
+ Unless required by applicable law or agreed to in writing, software
27
+ distributed under the License is distributed on an "AS IS" BASIS,
28
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
29
+ See the License for the specific language governing permissions and
30
+ limitations under the License.
@@ -1,24 +1,32 @@
1
1
  from setuptools import setup, find_packages
2
+ import os, sys
3
+
4
+
5
+ packageVersion = os.getenv("PyLibVersion", "0.0.1")
6
+ print ("Setting up package version: {}".format(packageVersion))
7
+
2
8
 
3
9
  description = ""
4
10
  with open("README.md", "r") as rdf:
5
11
  description = rdf.read()
6
12
 
7
- print ("Possible packages: {}".format(find_packages()))
8
13
 
9
14
  setup (
10
15
  name="unitypredict",
11
- version="0.1.18",
16
+ version=packageVersion,
12
17
  packages=find_packages(),
13
18
  install_requires=[
14
19
  # Currently no dependencies
20
+ "attr",
21
+ "cattrs",
22
+ "requests",
15
23
  ],
16
24
  entry_points = { # this here is the magic that binds your function into a callable script
17
- 'console_scripts':
18
- [
19
- 'uptools=unitypredict.scripts:main'
20
- ],
21
25
  },
26
+ description=" ",
22
27
  long_description=description,
23
- long_description_content_type="text/markdown"
28
+ long_description_content_type="text/markdown",
29
+ license=" ",
30
+ url="https://unitypredict.com",
31
+ author="UnityPredict"
24
32
  )
@@ -0,0 +1,331 @@
1
+
2
+ from io import IOBase
3
+ import json
4
+ import os
5
+ import time
6
+
7
+ import requests
8
+
9
+ class UnityPredictFileTransmitDto:
10
+ FileName: str = ''
11
+ FileHandle: IOBase = None
12
+
13
+ def __init__(self, fileName, fileHandle):
14
+ self.FileName = fileName
15
+ self.FileHandle = fileHandle
16
+
17
+ class UnityPredictFileReceivedDto:
18
+ FileName: str = ''
19
+ LocalFilePath: str = ''
20
+
21
+ def __init__(self, fileName, localFilePath):
22
+ self.FileName = fileName
23
+ self.LocalFilePath = localFilePath
24
+
25
+ class UnityPredictRequest:
26
+ ContextId: str = ''
27
+ InputValues: dict
28
+ DesiredOutcomes: list
29
+ OutputFolderPath: str
30
+
31
+ def __init__(self, ContextId='', InputValues={}, DesiredOutcomes=[], OutputFolderPath=""):
32
+ self.ContextId = ContextId
33
+ self.InputValues = InputValues
34
+ self.DesiredOutcomes = DesiredOutcomes
35
+ self.OutputFolderPath = OutputFolderPath
36
+
37
+
38
+ class UnityPredictResponse:
39
+ ContextId: str = ''
40
+ RequestId: str = ''
41
+ ErrorMessages: str = ''
42
+ ComputeCost: float = 0.0
43
+ OutcomeValues: dict = {}
44
+ Outcomes: dict = {}
45
+ Status: str|None = None
46
+
47
+ class UnityPredictClient:
48
+ ApiKey: str = ''
49
+ ApiBaseUrl: str = 'https://api.prod.unitypredict.com/api'
50
+ ApiMaxTimeout: int = 12 * 60 * 60
51
+
52
+ # Async Variables
53
+ _asyncResult: UnityPredictResponse = None
54
+ _asyncResponseJson: any = {}
55
+
56
+ def __init__(self, apiKey, apiMaxTimeoutInSec = 12 * 60 * 60):
57
+ self.ApiKey = f"APIKEY@{apiKey}"
58
+ self.ApiMaxTimeout = apiMaxTimeoutInSec
59
+ self._asyncResult = UnityPredictResponse()
60
+
61
+
62
+
63
+ def _uploadFileAndStartPredict(self, modelId: str, request: UnityPredictRequest):
64
+
65
+ apiKey = self.ApiKey
66
+ apiBaseUrl = self.ApiBaseUrl
67
+
68
+ results = UnityPredictResponse()
69
+ needFileUpload = False
70
+
71
+ #####
72
+ # The request can contain file objects so we need to change those to file names before sending out
73
+ #####
74
+ # first get a list of file that we'll need to upload later & update the POST obj
75
+ for xvarName in request.InputValues:
76
+ if isinstance(request.InputValues.get(xvarName), UnityPredictFileTransmitDto):
77
+ needFileUpload = True
78
+ break
79
+
80
+ finalResponseJson: any = ''
81
+
82
+ response: requests.Response = None
83
+ if not needFileUpload:
84
+ # serialize the POST obj
85
+ jsonBody = json.dumps(request, default=vars)
86
+
87
+ # there are no files to upload so just post normally
88
+ response = requests.post(url = "{}/predict/{}".format(apiBaseUrl, modelId), data=jsonBody, headers={"Authorization": "Bearer {}".format(apiKey)})
89
+
90
+ if response.status_code != 200:
91
+ results.ErrorMessages = 'Error from server: {}'.format(response.status_code)
92
+ return (results, {})
93
+
94
+ finalResponseJson = response.json()
95
+ else:
96
+ # we need to initialize first
97
+ print ("Initializing Platform ...")
98
+ response = requests.post(url = "{}/predict/initialize/{}".format(apiBaseUrl, modelId), data="", headers={"Authorization": "Bearer {}".format(apiKey)})
99
+
100
+
101
+ if response.status_code != 200:
102
+ results.ErrorMessages = 'Error from server: {}'.format(response.status_code)
103
+ return (results, {})
104
+
105
+ print ("Platform Initialized!")
106
+ requestId: str = response.json().get('requestId')
107
+
108
+ # print (f"Initialized request: {requestId}")
109
+
110
+ # upload the files
111
+ for xvarName in request.InputValues:
112
+ if isinstance(request.InputValues.get(xvarName), UnityPredictFileTransmitDto):
113
+ fileToUpload: UnityPredictFileTransmitDto = request.InputValues.get(xvarName)
114
+ print (f"Uploading {fileToUpload.FileName}...")
115
+ response = requests.get(url = "{}/predict/upload/{}/{}".format(apiBaseUrl, requestId, fileToUpload.FileName), headers={"Authorization": "Bearer {}".format(apiKey)})
116
+ if response.status_code != 200:
117
+ results.ErrorMessages = 'Error from server: {}'.format(response.status_code)
118
+ return (results, {})
119
+ uploadLink = response.json().get('uploadLink')
120
+ fileName = response.json().get('fileName')
121
+ request.InputValues[xvarName] = fileName # make sure that only the filename is in the request that we are going to POST
122
+ requests.put(url = uploadLink, data=fileToUpload.FileHandle)
123
+ print (f"Upload file {fileToUpload.FileName} Success!")
124
+
125
+ # print (f"Input request: {request.InputValues}")
126
+ jsonBody = json.dumps(request, default=vars)
127
+
128
+ # print (f"URL: {"{}/predict/{}/{}".format(apiBaseUrl, modelId, requestId)}, body: {jsonBody}")
129
+ response = requests.post(url = "{}/predict/{}/{}".format(apiBaseUrl, modelId, requestId), data=jsonBody, headers={"Authorization": "Bearer {}".format(apiKey)})
130
+
131
+ if response.status_code != 200:
132
+ results.ErrorMessages = 'Error from server: {}'.format(response.status_code)
133
+ return (results, {})
134
+
135
+ finalResponseJson = response.json()
136
+
137
+ return (results, finalResponseJson)
138
+
139
+
140
+ def _processPredictedInference(self, responseJson: any, outputFolderPath: str = ""):
141
+
142
+ results = UnityPredictResponse()
143
+
144
+ apiKey = self.ApiKey
145
+ apiBaseUrl = self.ApiBaseUrl
146
+ finalResponseJson = responseJson
147
+
148
+ finalResponseRequestId: str = finalResponseJson.get('requestId')
149
+
150
+ outcomeValues = finalResponseJson.get('outcomeValues')
151
+ for outputVarName in outcomeValues:
152
+ outcome: dict = outcomeValues.get(outputVarName)
153
+ if outcome.get('dataType') == 'File':
154
+
155
+ tempOutputFolder: str = os.path.join(outputFolderPath, "chainedResults", finalResponseRequestId)
156
+ if not os.path.exists(tempOutputFolder):
157
+ os.makedirs(tempOutputFolder)
158
+
159
+ fileName = outcome.get('value')
160
+
161
+ tempFilePath = os.path.join(tempOutputFolder, fileName)
162
+ response = requests.get(url = "{}/predict/download/{}/{}".format(apiBaseUrl, finalResponseRequestId, fileName), headers={"Authorization": "Bearer {}".format(apiKey)})
163
+ with open(tempFilePath, 'wb') as f:
164
+ f.write(response.content)
165
+
166
+ fileReceived: UnityPredictFileReceivedDto = UnityPredictFileReceivedDto(fileName, tempFilePath)
167
+ outcome['value'] = fileReceived
168
+
169
+ outcomes = finalResponseJson.get('outcomes')
170
+ for outputVarName in outcomes:
171
+ outcome: list = outcomes.get(outputVarName)
172
+ for outcomeItem in outcome:
173
+ if outcomeItem.get('dataType') == 'File':
174
+ fileName = outcomeItem.get('value')
175
+
176
+ tempFilePath = os.path.join(tempOutputFolder, fileName)
177
+ response = requests.get(url = "{}/predict/download/{}/{}".format(apiBaseUrl, finalResponseRequestId, fileName), headers={"Authorization": "Bearer {}".format(apiKey)})
178
+ with open(tempFilePath, 'wb') as f:
179
+ f.write(response.content)
180
+
181
+ fileReceived: UnityPredictFileReceivedDto = UnityPredictFileReceivedDto(fileName, tempFilePath)
182
+ outcomeItem['value'] = fileReceived
183
+
184
+
185
+ try:
186
+ results.ComputeCost = finalResponseJson.get('computeCost')
187
+ results.OutcomeValues = outcomeValues
188
+ results.Outcomes = outcomes
189
+ results.RequestId = finalResponseRequestId
190
+ results.ContextId = finalResponseJson.get('contextId')
191
+ results.ErrorMessages = finalResponseJson.get('errorMessages')
192
+
193
+ except Exception as e:
194
+ print(e)
195
+
196
+ return results
197
+
198
+
199
+ def Predict(self, modelId: str, request: UnityPredictRequest) -> UnityPredictResponse:
200
+ results = UnityPredictResponse()
201
+
202
+ apiKey = self.ApiKey
203
+ apiBaseUrl = self.ApiBaseUrl
204
+
205
+ needFileUpload: bool = False
206
+
207
+ #####
208
+ # The request can contain file objects so we need to change those to file names before sending out
209
+ #####
210
+ # first get a list of file that we'll need to upload later & update the POST obj
211
+
212
+
213
+ results, finalResponseJson = self._uploadFileAndStartPredict(modelId=modelId, request=request)
214
+
215
+ if (finalResponseJson == {}):
216
+ return results
217
+
218
+ statusUrl = ''
219
+ if (finalResponseJson.get('status') == 'Processing'):
220
+ statusUrl = finalResponseJson.get('statusUrl') # this is probably a long-running inference
221
+
222
+ loopCount = 0
223
+ startTime = time.time()
224
+ maxPredictTime = self.ApiMaxTimeout
225
+ maxTimeExceed = False
226
+ print (f"Starting max inference timer for {maxPredictTime} Seconds")
227
+ while finalResponseJson.get('status') == 'Processing': # todo: add timeout in UnityPredictRequest
228
+
229
+ if ((time.time() - startTime) > maxPredictTime):
230
+ print (f"Max time limit of {maxPredictTime} seconds exceeded!")
231
+ maxTimeExceed = True
232
+ break
233
+
234
+ response = requests.get(url = statusUrl, headers={"Authorization": "Bearer {}".format(apiKey)})
235
+ finalResponseJson = response.json()
236
+
237
+ delay = min(loopCount * 2, 30)
238
+ time.sleep(delay)
239
+
240
+ loopCount = loopCount + 1
241
+
242
+ print('Waiting {} seconds for job to finish...'.format(delay))
243
+
244
+ if maxTimeExceed:
245
+ results = UnityPredictResponse()
246
+ results.Status = None
247
+ results.ErrorMessages = f"Max time limit of {maxPredictTime} seconds exceeded!"
248
+ return results
249
+
250
+ try:
251
+ results = self._processPredictedInference(responseJson=finalResponseJson, outputFolderPath=request.OutputFolderPath)
252
+ results.Status = finalResponseJson.get('status')
253
+ except Exception as e:
254
+ results = UnityPredictResponse()
255
+ results.Status = None
256
+ results.ErrorMessages = f"Exception Occured while processing Inference: {e}"
257
+
258
+ return results
259
+
260
+ def AsyncPredict(self, modelId: str, request: UnityPredictRequest):
261
+
262
+ #####
263
+ # The request can contain file objects so we need to change those to file names before sending out
264
+ #####
265
+ # first get a list of file that we'll need to upload later & update the POST obj
266
+
267
+ try:
268
+
269
+ results, finalResponseJson = self._uploadFileAndStartPredict(modelId=modelId, request=request)
270
+
271
+ self._asyncResult = results
272
+ self._asyncResponseJson = finalResponseJson
273
+
274
+ except Exception as e:
275
+
276
+ self._asyncResult.ErrorMessages = f"Predict Exception Occured: {e}"
277
+
278
+
279
+ def AsyncInference(self, outputFolderPath: str = ""):
280
+
281
+ self._asyncResult.Status = self._asyncResponseJson.get("status", None)
282
+ statusUrl = self._asyncResponseJson.get('statusUrl', None)
283
+
284
+ apiKey = self.ApiKey
285
+
286
+ inferStatus = self._asyncResult.Status
287
+ if inferStatus == 'Processing':
288
+
289
+ if statusUrl == None:
290
+ self._asyncResult.Status = None
291
+ return self._asyncResult
292
+
293
+ response = requests.get(url = statusUrl, headers={"Authorization": "Bearer {}".format(apiKey)})
294
+ finalResponseJson = response.json()
295
+
296
+ inferStatus = finalResponseJson.get('status', None)
297
+ self._asyncResult.Status = inferStatus
298
+
299
+ if (inferStatus == None):
300
+ return self._asyncResult
301
+
302
+ if (inferStatus == 'Processing'):
303
+ return self._asyncResult
304
+
305
+ elif inferStatus == None:
306
+ return self._asyncResult
307
+
308
+ else:
309
+ finalResponseJson = self._asyncResponseJson
310
+
311
+
312
+ # Once the processing is done
313
+
314
+ try:
315
+ self._asyncResult = self._processPredictedInference(responseJson=finalResponseJson, outputFolderPath=outputFolderPath)
316
+ self._asyncResult.Status = inferStatus
317
+ except Exception as e:
318
+ self._asyncResult = UnityPredictResponse()
319
+ self._asyncResult.ErrorMessages = f"Exception Occured while processing Inference: {e}"
320
+
321
+ return self._asyncResult
322
+
323
+ def AsyncResponse(self):
324
+
325
+ return self._asyncResponseJson
326
+
327
+
328
+
329
+
330
+
331
+
@@ -0,0 +1 @@
1
+ from .UnityPredictClient import *
@@ -0,0 +1,41 @@
1
+ Metadata-Version: 2.1
2
+ Name: unitypredict
3
+ Version: 1.1.43
4
+ Summary:
5
+ Home-page: https://unitypredict.com
6
+ Author: UnityPredict
7
+ License:
8
+ Platform: UNKNOWN
9
+ Description-Content-Type: text/markdown
10
+
11
+ # UnityPredict API SDK
12
+
13
+
14
+ ## Installation
15
+ * You can use pip to install the ```unitypredict``` library.
16
+ ```bash
17
+ pip install unitypredict
18
+ ```
19
+
20
+ ## Usage
21
+
22
+ TFor detailed instructions on how to use the SDK, please refer to [Unitypredict API SDK](https://docs.unitypredict.com/sdk).
23
+
24
+
25
+
26
+
27
+ ## License
28
+ Copyright 2024 Unified Predictive Technologies
29
+
30
+ Licensed under the Apache License, Version 2.0 (the "License");
31
+ you may not use this file except in compliance with the License.
32
+ You may obtain a copy of the License at
33
+
34
+ http://www.apache.org/licenses/LICENSE-2.0
35
+
36
+ Unless required by applicable law or agreed to in writing, software
37
+ distributed under the License is distributed on an "AS IS" BASIS,
38
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
39
+ See the License for the specific language governing permissions and
40
+ limitations under the License.
41
+
@@ -0,0 +1,9 @@
1
+ README.md
2
+ setup.py
3
+ unitypredict/UnityPredictClient.py
4
+ unitypredict/__init__.py
5
+ unitypredict.egg-info/PKG-INFO
6
+ unitypredict.egg-info/SOURCES.txt
7
+ unitypredict.egg-info/dependency_links.txt
8
+ unitypredict.egg-info/requires.txt
9
+ unitypredict.egg-info/top_level.txt
@@ -0,0 +1,3 @@
1
+ attr
2
+ cattrs
3
+ requests