diff --git a/doc/_update_doc/conf.py b/doc/_update_doc/conf.py index c9f4e21..d75b995 100644 --- a/doc/_update_doc/conf.py +++ b/doc/_update_doc/conf.py @@ -40,8 +40,8 @@ master_doc = 'index' # General information about the project. -project = u'BaseSpacePy' -copyright = u'2014, Illumina' +project = 'BaseSpacePy' +copyright = '2014, Illumina' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the @@ -183,8 +183,8 @@ # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, author, documentclass [howto/manual]). latex_documents = [ - ('index', 'BaseSpacePy.tex', u'BaseSpacePy Documentation', - u'Illumina', 'manual'), + ('index', 'BaseSpacePy.tex', 'BaseSpacePy Documentation', + 'Illumina', 'manual'), ] # The name of an image file (relative to this directory) to place at the top of @@ -213,8 +213,8 @@ # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). man_pages = [ - ('index', 'basespacepy', u'BaseSpacePy Documentation', - [u'Illumina'], 1) + ('index', 'basespacepy', 'BaseSpacePy Documentation', + ['Illumina'], 1) ] # If true, show URL addresses after external links. @@ -227,8 +227,8 @@ # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ - ('index', 'BaseSpacePy', u'BaseSpacePy Documentation', - u'Illumina', 'BaseSpacePy', 'One line description of project.', + ('index', 'BaseSpacePy', 'BaseSpacePy Documentation', + 'Illumina', 'BaseSpacePy', 'One line description of project.', 'Miscellaneous'), ] diff --git a/examples/0_Browsing.py b/examples/0_Browsing.py index d90710e..a616d5e 100644 --- a/examples/0_Browsing.py +++ b/examples/0_Browsing.py @@ -52,32 +52,32 @@ # First, let's grab the genome with id=4 myGenome = myAPI.getGenomeById('4') -print "\nThe Genome is " + str(myGenome) -print "We can get more information from the genome object" -print 'Id: ' + myGenome.Id -print 'Href: ' + myGenome.Href -print 'DisplayName: ' + myGenome.DisplayName +print("\nThe Genome is " + str(myGenome)) +print("We can get more information from the genome object") +print('Id: ' + myGenome.Id) +print('Href: ' + myGenome.Href) +print('DisplayName: ' + myGenome.DisplayName) # Get a list of all genomes allGenomes = myAPI.getAvailableGenomes() -print "\nGenomes \n" + str(allGenomes) +print("\nGenomes \n" + str(allGenomes)) # Let's have a look at the current user user = myAPI.getUserById('current') -print "\nThe current user is \n" + str(user) +print("\nThe current user is \n" + str(user)) # Now list the projects for this user myProjects = myAPI.getProjectByUser() -print "\nThe projects for this user are \n" + str(myProjects) +print("\nThe projects for this user are \n" + str(myProjects)) # We can also achieve this by making a call using the 'user instance' myProjects2 = user.getProjects(myAPI) -print "\nProjects retrieved from the user instance \n" + str(myProjects2) +print("\nProjects retrieved from the user instance \n" + str(myProjects2)) # List the runs available for the current user runs = user.getRuns(myAPI) -print "\nThe runs for this user are \n" + str(runs) +print("\nThe runs for this user are \n" + str(runs)) # In the same manner we can get a list of accessible user runs runs = user.getRuns(myAPI) -print "\nRuns retrieved from user instance \n" + str(runs) +print("\nRuns retrieved from user instance \n" + str(runs)) diff --git a/examples/1_AccessingFiles.py b/examples/1_AccessingFiles.py index 7b65b1e..f794208 100644 --- a/examples/1_AccessingFiles.py +++ b/examples/1_AccessingFiles.py @@ -51,40 +51,40 @@ # Let's list all the AppResults and samples for these projects for singleProject in myProjects: - print "# " + str(singleProject) + print("# " + str(singleProject)) appResults = singleProject.getAppResults(myAPI) - print " The App results for project " + str(singleProject) + " are \n\t" + str(appResults) + print(" The App results for project " + str(singleProject) + " are \n\t" + str(appResults)) samples = singleProject.getSamples(myAPI) - print " The samples for project " + str(singleProject) + " are \n\t" + str(samples) + print(" The samples for project " + str(singleProject) + " are \n\t" + str(samples)) # ## we'll take a further look at the files belonging to the sample and ##analyses from the last project in the loop above for a in appResults: - print "# " + a.Id + print("# " + a.Id) ff = a.getFiles(myAPI) - print ff + print(ff) for s in samples: - print "Sample " + str(s) + print("Sample " + str(s)) ff = s.getFiles(myAPI) - print ff + print(ff) ## Now let's do some work with files ## we'll grab a BAM by id and get the coverage for an interval + accompanying meta-data myBam = myAPI.getFileById('9895890') -print myBam +print(myBam) cov = myBam.getIntervalCoverage(myAPI,'chr','1','100') -print cov +print(cov) try: covMeta = myBam.getCoverageMeta(myAPI,'chr') except Exception as e: - print "Coverage metadata may not be available for this BAM file: %s" % str(e) + print("Coverage metadata may not be available for this BAM file: %s" % str(e)) else: - print covMeta + print(covMeta) # ## and a vcf file myVCF = myAPI.getFileById('9895892') varMeta = myVCF.getVariantMeta(myAPI) -print varMeta +print(varMeta) var = myVCF.filterVariant(myAPI,'chr','1', '25000') -print var +print(var) diff --git a/examples/2_AppTriggering.py b/examples/2_AppTriggering.py index e38c87f..df5e218 100644 --- a/examples/2_AppTriggering.py +++ b/examples/2_AppTriggering.py @@ -51,30 +51,30 @@ # Using the basespaceApi we can request the appSession object corresponding to the AppSession id supplied myAppSession = myAPI.getAppSession() -print myAppSession +print(myAppSession) # An app session contains a referal to one or more appLaunchObjects which reference the data module # the user launched the app on. This can be a list of projects, samples, or a mixture of objects -print "\nType of data the app was triggered on can be seen in 'references'" -print myAppSession.References +print("\nType of data the app was triggered on can be seen in 'references'") +print(myAppSession.References) # We can also get a handle to the user who started the AppSession -print "\nWe can get a handle for the user who triggered the app\n" + str(myAppSession.UserCreatedBy) +print("\nWe can get a handle for the user who triggered the app\n" + str(myAppSession.UserCreatedBy)) # Let's have a closer look at the appSessionLaunchObject myReference = myAppSession.References[0] -print "\nWe can get out information such as the href to the launch object:" -print myReference.HrefContent -print "\nand the specific type of that object:" -print myReference.Type +print("\nWe can get out information such as the href to the launch object:") +print(myReference.HrefContent) +print("\nand the specific type of that object:") +print(myReference.Type) # Now we will want to ask for more permission for the specific reference object -print "\nWe can get out the specific project objects by using 'content':" +print("\nWe can get out the specific project objects by using 'content':") myReference = myReference.Content -print myReference -print "\nThe scope string for requesting read access to the reference object is:" -print myReference.getAccessStr(scope='write') +print(myReference) +print("\nThe scope string for requesting read access to the reference object is:") +print(myReference.getAccessStr(scope='write')) # We can easily request write access to the reference object so our App can start contributing analysis # by default we ask for write permission and authentication for a device diff --git a/examples/3_Authentication.py b/examples/3_Authentication.py index 6b13753..0cbc880 100644 --- a/examples/3_Authentication.py +++ b/examples/3_Authentication.py @@ -17,7 +17,7 @@ from BaseSpacePy.api.BaseSpaceAPI import BaseSpaceAPI import time import webbrowser -import cPickle as Pickle +import pickle as Pickle import os """ @@ -50,13 +50,13 @@ # First, get the verification code and uri for scope 'browse global' deviceInfo = myAPI.getVerificationCode('browse global') -print "\n URL for user to visit and grant access: " -print deviceInfo['verification_with_code_uri'] +print("\n URL for user to visit and grant access: ") +print(deviceInfo['verification_with_code_uri']) ## PAUSE HERE # Have the user visit the verification uri to grant us access -print "\nPlease visit the uri within 15 seconds and grant access" -print deviceInfo['verification_with_code_uri'] +print("\nPlease visit the uri within 15 seconds and grant access") +print(deviceInfo['verification_with_code_uri']) webbrowser.open_new(deviceInfo['verification_with_code_uri']) time.sleep(15) ## PAUSE HERE @@ -68,13 +68,13 @@ myAPI.updatePrivileges(code) # As a reference the provided access-token can be obtained from the BaseSpaceApi object -print "\nMy Access-token:" -print myAPI.getAccessToken() +print("\nMy Access-token:") +print(myAPI.getAccessToken()) # Let's try and grab all available genomes with our new api! allGenomes = myAPI.getAvailableGenomes() -print "\nGenomes \n" + str(allGenomes) +print("\nGenomes \n" + str(allGenomes)) # If at a later stage we wish to initialize a BaseSpaceAPI object when we already have @@ -82,8 +82,8 @@ # object using the key-word AccessToken. myToken = myAPI.getAccessToken() myAPI.setAccessToken(myToken) -print "\nA BaseSpaceAPI instance was updated with an access-token: " -print myAPI +print("\nA BaseSpaceAPI instance was updated with an access-token: ") +print(myAPI) #################### Web-based verification ################################# # The scenario where the authentication is done through a web-browser @@ -94,8 +94,8 @@ BSapiWeb = BaseSpaceAPI(profile='DEFAULT') userUrl= BSapiWeb.getWebVerificationCode('browse global','http://localhost',state='myState') -print "\nHave the user visit:" -print userUrl +print("\nHave the user visit:") +print(userUrl) webbrowser.open_new(userUrl) @@ -121,8 +121,8 @@ # Get current user user= myAPI.getUserById('current') -print user -print myAPI +print(user) +print(myAPI) #### Here some work goes on @@ -136,7 +136,7 @@ # Imagine the current request is done, we will simulate this by deleting the api instance myAPI = None -print "\nTry printing the removed API, we get: " + str(myAPI) +print("\nTry printing the removed API, we get: " + str(myAPI)) # Next request in the session with id = id123 comes in @@ -145,10 +145,10 @@ f = open(mySessionId) myAPI = Pickle.load(f) f.close() - print - print "We got the API back!" - print myAPI + print() + print("We got the API back!") + print(myAPI) else: - print "Looks like we haven't stored anything for this session yet" + print("Looks like we haven't stored anything for this session yet") # create a BaseSpaceAPI for the first time diff --git a/examples/4_AppResultUpload.py b/examples/4_AppResultUpload.py index e5c2017..473f4c0 100644 --- a/examples/4_AppResultUpload.py +++ b/examples/4_AppResultUpload.py @@ -49,41 +49,41 @@ # Assuming we have write access to the project # we will list the current App Results for the project appRes = p.getAppResults(myAPI,statuses=['Running']) -print "\nThe current running AppResults are \n" + str(appRes) +print("\nThe current running AppResults are \n" + str(appRes)) # now let's do some work! # to create an appResults for a project, simply give the name and description appResults = p.createAppResult(myAPI,"testing","this is my results",appSessionId='') -print "\nSome info about our new app results" -print appResults -print appResults.Id -print "\nThe app results also comes with a reference to our AppSession" +print("\nSome info about our new app results") +print(appResults) +print(appResults.Id) +print("\nThe app results also comes with a reference to our AppSession") myAppSession = appResults.AppSession -print myAppSession +print(myAppSession) # we can change the status of our AppSession and add a status-summary as follows myAppSession.setStatus(myAPI,'needsattention',"We worked hard, but encountered some trouble.") -print "\nAfter a change of status of the app sessions we get\n" + str(myAppSession) +print("\nAfter a change of status of the app sessions we get\n" + str(myAppSession)) # we'll set our appSession back to running so we can do some more work myAppSession.setStatus(myAPI,'running',"Back on track") ### Let's list all AppResults again and see if our new object shows up appRes = p.getAppResults(myAPI,statuses=['Running']) -print "\nThe updated app results are \n" + str(appRes) +print("\nThe updated app results are \n" + str(appRes)) appResult2 = myAPI.getAppResultById(appResults.Id) -print appResult2 +print(appResult2) ## Now we will make another AppResult ## and try to upload a file to it appResults2 = p.createAppResult(myAPI,"My second AppResult","This one I will upload to") appResults2.uploadFile(myAPI, '/home/mkallberg/Desktop/testFile2.txt', 'BaseSpaceTestFile.txt', '/mydir/', 'text/plain') -print "\nMy AppResult number 2 \n" + str(appResults2) +print("\nMy AppResult number 2 \n" + str(appResults2)) ## let's see if our new file made it appResultFiles = appResults2.getFiles(myAPI) -print "\nThese are the files in the appResult" -print appResultFiles +print("\nThese are the files in the appResult") +print(appResultFiles) f = appResultFiles[-1] # we can even download our newly uploaded file diff --git a/examples/5_Purchasing.py b/examples/5_Purchasing.py index d9fbea0..de6b7ef 100644 --- a/examples/5_Purchasing.py +++ b/examples/5_Purchasing.py @@ -49,43 +49,43 @@ # create a consumable purchase, and associated it with an AppSession # also add tags to provide (fake) details about the purchase -print "\nCreating purchase\n" +print("\nCreating purchase\n") purch = billAPI.createPurchase({'id':product_id,'quantity':4, 'tags':["test","test_tag"] }, AppSessionId) # record the purchase Id and RefundSecret for refunding later purchaseId = purch.Id refundSecret = purch.RefundSecret -print "Now complete the purchase in your web browser" -print "CLOSE the browser window/tab after you click 'Purchase' (and don't proceed into the app)" +print("Now complete the purchase in your web browser") +print("CLOSE the browser window/tab after you click 'Purchase' (and don't proceed into the app)") time.sleep(3) ## PAUSE HERE -print "Opening: " + purch.HrefPurchaseDialog +print("Opening: " + purch.HrefPurchaseDialog) webbrowser.open_new(purch.HrefPurchaseDialog) -print "Waiting 30 seconds..." +print("Waiting 30 seconds...") time.sleep(30) ## PAUSE HERE -print "\nConfirm the purchase" +print("\nConfirm the purchase") post_purch = billAPI.getPurchaseById(purchaseId) -print "The status of the purchase is now: " + post_purch.Status +print("The status of the purchase is now: " + post_purch.Status) -print "\nRefunding the Purchase" +print("\nRefunding the Purchase") # note we must use the same access token that was provided used for the purchase refunded_purchase = billAPI.refundPurchase(purchaseId, refundSecret, comment='the product did not function well as a frisbee') -print "\nGetting all purchases for the current user with the tags we used for the purchase above" +print("\nGetting all purchases for the current user with the tags we used for the purchase above") purch_prods = billAPI.getUserProducts(Id='current', queryPars=qpp( {'Tags':'test,test_tag'} )) if not len(purch_prods): - print "\nHmmm, didn't find any purchases with these tags. Did everything go OK above?\n" + print("\nHmmm, didn't find any purchases with these tags. Did everything go OK above?\n") else: - print "\nFor the first of these purchases:\n" - print "Purchase Name: " + purch_prods[0].Name - print "Purchase Price: " + purch_prods[0].Price - print "Purchase Quantity: " + purch_prods[0].Quantity - print "Tags: " + str(purch_prods[0].Tags) + print("\nFor the first of these purchases:\n") + print("Purchase Name: " + purch_prods[0].Name) + print("Purchase Price: " + purch_prods[0].Price) + print("Purchase Quantity: " + purch_prods[0].Quantity) + print("Tags: " + str(purch_prods[0].Tags)) # Get the refund status of the purchase - print "\nGetting the (refunded) Purchase we just made" + print("\nGetting the (refunded) Purchase we just made") get_purch = billAPI.getPurchaseById(purch_prods[0].PurchaseId) - print "Refund Status: " + get_purch.RefundStatus + "\n" + print("Refund Status: " + get_purch.RefundStatus + "\n") diff --git a/src/BaseSpacePy/api/APIClient.py b/src/BaseSpacePy/api/APIClient.py index d25eea6..85d791b 100644 --- a/src/BaseSpacePy/api/APIClient.py +++ b/src/BaseSpacePy/api/APIClient.py @@ -2,10 +2,10 @@ import sys import os import re -import urllib -import urllib2 +import urllib.request, urllib.parse, urllib.error +import urllib.request, urllib.error, urllib.parse +import io import io -import cStringIO import json from subprocess import * import subprocess @@ -46,7 +46,7 @@ def __forcePostCall__(self, resourcePath, postData, headers): pass import logging logging.getLogger("requests").setLevel(logging.WARNING) - encodedPost = urllib.urlencode(postData) + encodedPost = urllib.parse.urlencode(postData) resourcePath = "%s?%s" % (resourcePath, encodedPost) response = requests.post(resourcePath, data=json.dumps(postData), headers=headers) return response.text @@ -101,10 +101,10 @@ def callAPI(self, resourcePath, method, queryParams, postData, headerParams=None if self.userAgent: headers['User-Agent'] = self.userAgent if headerParams: - for param, value in headerParams.iteritems(): + for param, value in headerParams.items(): headers[param] = value # specify the content type - if not headers.has_key('Content-Type') and not method=='PUT' and not forcePost: + if 'Content-Type' not in headers and not method=='PUT' and not forcePost: headers['Content-Type'] = 'application/json' # include access token in header headers['Authorization'] = 'Bearer ' + self.apiKey @@ -114,20 +114,20 @@ def callAPI(self, resourcePath, method, queryParams, postData, headerParams=None if queryParams: # Need to remove None values, these should not be sent sentQueryParams = {} - for param, value in queryParams.iteritems(): + for param, value in queryParams.items(): if value != None: sentQueryParams[param] = value - url = url + '?' + urllib.urlencode(sentQueryParams) - request = urllib2.Request(url=url, headers=headers) + url = url + '?' + urllib.parse.urlencode(sentQueryParams) + request = urllib.request.Request(url=url, headers=headers) elif method in ['POST', 'PUT', 'DELETE']: if queryParams: # Need to remove None values, these should not be sent sentQueryParams = {} - for param, value in queryParams.iteritems(): + for param, value in queryParams.items(): if value != None: sentQueryParams[param] = value forcePostUrl = url - url = url + '?' + urllib.urlencode(sentQueryParams) + url = url + '?' + urllib.parse.urlencode(sentQueryParams) data = postData if data: if type(postData) not in [str, int, float, bool]: @@ -135,7 +135,7 @@ def callAPI(self, resourcePath, method, queryParams, postData, headerParams=None if not forcePost: if data and not len(data): data='\n' # temp fix, in case is no data in the file, to prevent post request from failing - request = urllib2.Request(url=url, headers=headers, data=data)#,timeout=self.timeout) + request = urllib.request.Request(url=url, headers=headers, data=data)#,timeout=self.timeout) else: response = self.__forcePostCall__(forcePostUrl, sentQueryParams, headers) if method in ['PUT', 'DELETE']: @@ -149,13 +149,13 @@ def callAPI(self, resourcePath, method, queryParams, postData, headerParams=None # Make the request if not forcePost and not method in ['PUT', 'DELETE']: # the normal case try: - response = urllib2.urlopen(request, timeout=self.timeout).read() - except urllib2.HTTPError as e: + response = urllib.request.urlopen(request, timeout=self.timeout).read() + except urllib.error.HTTPError as e: response = e.read() # treat http error as a response (handle in caller) - except urllib2.URLError as e: + except urllib.error.URLError as e: raise ServerResponseException('URLError: ' + str(e)) try: - data = json.loads(response) + data = json.loads(response.decode('utf-8')) except ValueError as e: raise ServerResponseException('Error decoding json in server response') return data @@ -191,7 +191,7 @@ def deserialize(self, obj, objClass): # For dynamic types, substitute real class after looking up 'Type' value. # For lists, deserialize all members of a list, including lists of lists (though not list of list of list...). # For datetimes, convert to a readable output string - for attr, attrType in instance.swaggerTypes.iteritems(): + for attr, attrType in instance.swaggerTypes.items(): if attr in obj: value = obj[attr] if attrType in ['str', 'int', 'float', 'bool']: @@ -199,7 +199,7 @@ def deserialize(self, obj, objClass): try: value = attrType(value) except UnicodeEncodeError: - value = unicode(value) + value = str(value) setattr(instance, attr, value) elif attrType == 'DynamicType': try: diff --git a/src/BaseSpacePy/api/AppLaunchHelpers.py b/src/BaseSpacePy/api/AppLaunchHelpers.py index e985328..dc7361d 100644 --- a/src/BaseSpacePy/api/AppLaunchHelpers.py +++ b/src/BaseSpacePy/api/AppLaunchHelpers.py @@ -18,8 +18,8 @@ import json import os -from BaseMountInterface import BaseMountInterface -from BaseSpaceException import ServerResponseException +from .BaseMountInterface import BaseMountInterface +from .BaseSpaceException import ServerResponseException # if these strings are in the property names, we should not try to capture default values for them. # these are "global" but are needed by more than one object, so it's the cleanest way for now @@ -27,7 +27,7 @@ BS_ENTITY_LIST_NAMES = ["Samples", "Projects", "AppResults", "Files"] -class AppSessionMetaData(object): +class AppSessionMetaData(object, metaclass=abc.ABCMeta): """ Class to help extract information from an appsession. This is an abstract base class without two concrete implementations: @@ -36,8 +36,6 @@ class AppSessionMetaData(object): """ - __metaclass__ = abc.ABCMeta - SKIP_PROPERTIES = ["app-session-name", "attributes", "columns", "num-columns", "rowcount", "IsMultiNode"] @@ -429,8 +427,8 @@ def make_launch_json(self, user_supplied_vars, launch_name, api_version, sample_ raise LaunchSpecificationException( "Compulsory variable(s) missing! (%s)" % str(required_vars - supplied_var_names)) if supplied_var_names - (self.get_variable_requirements() | set(["LaunchName"])): - print "warning! unused variable(s) specified: (%s)" % str( - supplied_var_names - self.get_variable_requirements()) + print("warning! unused variable(s) specified: (%s)" % str( + supplied_var_names - self.get_variable_requirements())) all_vars = copy.copy(self.defaults) all_vars.update(user_supplied_vars) self.resolve_list_variables(all_vars) @@ -459,7 +457,7 @@ def dump_property_information(self): dump all properties with their type and any default value for verbose usage information output """ - print self.format_property_information() + print(self.format_property_information()) def format_minimum_requirements(self): minimum_requirements = self.get_minimum_requirements() diff --git a/src/BaseSpacePy/api/AuthenticationAPI.py b/src/BaseSpacePy/api/AuthenticationAPI.py index f0cd2ab..c3447e2 100644 --- a/src/BaseSpacePy/api/AuthenticationAPI.py +++ b/src/BaseSpacePy/api/AuthenticationAPI.py @@ -1,6 +1,6 @@ import sys import time -import ConfigParser +import configparser import getpass import os import requests @@ -49,7 +49,7 @@ def parse_config(self): :param config_path: path to config file :return: ConfigParser object """ - self.config = ConfigParser.SafeConfigParser() + self.config = configparser.SafeConfigParser() self.config.optionxform = str if os.path.exists(self.config_path): self.config.read(self.config_path) @@ -86,7 +86,7 @@ def check_session_details(self): pass def set_session_details(self, config_path): - username = raw_input("username:") + username = input("username:") password = getpass.getpass() s, r = self.basespace_session(username, password) self.config.set(self.DEFAULT_CONFIG_NAME, self.SESSION_TOKEN_NAME, r.cookies[self.COOKIE_NAME]) @@ -129,7 +129,7 @@ def set_oauth_details(self, client_id, client_secret, scopes): raise AuthenticationException(msg) auth_url = payload["verification_with_code_uri"] auth_code = payload["device_code"] - print "please authenticate here: %s" % auth_url + print("please authenticate here: %s" % auth_url) # poll the token URL until we get the token token_payload = { "client_id": client_id, @@ -156,6 +156,6 @@ def set_oauth_details(self, client_id, client_secret, scopes): self.construct_default_config(self.api_server) if not access_token: raise Exception("problem obtaining token!") - print "Success!" + print("Success!") self.config.set(self.DEFAULT_CONFIG_NAME, self.ACCESS_TOKEN_NAME, access_token) self.write_config() \ No newline at end of file diff --git a/src/BaseSpacePy/api/BaseAPI.py b/src/BaseSpacePy/api/BaseAPI.py index dab6b2f..16264af 100644 --- a/src/BaseSpacePy/api/BaseAPI.py +++ b/src/BaseSpacePy/api/BaseAPI.py @@ -1,10 +1,10 @@ from pprint import pprint -import urllib2 +import urllib.request, urllib.error, urllib.parse import shutil -import urllib -import httplib -import cStringIO +import urllib.request, urllib.parse, urllib.error +import http.client +import io import json import os import inspect @@ -33,9 +33,9 @@ def __json_print__(self, label, var): try: prefix = " " * len(label) var_list = json.dumps(var,indent=4).split('\n') # ,ensure_ascii=False - print label + var_list[0] + print(label + var_list[0]) if len(var_list)>1: - print "\n".join( [prefix + s for s in var_list[1:]] ) + print("\n".join( [prefix + s for s in var_list[1:]] )) except UnicodeDecodeError: pass # we could disable ascii-enforcing, as shown above, but # this will massively increase the volume of logs @@ -57,24 +57,24 @@ def __singleRequest__(self, myModel, resourcePath, method, queryParams, headerPa :returns: an instance of the Response model from the provided myModel ''' if self.verbose: - print "" - print "* " + inspect.stack()[1][3] + " (" + str(method) + ")" # caller - print ' # Path: ' + str(resourcePath) - print ' # QPars: ' + str(queryParams) - print ' # Hdrs: ' + str(headerParams) - print ' # forcePost: ' + str(forcePost) + print("") + print("* " + inspect.stack()[1][3] + " (" + str(method) + ")") # caller + print(' # Path: ' + str(resourcePath)) + print(' # QPars: ' + str(queryParams)) + print(' # Hdrs: ' + str(headerParams)) + print(' # forcePost: ' + str(forcePost)) self.__json_print__(' # postData: ',postData) response = self.apiClient.callAPI(resourcePath, method, queryParams, postData, headerParams, forcePost=forcePost) if self.verbose: self.__json_print__(' # Response: ',response) if not response: raise ServerResponseException('No response returned') - if response.has_key('ResponseStatus'): - if response['ResponseStatus'].has_key('ErrorCode'): + if 'ResponseStatus' in response: + if 'ErrorCode' in response['ResponseStatus']: raise ServerResponseException(str(response['ResponseStatus']['ErrorCode'] + ": " + response['ResponseStatus']['Message'])) - elif response['ResponseStatus'].has_key('Message'): + elif 'Message' in response['ResponseStatus']: raise ServerResponseException(str(response['ResponseStatus']['Message'])) - elif response.has_key('ErrorCode'): + elif 'ErrorCode' in response: raise ServerResponseException(response["MessageFormatted"]) responseObject = self.apiClient.deserialize(response, myModel) @@ -102,11 +102,11 @@ def __listRequest__(self, myModel, resourcePath, method, queryParams, headerPara :returns: a list of instances of the provided model ''' if self.verbose: - print "" - print "* " + inspect.stack()[1][3] + " (" + str(method) + ")" # caller - print ' # Path: ' + str(resourcePath) - print ' # QPars: ' + str(queryParams) - print ' # Hdrs: ' + str(headerParams) + print("") + print("* " + inspect.stack()[1][3] + " (" + str(method) + ")") # caller + print(' # Path: ' + str(resourcePath)) + print(' # QPars: ' + str(queryParams)) + print(' # Hdrs: ' + str(headerParams)) number_received = 0 total_number = None responses = [] @@ -125,9 +125,9 @@ def __listRequest__(self, myModel, resourcePath, method, queryParams, headerPara self.__json_print__(' # Response: ',response) if not response: raise ServerResponseException('No response returned') - if response['ResponseStatus'].has_key('ErrorCode'): + if 'ErrorCode' in response['ResponseStatus']: raise ServerResponseException(str(response['ResponseStatus']['ErrorCode'] + ": " + response['ResponseStatus']['Message'])) - elif response['ResponseStatus'].has_key('Message'): + elif 'Message' in response['ResponseStatus']: raise ServerResponseException(str(response['ResponseStatus']['Message'])) respObj = self.apiClient.deserialize(response, ListResponse.ListResponse) @@ -161,7 +161,7 @@ def __makeCurlRequest__(self, data, url): if not r: raise ServerResponseException("No response from server") obj = json.loads(r.text) - if obj.has_key('error'): + if 'error' in obj: raise ServerResponseException(str(obj['error'] + ": " + obj['error_description'])) return obj diff --git a/src/BaseSpacePy/api/BaseMountInterface.py b/src/BaseSpacePy/api/BaseMountInterface.py index 199f240..d7bd89d 100644 --- a/src/BaseSpacePy/api/BaseMountInterface.py +++ b/src/BaseSpacePy/api/BaseMountInterface.py @@ -74,12 +74,12 @@ def __str__(self): return "%s : (%s) : (%s)" % (self.path, self.id, self.type) def _get_access_token_from_config(self, config_path): - from ConfigParser import SafeConfigParser, NoSectionError, NoOptionError + from configparser import SafeConfigParser, NoSectionError, NoOptionError config = SafeConfigParser() config.read(config_path) try: return config.get("DEFAULT", "accessToken") - except NoOptionError, NoSectionError: + except NoOptionError as NoSectionError: raise BaseMountInterfaceException("malformed BaseMount config: %s" % config_path) @@ -105,4 +105,4 @@ def get_meta_data(self): import sys path = sys.argv[1] mbi = BaseMountInterface(path) - print mbi \ No newline at end of file + print(mbi) \ No newline at end of file diff --git a/src/BaseSpacePy/api/BaseSpaceAPI.py b/src/BaseSpacePy/api/BaseSpaceAPI.py index 099195b..7d8284c 100755 --- a/src/BaseSpacePy/api/BaseSpaceAPI.py +++ b/src/BaseSpacePy/api/BaseSpaceAPI.py @@ -1,17 +1,17 @@ from pprint import pprint -import urllib2 +import urllib.request, urllib.error, urllib.parse import shutil -import urllib -import httplib -import cStringIO +import urllib.request, urllib.parse, urllib.error +import http.client +import io import json import os import re from tempfile import mkdtemp import socket -import ConfigParser -import urlparse +import configparser +import urllib.parse import logging import getpass import requests @@ -65,7 +65,7 @@ def __init__(self, clientKey=None, clientSecret=None, apiServer=None, version='v # TODO this replacement won't work for all environments self.weburl = cred['apiServer'].replace('api.','') - apiServerAndVersion = urlparse.urljoin(cred['apiServer'], cred['apiVersion']) + apiServerAndVersion = urllib.parse.urljoin(cred['apiServer'], cred['apiVersion']) super(BaseSpaceAPI, self).__init__(cred['accessToken'], apiServerAndVersion, userAgent, timeout, verbose) def _setCredentials(self, clientKey, clientSecret, apiServer, apiVersion, appSessionId, accessToken, profile): @@ -134,32 +134,32 @@ def _getLocalCredentials(self, profile): raise CredentialsException("Could not find config file: %s" % config_file) section_name = "DEFAULT" cred = {} - config = ConfigParser.SafeConfigParser() + config = configparser.SafeConfigParser() if config.read(config_file): cred['name'] = profile try: cred['clientKey'] = config.get(section_name, "clientKey") - except ConfigParser.NoOptionError: + except configparser.NoOptionError: pass try: cred['clientSecret'] = config.get(section_name, "clientSecret") - except ConfigParser.NoOptionError: + except configparser.NoOptionError: pass try: cred['apiServer'] = config.get(section_name, "apiServer") - except ConfigParser.NoOptionError: + except configparser.NoOptionError: pass try: cred['apiVersion'] = config.get(section_name, "apiVersion") - except ConfigParser.NoOptionError: + except configparser.NoOptionError: pass try: cred['appSessionId'] = config.get(section_name, "appSessionId") - except ConfigParser.NoOptionError: + except configparser.NoOptionError: pass try: cred['accessToken'] = config.get(section_name, "accessToken") - except ConfigParser.NoOptionError: + except configparser.NoOptionError: pass return cred @@ -187,7 +187,7 @@ def getAppSessionOld(self, Id=None): raise AppSessionException("An AppSession Id is required") resourcePath = self.apiClient.apiServerAndVersion + '/appsessions/{AppSessionId}' resourcePath = resourcePath.replace('{AppSessionId}', Id) - response = cStringIO.StringIO() + response = io.StringIO() import requests response = requests.get(resourcePath, auth=(self.key, self.secret)) resp_dict = json.loads(response.text) @@ -219,7 +219,7 @@ def __deserializeAppSessionResponse__(self, response): :param response: a dictionary (decoded from json) from getting an AppSession from the api server :returns: An AppSession instance ''' - if response['ResponseStatus'].has_key('ErrorCode'): + if 'ErrorCode' in response['ResponseStatus']: raise AppSessionException('BaseSpace error: ' + str(response['ResponseStatus']['ErrorCode']) + ": " + response['ResponseStatus']['Message']) tempApi = APIClient(AccessToken='', apiServerAndVersion=self.apiClient.apiServerAndVersion, userAgent=self.apiClient.userAgent) res = tempApi.deserialize(response, AppSessionResponse.AppSessionResponse) @@ -360,7 +360,7 @@ def getWebVerificationCode(self, scope, redirectURL, state=''): :returns: a url ''' data = {'client_id': self.key, 'redirect_uri': redirectURL, 'scope': scope, 'response_type': 'code', "state": state} - return self.weburl + webAuthorize + '?' + urllib.urlencode(data) + return self.weburl + webAuthorize + '?' + urllib.parse.urlencode(data) def obtainAccessToken(self, code, grantType='device', redirect_uri=None): ''' @@ -395,12 +395,12 @@ def getAccessTokenDetails(self): raise ServerResponseException('Could not query access token endpoint: %s' % str(e)) if not response: raise ServerResponseException('No response returned') - if response.has_key('ResponseStatus'): - if response['ResponseStatus'].has_key('ErrorCode'): + if 'ResponseStatus' in response: + if 'ErrorCode' in response['ResponseStatus']: raise ServerResponseException(str(response['ResponseStatus']['ErrorCode'] + ": " + response['ResponseStatus']['Message'])) - elif response['ResponseStatus'].has_key('Message'): + elif 'Message' in response['ResponseStatus']: raise ServerResponseException(str(response['ResponseStatus']['Message'])) - elif response.has_key('ErrorCode'): + elif 'ErrorCode' in response: raise ServerResponseException(response["MessageFormatted"]) responseObject = self.apiClient.deserialize(response["Response"], Token.Token) @@ -977,7 +977,7 @@ def createAppResult(self, Id, name, desc, samples=None, appSessionId=None): ref.append(d) postData['References'] = ref # case, an appSession is provided, we need to check if the app is running - if queryParams.has_key('appsessionid'): + if 'appsessionid' in queryParams: session = self.getAppSession(Id=queryParams['appsessionid']) if not session.canWorkOn(): raise Exception('AppSession status must be "running," to create an AppResults. Current status is ' + session.Status) @@ -1035,7 +1035,7 @@ def createSample(self, Id, name, experimentName, sampleNumber, sampleTitle, read queryParams['appsessionid'] = self.appSessionId # default case, we use the current appsession # case, an appSession is provided, we need to check if the app is running - if queryParams.has_key('appsessionid'): + if 'appsessionid' in queryParams: session = self.getAppSession(Id=queryParams['appsessionid']) if not session.canWorkOn(): raise Exception('AppSession status must be "running," to create a Sample. Current status is ' + session.Status) @@ -1300,21 +1300,21 @@ def __downloadFile__(self, Id, localDir, name, byteRange=None, standaloneRangeFi queryParams['redirect'] = 'meta' # we need to add this parameter to get the Amazon link directly response = self.apiClient.callAPI(resourcePath, method, queryParams, None, headerParams) - if response['ResponseStatus'].has_key('ErrorCode'): + if 'ErrorCode' in response['ResponseStatus']: raise Exception('BaseSpace error: ' + str(response['ResponseStatus']['ErrorCode']) + ": " + response['ResponseStatus']['Message']) # get the Amazon URL, then do the download; for range requests include # size to ensure reading until end of data stream. Create local file if # it doesn't exist (don't truncate in case other processes from # multipart download also do this) - req = urllib2.Request(response['Response']['HrefContent']) + req = urllib.request.Request(response['Response']['HrefContent']) filename = os.path.join(localDir, name) if not os.path.exists(filename): open(filename, 'a').close() iter_size = 16*1024 # python default if len(byteRange): req.add_header('Range', 'bytes=%s-%s' % (byteRange[0], byteRange[1])) - flo = urllib2.urlopen(req, timeout=self.getTimeout()) # timeout prevents blocking + flo = urllib.request.urlopen(req, timeout=self.getTimeout()) # timeout prevents blocking totRead = 0 with open(filename, 'r+b', 0) as fp: if len(byteRange) and standaloneRangeFile == False: @@ -1372,7 +1372,7 @@ def fileUrl(self, Id): queryParams['redirect'] = 'meta' # we need to add this parameter to get the Amazon link directly response = self.apiClient.callAPI(resourcePath, method, queryParams, None, headerParams) - if response['ResponseStatus'].has_key('ErrorCode'): + if 'ErrorCode' in response['ResponseStatus']: raise Exception('BaseSpace error: ' + str(response['ResponseStatus']['ErrorCode']) + ": " + response['ResponseStatus']['Message']) return response['Response']['HrefContent'] @@ -1394,7 +1394,7 @@ def fileS3metadata(self, Id): queryParams['redirect'] = 'meta' # we need to add this parameter to get the Amazon link directly response = self.apiClient.callAPI(resourcePath, method, queryParams,None, headerParams) - if response['ResponseStatus'].has_key('ErrorCode'): + if 'ErrorCode' in response['ResponseStatus']: raise Exception('BaseSpace error: ' + str(response['ResponseStatus']['ErrorCode']) + ": " + response['ResponseStatus']['Message']) # record S3 URL @@ -1402,9 +1402,9 @@ def fileS3metadata(self, Id): # TODO should use HEAD call here, instead do small GET range request # GET S3 url and record etag - req = urllib2.Request(response['Response']['HrefContent']) + req = urllib.request.Request(response['Response']['HrefContent']) req.add_header('Range', 'bytes=%s-%s' % (0, 1)) - flo = urllib2.urlopen(req, timeout=self.getTimeout()) # timeout prevents blocking + flo = urllib.request.urlopen(req, timeout=self.getTimeout()) # timeout prevents blocking try: etag = flo.headers['etag'] except KeyError: @@ -1442,7 +1442,7 @@ def __dictionaryToProperties__(self, rawProperties, namespace): ''' LEGAL_KEY_TYPES = [str, int, float, bool] propList = [] - for key, value in rawProperties.iteritems(): + for key, value in rawProperties.items(): if type(value) not in LEGAL_KEY_TYPES: raise IllegalParameterException(type(value), LEGAL_KEY_TYPES) propName = "%s.%s" % (namespace, key) diff --git a/src/BaseSpacePy/api/BillingAPI.py b/src/BaseSpacePy/api/BillingAPI.py index d1af30a..e6211df 100644 --- a/src/BaseSpacePy/api/BillingAPI.py +++ b/src/BaseSpacePy/api/BillingAPI.py @@ -1,5 +1,5 @@ -import urlparse +import urllib.parse from BaseSpacePy.api.BaseAPI import BaseAPI from BaseSpacePy.api.BaseSpaceException import * #@UnusedWildImport from BaseSpacePy.model import * #@UnusedWildImport @@ -18,7 +18,7 @@ def __init__(self, apiServer, version, appSessionId='', AccessToken=''): ''' self.appSessionId = appSessionId self.version = version - apiServerAndVersion = urlparse.urljoin(apiServer, version) + apiServerAndVersion = urllib.parse.urljoin(apiServer, version) super(BillingAPI, self).__init__(AccessToken, apiServerAndVersion) def createPurchase(self, products, appSessionId=''): diff --git a/src/BaseSpacePy/model/ListResponse.py b/src/BaseSpacePy/model/ListResponse.py index edbf7f1..f7d49b1 100644 --- a/src/BaseSpacePy/model/ListResponse.py +++ b/src/BaseSpacePy/model/ListResponse.py @@ -1,6 +1,6 @@ import json -from StringIO import StringIO +from io import StringIO class ListResponse(object): diff --git a/src/BaseSpacePy/model/MultipartFileTransfer.py b/src/BaseSpacePy/model/MultipartFileTransfer.py index fc5adc3..f7e35d4 100644 --- a/src/BaseSpacePy/model/MultipartFileTransfer.py +++ b/src/BaseSpacePy/model/MultipartFileTransfer.py @@ -3,7 +3,7 @@ import os import math import multiprocessing -import Queue +import queue import shutil import signal import hashlib @@ -50,7 +50,7 @@ def execute(self, lock): self.err_msg = str(e) else: # ETag contains hex encoded MD5 of part data on success - if res and res['Response'].has_key('ETag'): + if res and 'ETag' in res['Response']: self.success = True else: self.success = False @@ -158,7 +158,7 @@ def run(self): while True: try: next_task = self.task_queue.get(True, self.get_task_timeout) # block until timeout - except Queue.Empty: + except queue.Empty: LOGGER.debug('Worker %s exiting, getting task from task queue timed out and/or is empty' % self.name) break if next_task is None: @@ -169,7 +169,7 @@ def run(self): # attempt to run tasks, with retry LOGGER.debug('Worker %s processing task: %s' % (self.name, str(next_task))) LOGGER.info('%s' % str(next_task)) - for i in xrange(1, self.retries + 1): + for i in range(1, self.retries + 1): if self.halt.is_set(): LOGGER.debug('Worker %s exiting, found halt signal' % self.name) self.task_queue.task_done() @@ -203,7 +203,7 @@ def purge_task_queue(self): while 1: try: self.task_queue.get(False) - except Queue.Empty: + except queue.Empty: break else: self.task_queue.task_done() @@ -233,7 +233,7 @@ def add_workers(self, num_workers): ''' Added workers to internal list of workers, adding a poison pill for each to the task queue ''' - self.consumers = [ Consumer(self.tasks, self.result_queue, self.halt_event, self.lock) for i in xrange(num_workers) ] + self.consumers = [ Consumer(self.tasks, self.result_queue, self.halt_event, self.lock) for i in range(num_workers) ] for c in self.consumers: self.tasks.put(None) @@ -258,7 +258,7 @@ def start_workers(self, finalize_callback): while 1: try: success = self.result_queue.get(False) # non-blocking - except Queue.Empty: + except queue.Empty: break else: if success == False: @@ -324,7 +324,7 @@ def _setup(self): # raise MultiProcessingTaskFailedException(err_msg) self.exe = Executor() - for i in xrange(self.start_chunk, fileCount): + for i in range(self.start_chunk, fileCount): t = UploadTask(self.api, self.remote_file.Id, i, fileCount, self.local_path, total_size, chunk_size) self.exe.add_task(t) self.exe.add_workers(self.process_count) @@ -416,7 +416,7 @@ def _setup(self): os.makedirs(self.full_temp_dir) self.exe = Executor() - for i in xrange(self.start_chunk, self.file_count+1): + for i in range(self.start_chunk, self.file_count+1): t = DownloadTask(self.api, self.file_id, file_name, self.full_local_dir, i, self.file_count, part_size_bytes, total_bytes, self.full_temp_dir) self.exe.add_task(t) @@ -452,7 +452,7 @@ def _combine_file_chunks(self): Assembles download files chunks into single large file, then cleanup by deleting file chunks ''' LOGGER.debug("Assembling downloaded file parts into single file") - part_files = [os.path.join(self.full_temp_dir, self.file_name + '.' + str(i)) for i in xrange(self.start_chunk, self.file_count+1)] + part_files = [os.path.join(self.full_temp_dir, self.file_name + '.' + str(i)) for i in range(self.start_chunk, self.file_count+1)] with open(os.path.join(self.full_local_dir, self.file_name), 'w+b') as whole_file: for part_file in part_files: shutil.copyfileobj(open(part_file, 'r+b'), whole_file) diff --git a/src/BaseSpacePy/model/QueryParameters.py b/src/BaseSpacePy/model/QueryParameters.py index f5570e2..fa9bd6a 100644 --- a/src/BaseSpacePy/model/QueryParameters.py +++ b/src/BaseSpacePy/model/QueryParameters.py @@ -37,7 +37,7 @@ def __init__(self, pars=None, required=None): required = [] self.passed = {} try: - for k in pars.keys(): + for k in list(pars.keys()): self.passed[k] = pars[k] except AttributeError: raise QueryParameterException("The 'pars' argument to QueryParameters must be a dictionary") @@ -64,10 +64,10 @@ def validate(self): :returns: None ''' for p in self.required: - if not self.passed.has_key(p): + if p not in self.passed: raise UndefinedParameterException(p) - for p in self.passed.keys(): - if not legal.has_key(p): + for p in list(self.passed.keys()): + if p not in legal: raise UnknownParameterException(p) if len(legal[p])>0 and (not self.passed[p] in legal[p]): raise IllegalParameterException(p,legal[p]) diff --git a/src/BaseSpacePy/model/QueryParametersPurchasedProduct.py b/src/BaseSpacePy/model/QueryParametersPurchasedProduct.py index 44279d3..65bcb11 100644 --- a/src/BaseSpacePy/model/QueryParametersPurchasedProduct.py +++ b/src/BaseSpacePy/model/QueryParametersPurchasedProduct.py @@ -11,7 +11,7 @@ def __init__(self, pars=None): if pars is None: pars = {} self.passed = {} - for k in pars.keys(): + for k in list(pars.keys()): self.passed[k] = pars[k] self.validate() @@ -25,6 +25,6 @@ def getParameterDict(self): return self.passed def validate(self): - for p in self.passed.keys(): - if not legal.has_key(p): + for p in list(self.passed.keys()): + if p not in legal: raise UnknownParameterException(p) diff --git a/test/launch_helpers_tests.py b/test/launch_helpers_tests.py index f0c47b0..2e92c5e 100644 --- a/test/launch_helpers_tests.py +++ b/test/launch_helpers_tests.py @@ -36,10 +36,10 @@ 'sample-id', ] app_defaults = { - 'AnnotationSource': u'RefSeq', - 'genome-id': u'Human', - 'GQX-id': u'30', - 'StrandBias-id': u'10', + 'AnnotationSource': 'RefSeq', + 'genome-id': 'Human', + 'GQX-id': '30', + 'StrandBias-id': '10', 'FlagPCRDuplicates-id': [] } diff --git a/test/test_models.py b/test/test_models.py index aa79ff9..2d4fb48 100644 --- a/test/test_models.py +++ b/test/test_models.py @@ -27,12 +27,12 @@ def compare_dict_to_obj(self, rest_dict, p_obj): """ Compare a dictionary from a REST API response and a SDK object for identity. """ - for r_key, r_val in rest_dict.iteritems(): + for r_key, r_val in rest_dict.items(): # confirm that the key from REST api exists in stored object try: p_val = getattr(p_obj, r_key) except AttributeError: - print "REST API attribute '" + r_key + "' doesn't exist in object" + print("REST API attribute '" + r_key + "' doesn't exist in object") else: self.classify_rest_item(r_val, p_val, r_key) @@ -41,9 +41,9 @@ def compare_list_to_obj(self, rest_list, p_obj, r_key): Compare a list from a REST API response and an SDK object for identity. """ if type(p_obj) != list: - print "Attribute '" + r_key + "' is a list in the REST API but not in the object" + print("Attribute '" + r_key + "' is a list in the REST API but not in the object") elif len(p_obj) != len(rest_list): - print "Attribute '" + r_key + "' has different list length between REST API and object" + print("Attribute '" + r_key + "' has different list length between REST API and object") else: for r_val, p_val in map(None, rest_list, p_obj): self.classify_rest_item(r_val, p_val, r_key) @@ -53,26 +53,26 @@ def compare_builtin_to_obj(self, rest_val, p_obj, r_key): Compare a built-in type from a REST API response and an SDK object for identity. """ # convert unicode to ascii for comparisons - if isinstance(rest_val, unicode): + if isinstance(rest_val, str): rest_val = rest_val.encode('ascii','ignore') # don't compare values for datetimes if r_key in ['DateCreated', 'DateModified', 'DateUploadCompleted', 'DateUploadStarted']: pass elif rest_val != p_obj: - print "REST API attribute '" + r_key + "' has value '" + str(rest_val) + "' doesn't match object value '" + str(p_obj) + "'" + print("REST API attribute '" + r_key + "' has value '" + str(rest_val) + "' doesn't match object value '" + str(p_obj) + "'") def classify_rest_item(self, r_val, p_val, r_key): """ Determine the input REST item's type and call method to compare to input object """ - if type(r_val) in [ int, str, bool, float, unicode]: + if type(r_val) in [ int, str, bool, float, str]: self.compare_builtin_to_obj(r_val, p_val, r_key) elif type(r_val) == dict: self.compare_dict_to_obj(r_val, p_val) elif type(r_val) == list: self.compare_list_to_obj(r_val, p_val, r_key) else: - print "REST API attribute'" + r_key + "' has an unrecognized attribute type" + print("REST API attribute'" + r_key + "' has an unrecognized attribute type") def test_rest_vs_sdk(self): """ @@ -308,69 +308,69 @@ def add_tests(self): try: self.tests.append((FilterVariantSet(cfg['vcf_id'], cfg['vcf_chr'], cfg['vcf_start'], cfg['vcf_end'], cfg['vcf_format'], cfg['query_p']), "with query parameter")) except AttributeError: - print "Skipping test FilterVariantSet -- missing input parameter" + print("Skipping test FilterVariantSet -- missing input parameter") try: self.tests.append((GetAppSessionById(cfg['ssn_id']), "test")) except AttributeError: - print "Skipping test GetAppSessionById -- missing input parameter" + print("Skipping test GetAppSessionById -- missing input parameter") try: self.tests.append((GetAppSessionPropertiesById(cfg['ssn_id'], cfg['query_p']), "with query parameter")) except AttributeError: - print "Skipping test GetAppSessionPropertiesById -- missing input parameter" + print("Skipping test GetAppSessionPropertiesById -- missing input parameter") try: - for key, value in cfg['multivalue_property_names'].iteritems(): + for key, value in cfg['multivalue_property_names'].items(): self.tests.append((GetAppSessionPropertyByName(cfg['ssn_id'], value, cfg['query_p']), key)) except AttributeError: - print "Skipping test GetAppSessionPropertiesByName -- missing input parameter" + print("Skipping test GetAppSessionPropertiesByName -- missing input parameter") try: self.tests.append((GetRunById(cfg['run_id'], cfg['query_p']), "with query parameter")) except AttributeError: - print "Skipping test GetRunById -- missing input parameter" + print("Skipping test GetRunById -- missing input parameter") try: self.tests.append((GetRunPropertiesById(cfg['run_id'], cfg['query_p']), "with query parameter")) except AttributeError: - print "Skipping test GetRunPropertiesById -- missing input parameter" + print("Skipping test GetRunPropertiesById -- missing input parameter") try: self.tests.append((GetProjectById(cfg['project_id'], cfg['query_p']), "with query parameter")) except AttributeError: - print "Skipping test GetProjectById -- missing input parameter" + print("Skipping test GetProjectById -- missing input parameter") try: self.tests.append((GetProjectPropertiesById(cfg['project_id'], cfg['query_p']), "with query parameter")) except AttributeError: - print "Skipping test GetProjectPropertiesById -- missing input parameter" + print("Skipping test GetProjectPropertiesById -- missing input parameter") try: self.tests.append((GetSampleById(cfg['sample_id'], cfg['query_p']), "with query parameter")) except AttributeError: - print "Skipping test GetSampleById -- missing input parameter" + print("Skipping test GetSampleById -- missing input parameter") try: self.tests.append((GetSamplePropertiesById(cfg['sample_id'], cfg['query_p']), "with query parameter")) except AttributeError: - print "Skipping test GetSamplePropertiesById -- missing input parameter" + print("Skipping test GetSamplePropertiesById -- missing input parameter") try: self.tests.append((GetAppResultById(cfg['appresult_id'], cfg['query_p']), "with query parameter")) except AttributeError: - print "Skipping test GetAppResultById -- missing input parameter" + print("Skipping test GetAppResultById -- missing input parameter") try: self.tests.append((GetAppResultPropertiesById(cfg['appresult_id'], cfg['query_p']), "with query parameter")) except AttributeError: - print "Skipping test GetAppResultPropertiesById -- missing input parameter" + print("Skipping test GetAppResultPropertiesById -- missing input parameter") try: self.tests.append((GetFileById(cfg['file_id'], cfg['query_p']), "with query parameter")) except AttributeError: - print "Skipping test GetFileById -- missing input parameter" + print("Skipping test GetFileById -- missing input parameter") try: self.tests.append((GetFilePropertiesById(cfg['file_id'], cfg['query_p']), "with query parameter")) except AttributeError: - print "Skipping test GetFilePropertiesById -- missing input parameter" + print("Skipping test GetFilePropertiesById -- missing input parameter") def test_rest_vs_sdk(self): for test in self.tests: - print "\nTesting REST vs SDK for " + test[0].__class__.__name__ + "' with comment '" + test[1] + "'" + print("\nTesting REST vs SDK for " + test[0].__class__.__name__ + "' with comment '" + test[1] + "'") try: test[0].test_rest_vs_sdk() except Exception as e: - print "Exception: " + str(e) + print("Exception: " + str(e)) if __name__ == '__main__': diff --git a/test/unit_tests.py b/test/unit_tests.py index be807ac..27e3afd 100644 --- a/test/unit_tests.py +++ b/test/unit_tests.py @@ -3,7 +3,7 @@ import sys from tempfile import mkdtemp import shutil -from urlparse import urlparse, urljoin +from urllib.parse import urlparse, urljoin import multiprocessing import hashlib import webbrowser