11
11
# See the License for the specific language governing permissions and
12
12
# limitations under the License
13
13
14
+ import ast
14
15
import json
15
- import os
16
16
import random
17
17
import string
18
18
import time
19
19
from enum import Enum
20
20
21
- from runtime .dbapi .pyalisa .config import Config
22
21
from runtime .dbapi .pyalisa .pop import Pop
23
22
24
23
@@ -35,15 +34,15 @@ class AlisaTaksStatus(Enum):
35
34
ALISA_TASK_ALLOCATE = 11
36
35
37
36
38
- # used to deal with too many logs.
37
+ # used to deal with too many logs
39
38
MAX_LOG_NUM = 2000
40
39
41
40
42
41
class Client (object ):
43
42
"""Client for building kinds of tasks and submitting them to alisa gateway
44
43
45
44
Args:
46
- config(Config): the config for build the client
45
+ config(Config): the Config(runtime.dbapi.pyalisa. config)
47
46
"""
48
47
def __init__ (self , config ):
49
48
self .config = config # noqa F841
@@ -93,7 +92,6 @@ def create_pyodps_task(self, code, args):
93
92
params ["Exec" ] = self .config .withs ["Exec4PyODPS" ]
94
93
if len (args ) > 0 :
95
94
params ["Args" ] = args
96
-
97
95
return self ._create_task (params )
98
96
99
97
def _create_task (self , params ):
@@ -168,12 +166,12 @@ def read_logs(self, task_id, offset, w):
168
166
params ["AlisaTaskId" ] = task_id
169
167
params ["Offset" ] = str (offset )
170
168
log = self ._requet_and_parse_response ("GetAlisaTaskLog" , params )
171
- rlen = int (log ["ReadLen " ])
169
+ rlen = int (log ["readLength " ])
172
170
if rlen == 0 :
173
171
return offset
174
172
offset += rlen
175
- w .write (log ["Content " ])
176
- if bool (log ["End " ]):
173
+ w .write (log ["logMsg " ])
174
+ if bool (log ["isEnd " ]):
177
175
return - 1
178
176
return offset
179
177
@@ -205,20 +203,23 @@ def get_results(self, task_id, batch):
205
203
if batch <= 0 :
206
204
raise ValueError ("batch should greater than 0" )
207
205
count = self .count_results (task_id )
208
- result = []
206
+
207
+ columns , body = [], []
209
208
for i in range (0 , count , batch ):
210
209
params = self ._base_params ()
211
210
params ["AlisaTaskId" ] = task_id
212
211
params ["Start" ] = str (i )
213
212
params ["Limit" ] = str (batch )
214
- r = self ._requet_and_parse_response ("GetAlisaTaskResult" , params )
215
- # TODO(lhw): parse the result like:
216
- # https://github.com/sql-machine-learning/goalisa/blob/68d3aad1344c9e5c0cd35c6556e1f3f2b6ca9db7/alisa.go#L190
217
- result .append (r )
218
- return result
213
+ val = self ._requet_and_parse_response ("GetAlisaTaskResult" , params )
214
+ header , rows = self ._parse_alisa_value (val )
215
+ if len (columns ) == 0 :
216
+ columns = header
217
+ body .extend (rows )
218
+ return {"columns" : columns , "body" : body }
219
219
220
220
def stop (self , task_id ):
221
- """Stop given task
221
+ """Stop given task.
222
+ NOTE(weiguoz): need to be tested.
222
223
223
224
Args:
224
225
task_id(string): the task to stop
@@ -231,51 +232,38 @@ def stop(self, task_id):
231
232
res = self ._requet_and_parse_response ("StopAlisaTask" , params )
232
233
return bool (res )
233
234
235
+ def _parse_alisa_value (self , val ):
236
+ """Parse 'returnValue' in alisa response
237
+ https://github.com/sql-machine-learning/goalisa/blob/68d3aad1344c9e5c0cd35c6556e1f3f2b6ca9db7/alisa.go#L190
238
+
239
+ Args:
240
+ val: [{u'resultMsg': u'[["Alice","23.8","56000"]]',
241
+ u'dataHeader': u'["name::string","age::double","salary::bigint"]'}]
242
+ """
243
+ jsval = ast .literal_eval (json .dumps (val ))
244
+ columns = []
245
+ for h in json .loads (jsval ['dataHeader' ]):
246
+ nt = h .split ("::" )
247
+ name , typ = (nt [0 ], nt [1 ]) if len (nt ) == 2 else (h , "string" )
248
+ columns .append ({"name" : str (name ), "typ" : str (typ )})
249
+ body = []
250
+ for m in json .loads (jsval ['resultMsg' ]):
251
+ row = []
252
+ for i in ast .literal_eval (json .dumps (m )):
253
+ row .append (i )
254
+ body .append (row )
255
+ return columns , body
256
+
234
257
def _requet_and_parse_response (self , action , params ):
235
258
params ["Action" ] = action
236
259
params ["ProjectEnv" ] = self .config .env ["SKYNET_SYSTEM_ENV" ]
237
260
url = self .config .pop_scheme + "://" + self .config .pop_url
238
261
code , buf = Pop .request (url , params , self .config .pop_access_secret )
239
262
resp = json .loads (buf )
240
263
if code != 200 :
241
- raise RuntimeError ("%s got a bad result, response=%s" %
242
- (code , buf ))
264
+ raise RuntimeError ("%s got a bad result, request=%s, response=%s" %
265
+ (code , params , buf ))
266
+ if resp ['returnCode' ] != '0' :
267
+ raise Exception ("returned an error request={}, response={}" .format (
268
+ params , resp ))
243
269
return resp ["returnValue" ]
244
-
245
- @staticmethod
246
- def from_env ():
247
- """Build a Client from environment variable
248
-
249
- Returns:
250
- a Client instance
251
- """
252
- if not os .getenv ("POP_SECRET" ):
253
- return None
254
- conf = Config ()
255
- conf .pop_url = os .getenv ("POP_URL" )
256
- conf .pop_access_id = os .getenv ("POP_ID" )
257
- conf .pop_access_secret = os .getenv ("POP_SECRET" )
258
- conf .pop_scheme = "http"
259
- conf .verbose = os .getenv ("VERBOSE" ) == "true"
260
- conf .env = {
261
- "SKYNET_ONDUTY" : os .getenv ("SKYNET_ONDUTY" ),
262
- "SKYNET_ACCESSID" : os .getenv ("SKYNET_ACCESSID" ),
263
- "SKYNET_ACCESSKEY" : os .getenv ("SKYNET_ACCESSKEY" ),
264
- "SKYNET_ENDPOINT" : os .getenv ("SKYNET_ENDPOINT" ),
265
- "SKYNET_SYSTEMID" : os .getenv ("SKYNET_SYSTEMID" ),
266
- "SKYNET_PACKAGEID" : os .getenv ("SKYNET_PACKAGEID" ),
267
- "SKYNET_SYSTEM_ENV" : os .getenv ("SKYNET_SYSTEM_ENV" ),
268
- "SKYNET_BIZDATE" : os .getenv ("SKYNET_BIZDATE" ),
269
- "ALISA_TASK_EXEC_TARGET" : os .getenv ("ALISA_TASK_EXEC_TARGET" ),
270
- }
271
- conf .withs = {
272
- "CustomerId" : os .getenv ("CustomerId" ),
273
- "PluginName" : os .getenv ("PluginName" ),
274
- "Exec" : os .getenv ("Exec" ),
275
- "PluginName4PyODPS" : os .getenv ("PluginName4PyODPS" ),
276
- "Exec4PyODPS" : os .getenv ("Exec4PyODPS" ),
277
- }
278
- conf .curr_project = conf .env ["SKYNET_PACKAGEID" ]
279
- if len (conf .env ["SKYNET_SYSTEMID" ]) > 0 :
280
- conf .curr_project += "_" + conf .env ["SKYNET_SYSTEMID" ]
281
- return Client (conf )
0 commit comments