def web_makePublicAppState(self): up = self.__getUP() try: name = self.request.arguments['name'][-1] except KeyError as excp: raise WErr(400, "Missing %s" % excp) try: access = self.request.arguments['access'][-1].upper() except KeyError as excp: access = 'ALL' if access not in ('ALL', 'VO', 'GROUP', 'USER'): raise WErr(400, "Invalid access") revokeAccess = {'ReadAccess': access} if access == 'USER': # if we make private a state, # we have to revoke from the public as well revokeAccess['PublishAccess'] = 'USER' # TODO: Check access is in either 'ALL', 'VO' or 'GROUP' result = yield self.threadTask(up.setVarPermissions, name, revokeAccess) if not result['OK']: raise WErr.fromSERROR(result) self.set_status(200) self.finish()
def web_file(self): """ Get the file information, use: GET /filecatalogue/file/<file>/attributes -- get the file information GET /filecatalogue/file/<file>/metadata -- get the file metadata """ optns = self.overpath.strip('/').split('/') if len(optns) > 2: raise WErr(404, "Wrone way") path = self.__decodePath() __obj = re.match("([a-z]+)?", optns[1]).group() if len(optns) > 1 else None if __obj == "attributes": result = yield self.threadTask(self.rpc.getFileMetadata, path) if not result['OK'] or path not in result['Value']['Successful']: raise WErr.fromError(result) self.finish( self.__sanitizeForJSON(result['Value']['Successful'][path])) elif __obj == "metadata": result = yield self.threadTask(self.rpc.getFileUserMetadata, path) if not result['OK']: raise WErr.fromError(result) self.finish(self.__sanitizeForJSON(result['Value'])) else: raise WErr(404, "WTF?")
def web_requestNew(self): # validate # * dataset # * srcse # * dstse # * protocol self.log.debug(self.request.arguments) valid_list = ["dataset", "srcse", "dstse", "protocol"] build_input_param = {} for k in valid_list: if not self.request.arguments.has_key(k): raise WErr(400, "Missing %s" % k) build_input_param[k] = self.request.arguments[k][0] self.log.debug(build_input_param) # check the data ## SE if build_input_param["dstse"] == build_input_param["srcse"]: raise WErr(400, "dstse and srcse are same") ## protocol if build_input_param["protocol"] not in ["DIRACDMS", "DIRACFTS"]: raise WErr(400, "protocol %s is wrong" % build_input_param["protocol"]) # create RPC = RPCClient("Transfer/TransferRequest") res = RPC.create(build_input_param["dataset"], build_input_param["srcse"], build_input_param["dstse"], build_input_param["protocol"]) # TODO how to return error to the user? if not res["OK"]: self.log.error(res) self.set_status(200) self.finish() self.log.debug("finish")
def web_conf(self): """ Configuration endpoint, used to: GET /conf/get?<options> -- get configuration information, with arguments * options: * fullCFG - to get dump of configuration * option - option path to get option value * options - section path to get list of options * section - section path to get dict of all options/values there * sections - section path to get list of sections there * version - version of configuration that request information(optional) GET /conf/<helper method>?<arguments> -- get some information by using helpers methods * helper method - helper method of configuration service * arguments - arguments specifecly for every helper method :return: json with requested data """ self.log.notice('Request configuration information') optns = self.overpath.strip('/').split('/') if not optns or len(optns) > 1: raise WErr(404, "Wrone way") if optns[0] == 'get': if 'version' in self.args and ( self.args.get('version') or '0') >= gConfigurationData.getVersion(): self.finish() result = {} if 'fullCFG' in self.args: remoteCFG = yield self.threadTask( gConfigurationData.getRemoteCFG) result['Value'] = str(remoteCFG) elif 'option' in self.args: result = yield self.threadTask(gConfig.getOption, self.args['option']) elif 'section' in self.args: result = yield self.threadTask(gConfig.getOptionsDict, self.args['section']) elif 'options' in self.args: result = yield self.threadTask(gConfig.getOptions, self.args['options']) elif 'sections' in self.args: result = yield self.threadTask(gConfig.getSections, self.args['sections']) else: raise WErr(500, 'Invalid argument') elif any([ optns[0] == m and re.match('^[a-z][A-z]+', m) for m in dir(Registry) ]) and self.isRegisteredUser(): result = yield self.threadTask(getattr(Registry, optns[0]), **self.args) if not result['OK']: raise WErr(404, result['Message']) self.finishJEncode(result['Value'])
def _getJobSB( self, jid, objName ): with TmpDir() as tmpDir: if objName == "outputsandbox": objName = "Output" else: objName = "Input" result = SandboxStoreClient().downloadSandboxForJob( int( jid ), objName, tmpDir, inMemory = True ) if not result[ 'OK' ]: msg = result[ 'Message' ] if msg.find( "No %s sandbox" % objName ) == 0: return WErr( 404, "No %s sandbox defined for job %s" % ( jid, objName.lower() ) ) return WErr( 500, result[ 'Message' ] ) return WOK( result[ 'Value' ] )
def web_saveAppState(self): up = self.__getUP() try: name = self.request.arguments['name'][-1] state = self.request.arguments['state'][-1] except KeyError as excp: raise WErr(400, "Missing %s" % excp) data = base64.b64encode(zlib.compress(DEncode.encode(state), 9)) # before we save the state (modify the state) we have to remeber the actual access: ReadAccess and PublishAccess result = yield self.threadTask(up.getVarPermissions, name) if result['OK']: access = result['Value'] else: access = { 'ReadAccess': 'USER', 'PublishAccess': 'USER' } # this is when the application/desktop does not exists. result = yield self.threadTask(up.storeVar, name, data) if not result['OK']: raise WErr.fromSERROR(result) # change the access to the application/desktop result = yield self.threadTask(up.setVarPermissions, name, access) if not result['OK']: raise WErr.fromSERROR(result) self.set_status(200) self.finish()
def web_action(self): try: transid = int(self.request.arguments['id'][-1]) except KeyError as excp: raise WErr(400, "Missing %s" % excp) callback = {} if self.request.arguments["data_kind"][0] == "getLoggingInfo": callback = yield self.threadTask(self.__getLoggingInfo, transid) elif self.request.arguments["data_kind"][0] == "fileStatus": callback = yield self.threadTask(self.__transformationFileStatus, transid) elif self.request.arguments["data_kind"][0] == "fileProcessed": callback = yield self.threadTask(self.__fileRetry, transid, 'proc') elif self.request.arguments["data_kind"][0] == "fileNotProcessed": callback = yield self.threadTask(self.__fileRetry, transid, 'not') elif self.request.arguments["data_kind"][0] == "fileAllProcessed": callback = yield self.threadTask(self.__fileRetry, transid, 'all') elif self.request.arguments["data_kind"][0] == "dataQuery": callback = yield self.threadTask(self.__dataQuery, transid) elif self.request.arguments["data_kind"][0] == "additionalParams": callback = yield self.threadTask(self.__additionalParams, transid) elif self.request.arguments["data_kind"][0] == "transformationDetail": callback = yield self.threadTask(self.__transformationDetail, transid) elif self.request.arguments["data_kind"][0] == "extend": callback = yield self.threadTask(self.__extendTransformation, transid) elif self.request.arguments["data_kind"][0] == "workflowxml": callback = yield self.threadTask(self.__workflowxml, transid) else: callback = {"success": "false", "error": "Action is unknown!!!"} self.finish(callback)
def web_metadata(self): """ Retrieve all metadata keys with their type and possible values that are compatible with the metadata restriction. Accepts metadata condition: GET /filecatalogue/metadata -- retrieve all metadata keys with their type and possible values that are compatible with the metadata restriction. Accepts metadata condition :return: json with requested data """ if self.overpath: raise WErr(404, "Wrone way") cond = self.__decodeMetadataQuery() result = yield self.threadTask(self.__rpc.getMetadataFields) if not result['OK']: raise WErr.fromError(result) data = result['Value'] fields = {} for k in data['DirectoryMetaFields']: fields[k] = data['DirectoryMetaFields'][k].lower() result = yield self.threadTask(self.__rpc.getCompatibleMetadata, cond, "/") if not result['OK']: raise WErr.fromError(result) values = result['Value'] data = {} for k in fields: if k not in values: continue data[k] = {'type': fields[k], 'values': values[k]} self.finish(data)
def _getJobs(self, selDict, startJob=0, maxJobs=500): result = RPCClient("WorkloadManagement/JobMonitoring").getJobPageSummaryWeb(selDict, [('JobID', 'DESC')], startJob, maxJobs, True) if not result['OK']: return WErr(500, result['Message']) origData = result['Value'] totalRecords = origData['TotalRecords'] retData = {'entries': totalRecords, 'jobs': []} if totalRecords == 0: return WOK(retData) indexes = self.__findIndexes(origData['ParameterNames']) records = origData['Records'] for record in records: job = {} for param in indexes['attrs']: job[param] = record[indexes['attrs'][param]] if param in self.NUMERICAL: job[param] = int(float(job[param])) for k in ('flags', 'times'): job[k] = {} for field in indexes[k]: value = record[indexes[k][field]] if value.lower() == "none": continue if k == 'flags': job[k][field] = value.lower() == 'true' else: job[k][field] = value retData['jobs'].append(job) return WOK(retData)
def __getUP(self): try: obj = self.request.arguments['obj'][-1] app = self.request.arguments['app'][-1] except KeyError as excp: raise WErr(400, "Missing %s" % excp) return UserProfileClient("Web/%s/%s" % (obj, app))
def prepare(self): if not self.isRegisteredUser(): raise WErr(401, "Not a registered user") self.set_header("Pragma", "no-cache") self.set_header("Cache-Control", "max-age=0, no-store, no-cache, must-revalidate") #Do not use the defined user setup. Use the web one to show the same profile independenly of # user setup self.__tc.setSetup(False)
def web_makePublicDesktopState(self): up = UserProfileClient("Web/application/desktop") try: name = self.request.arguments['name'][-1] except KeyError as excp: raise WErr(400, "Missing %s" % excp) try: access = self.request.arguments['access'][-1].upper() except KeyError as excp: access = 'ALL' if access not in ('ALL', 'VO', 'GROUP', 'USER'): raise WErr(400, "Invalid access") # TODO: Check access is in either 'ALL', 'VO' or 'GROUP' result = yield self.threadTask(up.setVarPermissions, name, {'ReadAccess': access}) if not result['OK']: raise WErr.fromSERROR(result) self.set_status(200) self.finish()
def web_delAppState(self): up = self.__getUP() try: name = self.request.arguments['name'][-1] except KeyError as excp: raise WErr(400, "Missing %s" % excp) result = yield self.threadTask(up.deleteVar, name) if not result['OK']: raise WErr.fromSERROR(result) self.finish()
def web_executeOperation(self): try: cmd = self.request.arguments['action'][-1] ids = self.request.arguments["ids"][0].split(",") ids = [int(i) for i in ids] except KeyError as excp: raise WErr(400, "Missing %s" % excp) tsClient = TransformationClient() agentType = 'Manual' if cmd == 'clean': status = 'Cleaning' elif cmd == 'start': status = 'Active' agentType = 'Automatic' elif cmd == 'flush': status = 'Flush' agentType = 'Automatic' elif cmd == 'stop': status = 'Stopped' elif cmd == 'complete': status = 'Completed' else: self.finish({"success": "false", "error": "Unknown action"}) callback = [] for i in ids: try: transid = int(i) result = yield self.threadTask( tsClient.setTransformationParameter, transid, 'Status', status) if result["OK"]: resString = "ProdID: %s set to %s successfully" % (i, cmd) result = yield self.threadTask( tsClient.setTransformationParameter, transid, 'AgentType', agentType) if not result["OK"]: resString = "ProdID: %s failed to set to %s: %s" % ( i, cmd, result["Message"]) else: resString = "ProdID: %s failed due the reason: %s" % ( i, result["Message"]) except: resString = "Unable to convert given ID %s to transformation ID" % i callback.append(resString) callback = {"success": "true", "showResult": callback} gLogger.info(cmd, ids) self.finish(callback)
def _getJobManifest( self, jid ): result = RPCClient( "WorkloadManagement/JobMonitoring" ).getJobJDL( int( jid ) ) if not result[ 'OK' ]: return WErr( 500, result[ 'Message' ] ) result = loadJDLAsCFG( result[ 'Value' ] ) if not result[ 'OK' ]: return WErr( 500, result[ 'Message' ] ) cfg = result[ 'Value' ][0] jobData = {} stack = [ ( cfg, jobData ) ] while stack: cfg, level = stack.pop( 0 ) for op in cfg.listOptions(): val = List.fromChar( cfg[ op ] ) if len( val ) == 1: val = val[0] level[ op ] = val for sec in cfg.listSections(): level[ sec ] = {} stack.append( ( cfg[ sec ], level[ sec ] ) ) return WOK( jobData )
def web_loadAppState(self): up = self.__getUP() try: name = self.request.arguments['name'][-1] except KeyError as excp: raise WErr(400, "Missing %s" % excp) result = yield self.threadTask(up.retrieveVar, name) if not result['OK']: raise WErr.fromSERROR(result) data = result['Value'] data, count = DEncode.decode(zlib.decompress(base64.b64decode(data))) self.finish(data)
def web_upload(self): if 'filename' not in self.request.arguments: raise WErr(400, "Please provide a file name!") data = self.request.arguments.get("data", "")[0] filename = self.request.arguments.get("filename", "")[0] if re.match("(?!\.)^[\w\d_\.\-]*$", filename): filepath = "%s/webRoot/www/pilot/%s" % (rootPath, filename) else: raise WErr(400, "Please provide a valid file name!") try: tmpfile = "%s.tmp" % filepath with open(tmpfile, 'w') as tmp: tmp.write(data) os.rename(tmpfile, filepath) except OSError as e: raise WErr(400, "Cannot create the file: %s; %s" % (filename, repr(e))) self.finish('File has created')
def web_saveAppState(self): up = self.__getUP() try: name = self.request.arguments['name'][-1] state = self.request.arguments['state'][-1] except KeyError as excp: raise WErr(400, "Missing %s" % excp) data = base64.b64encode(zlib.compress(DEncode.encode(state), 9)) result = yield self.threadTask(up.storeVar, name, data) if not result['OK']: raise WErr.fromSERROR(result) self.set_status(200) self.finish()
def web_listAppState(self): self.__tc.setSetup(False) try: app = self.request.arguments['app'][-1] except KeyError as excp: raise WErr(400, "Missing %s" % excp) up = UserProfileClient("Web/App/%s" % app) result = yield self.threadTask(up.listAvailableVars, {'UserName': [self.getUserName()]}) if not result['OK']: raise WErr.fromSERROR(result) data = result['Value'] self.finish({'app': [e[-1] for e in data]})
def web_publishAppState(self): up = self.__getUP() try: name = self.request.arguments['name'][-1] except KeyError as excp: raise WErr(400, "Missing %s" % excp) try: access = self.request.arguments['access'][-1].upper() except KeyError as excp: access = 'ALL' if access not in ('ALL', 'VO', 'GROUP', 'USER'): raise WErr(400, "Invalid access") result = yield self.threadTask(up.setVarPermissions, name, { 'PublishAccess': access, 'ReadAccess': access }) if not result['OK']: raise WErr.fromSERROR(result) self.set_status(200) self.finish()
def web_loadAppState(self): self.__tc.setSetup(False) try: app = self.request.arguments['app'][-1] name = self.request.arguments['name'][-1] except KeyError as excp: raise WErr(400, "Missing %s" % excp) up = UserProfileClient("Web/App/%s" % app) result = yield self.threadTask(up.retrieveVar, name) if not result['OK']: raise WErr.fromSERROR(result) data = result['Value'] data, count = DEncode.decode(zlib.decompress(base64.b64decode(data))) self.set_header("Content-Type", "application/json") self.finish(data)
def __decodePath(self): """ All directories that have to be set in a URL have to be encoded in url safe base 64 (RFC 4648 Spec where ‘+’ is encoded as ‘-‘ and ‘/’ is encoded as ‘_’). There are several implementations for different languages already. :return: basestring """ did = re.match("([A-z0-9=-_]+)?", self.overpath.strip('/').split('/')[0]).group() if not did: return "/" try: return base64.urlsafe_b64decode(str(did)).rstrip("/") or "/" except TypeError, e: raise WErr(400, "Cannot decode path")
def web_saveAppState(self): self.__tc.setSetup(False) try: app = self.request.arguments['app'][-1] name = self.request.arguments['name'][-1] state = self.request.arguments['state'][-1] except KeyError as excp: raise WErr(400, "Missing %s" % excp) data = base64.b64encode(zlib.compress(DEncode.encode(state), 9)) up = UserProfileClient("Web/App/%s" % app) result = yield self.threadTask(up.storeVar, name, data) if not result['OK']: raise WErr.fromSERROR(result) self.set_status(200) self.finish()
def uploadSandbox(self, fileData): with TmpDir() as tmpDir: fileList = [] for fName in fileData: for entry in fileData[fName]: tmpFile = os.path.join(tmpDir, entry.filename) if tmpFile not in fileList: fileList.append(tmpFile) dfd = open(tmpFile, "w") dfd.write(entry.body) dfd.close() sbClient = SandboxStoreClient() result = sbClient.uploadFilesAsSandbox(fileList) if not result['OK']: return WErr(500, result['Message']) return WOK(result['Value'])
def web_changeView(self): up = self.__getUP() try: desktopName = self.request.arguments['desktop'][-1] view = self.request.arguments['view'][-1] except KeyError as excp: raise WErr(400, "Missing %s" % excp) result = yield self.threadTask(up.retrieveVar, desktopName) if not result['OK']: raise WErr.fromSERROR(result) data = result['Value'] oDesktop = json.loads( DEncode.decode(zlib.decompress(base64.b64decode(data)))[0]) oDesktop[unicode('view')] = unicode(view) oDesktop = json.dumps(oDesktop) data = base64.b64encode(zlib.compress(DEncode.encode(oDesktop), 9)) result = yield self.threadTask(up.storeVar, desktopName, data) if not result['OK']: raise WErr.fromSERROR(result) self.set_status(200) self.finish()
def web_setSite(self): callback = {} try: transID = int(self.request.arguments['TransformationId'][-1]) runID = int(self.request.arguments['RunNumber'][-1]) site = self.request.arguments['Site'][-1] except KeyError as excp: raise WErr(400, "Missing %s" % excp) gLogger.info( "\033[0;31m setTransformationRunsSite(%s, %s, %s) \033[0m" % (transID, runID, site)) tsClient = TransformationClient() result = yield self.threadTask(tsClient.setTransformationRunsSite, transID, runID, site) if result["OK"]: callback = {"success": "true", "result": "true"} else: callback = {"success": "false", "error": result["Message"]} self.finish(callback)
def __extendTransformation(self, transid): try: tasks = int(self.request.arguments["tasks"][-1]) except KeyError as excp: raise WErr(400, "Missing %s" % excp) gLogger.info("extend %s" % transid) tsClient = TransformationClient() gLogger.info("extendTransformation(%s,%s)" % (transid, tasks)) res = tsClient.extendTransformation(transid, tasks) if res["OK"]: resString = "%s extended by %s successfully" % (transid, tasks) else: resString = "%s failed to extend: %s" % (transid, res["Message"]) callback = { "success": "true", "showResult": [resString], "result": resString } gLogger.info("#######", res) return callback
def web_proxy(self): """ Proxy management endpoint, use: GET /proxy?<options> -- retrieve personal proxy * options: * voms - to get VOMSproxy(optional) * lifetime - requested proxy live time(optional) GET /proxy/<user>/<group>?<options> -- retrieve proxy * user - user name * group - group name * options: * voms - to get VOMSproxy(optional) * lifetime - requested proxy live time(optional) GET /proxy/metadata?<options> -- retrieve proxy metadata.. * options: :return: json """ voms = self.args.get('voms') proxyLifeTime = 3600 * 12 if re.match('[0-9]+', self.args.get('lifetime') or ''): proxyLifeTime = int(self.args.get('lifetime')) optns = self.overpath.strip('/').split('/') # GET if self.request.method == 'GET': # Return content of Proxy DB if 'metadata' in optns: pass # Return personal proxy elif not self.overpath: result = yield self.threadTask(ProxyManagerClient().downloadPersonalProxy, self.getUserName(), self.getUserGroup(), requiredTimeLeft=proxyLifeTime, voms=voms) if not result['OK']: raise WErr(500, result['Message']) self.log.notice('Proxy was created.') result = result['Value'].dumpAllToString() if not result['OK']: raise WErr(500, result['Message']) self.finishJEncode(result['Value']) # Return proxy elif len(optns) == 2: user = optns[0] group = optns[1] # Get proxy to string result = getDNForUsernameInGroup(user, group) if not result['OK'] or not result.get('Value'): raise WErr(500, '%s@%s has no registred DN: %s' % (user, group, result.get('Message') or "")) if voms: result = yield self.threadTask(ProxyManagerClient().downloadVOMSProxy, user, group, requiredTimeLeft=proxyLifeTime) else: result = yield self.threadTask(ProxyManagerClient().downloadProxy, user, group, requiredTimeLeft=proxyLifeTime) if not result['OK']: raise WErr(500, result['Message']) self.log.notice('Proxy was created.') result = result['Value'].dumpAllToString() if not result['OK']: raise WErr(500, result['Message']) self.finishJEncode(result['Value']) else: raise WErr(404, "Wrone way")
def web_auth(self): """ Authentication endpoint, used: GET /auth/<IdP>?<options> -- submit authentication flow, retrieve session with status and describe * IdP - Identity provider name for authentication * options: * email - email to get authentcation URL(optional) GET /auth/<session> -- will redirect to authentication endpoint GET /auth/<session>/status -- retrieve session with status and describe * session - session number GET /auth/redirect?<options> -- redirect endpoint to catch authentication responce * options - responce options :return: json """ optns = self.overpath.strip('/').split('/') if not optns or len(optns) > 2: raise WErr(404, "Wrone way") result = Resources.getInfoAboutProviders(of='Id') if not result['OK']: raise WErr(500, result['Message']) idPs = result['Value'] idP = re.match("(%s)?" % '|'.join(idPs), optns[0]).group() session = re.match("([A-z0-9]+)?", optns[0]).group() if idP: # Create new authenticate session session = self.get_cookie(idP) self.log.info('Initialize "%s" authorization flow' % idP, 'with %s session' % session if session else '') result = yield self.threadTask(gSessionManager.submitAuthorizeFlow, idP, session) if not result['OK']: raise WErr(500, result['Message']) if result['Value']['Status'] == 'ready': self.set_cookie("TypeAuth", idP) elif result['Value']['Status'] == 'needToAuth': if self.args.get('email'): notify = yield self.threadTask( NotificationClient().sendMail, self.args['email'], 'Authentication throught %s' % idP, 'Please, go throught the link %s to authorize.' % result['Value']['URL']) if not notify['OK']: result['Value']['Comment'] = '%s\n%s' % ( result['Value'].get('Comment') or '', notify['Message']) self.log.notice( '%s authorization session "%s" provider was created' % (result['Value']['Session'], idP)) else: raise WErr( 500, 'Not correct status "%s" of %s' % (result['Value']['Status'], idP)) self.finishJEncode(result['Value']) elif optns[0] == 'redirect': # Redirect endpoint for response self.log.info('REDIRECT RESPONSE:\n', self.request) if self.args.get('error'): raise WErr( 500, '%s session crashed with error:\n%s\n%s' % (self.args.get('state') or '', self.args['error'], self.args.get('error_description') or '')) if 'state' not in self.args: raise WErr(404, '"state" argument not set.') if not self.args.get('state'): raise WErr(404, '"state" argument is empty.') self.log.info( self.args['state'], 'session, parsing authorization response %s' % self.args) result = yield self.threadTask(gSessionManager.parseAuthResponse, self.args, self.args['state']) if not result['OK']: raise WErr(500, result['Message']) comment = result['Value']['Comment'] status = result['Value']['Status'] t = Template('''<!DOCTYPE html> <html><head><title>Authetication</title> <meta charset="utf-8" /></head><body> %s <br> <script type="text/javascript"> if ("%s" == "redirect") { window.open("%s","_self") } else { window.close() } </script> </body> </html>''' % (comment, status, comment)) self.log.info('>>>REDIRECT:\n', comment) self.finish(t.generate()) elif session: if optns[-1] == session: # Redirect to authentication endpoint self.log.info(session, 'authorization session flow.') result = yield self.threadTask( gSessionManager.getLinkBySession, session) if not result['OK']: raise WErr(500, '%s session not exist or expired!' % session) self.log.notice('Redirect to', result['Value']) self.redirect(result['Value']) elif optns[-1] == 'status': # Get session authentication status self.log.info(session, 'session, get status of authorization.') result = yield self.threadTask( gSessionManager.getSessionStatus, session) if not result['OK']: raise WErr(500, result['Message']) self.set_cookie("TypeAuth", result['Value']['Provider']) self.set_cookie(result['Value']['Provider'], session) self.finishJEncode(result['Value']) else: raise WErr(404, "Wrone way") else: raise WErr(404, "Wrone way")
def web_changeSetup(self): try: to = self.request.arguments['to'][-1] except KeyError: raise WErr(400, "Missing 'to' argument") self.__change(setup=to)