692b26d94a66f8c655dc65a2d4e697dcd500e5e8 chmalee Tue May 14 15:48:44 2019 -0700 Adding python client to userapps, refs #18869 diff --git src/utils/ucscApiClient src/utils/ucscApiClient new file mode 100755 index 0000000..aa88e2a --- /dev/null +++ src/utils/ucscApiClient @@ -0,0 +1,147 @@ +#!/bin/env python + +""" +This code is inspired by the Ensembl python client +https://github.com/Ensembl/ensembl-rest/wiki/Example-Python-Client +""" +import argparse +import json +import sys +from collections import OrderedDict + +# support python2 and 3 +try: + from urllib.parse import urlparse, urlencode + from urllib.request import urlopen, Request + from urllib.error import HTTPError +except ImportError: + from urlparse import urlparse + from urllib import urlencode + from urllib2 import urlopen, Request, HTTPError + +serverName = "https://api.genome.ucsc.edu" + +def parseCommandLine(): + parser = argparse.ArgumentParser(formatter_class=argparse.RawDescriptionHelpFormatter, + description="Command line utility for UCSC Genome Browser API access", + epilog="Example usage:\nucscApiClient \"/getData/track\" " + "\"track=gold;genome=hg38;chrom=chrM;maxItemsOutput=2\"") + parser.add_argument("endpoint", nargs='?', default="", + help="Endpoint string like \"/list/tracks\" or \"/getData/track/\"", type=str) + parser.add_argument("parameters", nargs='?', default="", + help="Parameters to endpoints. semi-colon separated key=value formatted string, " + "like \"genome=hg38;chrom=chrM;maxItemsOutput=2\"",type=str) + parser.add_argument("-p", "--pretty-print", action="store_true", default=False, + help="Print json response with newlines") + parser.add_argument("--debug", action="store_true", default=False, + help="Print final URL of the request") + parser.add_argument("-test0", action="store_true", default=False, + help="Run special test") + parser.add_argument("-getDnaExample", action="store_true", default=False, + help="Show example query for fetching Human GRCh38(hg38) DNA sequence") + return parser + +def tryJsonRequest(requestUrl): + """ + Wrap call to urlopen in try/except and exit on an HTTP error. + Returns json response if request is good. + """ + data = None + try: + request = Request(requestUrl) + response = urlopen(request) + content = response.read() + if content: + data = json.loads(content, object_pairs_hook=OrderedDict) + except HTTPError as e: + if e.code == 400: # does this work for other status codes? + msg = json.loads(e.read(), object_pairs_hook=OrderedDict) + sys.stderr.write("Error: %s\n" % msg["error"]) + sys.exit(1) + else: + sys.stderr.write("Request %s failed with HTTP status %s\nreason:%s\n" % + (requestUrl, e.code, e.reason)) + sys.exit(1) + return data + +def runGetDnaExample(prettyPrint=False): + """ + Run test of getting short DNA sequence from the hg38 assembly and exit. + """ + req = serverName + "/getData/sequence?genome=hg38;chrom=chr1;start=11110531;end=11110538" + data = tryJsonRequest(req) + if data: + print("Example request for obtaining DNA sequence:\n%s" % req) + if prettyPrint: + print(json.dumps(data, indent=4, separators=(" , "," : "))) + else: + print(json.dumps(data)) + sys.exit(0) + +def runTest0(prettyPrint=False): + """ + Run test of getting public hub data for "Plants" and print UCSC info + for the hg38 genome and exit + """ + hubRequest = serverName + "/list/publicHubs" + hg38Request = serverName + "/list/ucscGenomes" + + # do plants hub test first + data = tryJsonRequest(hubRequest) + if data: + plantData = None + for obj in data['publicHubs']: + if obj['shortLabel'] == 'Plants': + plantData = obj + if plantData is not None: + print("Plants public hub data") + if prettyPrint: + print(json.dumps(plantData,indent=4, separators=(",",":"))) + else: + print(json.dumps(plantData)) + + # now do ucsc hg38 test + data = tryJsonRequest(hg38Request) + if data: + hg38Data = None + if data['ucscGenomes']['hg38']: + hg38Data = data['ucscGenomes']['hg38'] + if hg38Data is not None: + print("hg38/Human information") + if prettyPrint: + print(json.dumps(hg38Data,indent=4, separators=(",",":"))) + else: + print(json.dumps(hg38Data)) + sys.exit(0) + +def main(): + cmd = parseCommandLine() + args = cmd.parse_args() + req = serverName + + if len(sys.argv) == 1: + cmd.print_help() + sys.exit(0) + + # run special test + if args.test0: + runTest0(args.pretty_print) + + if args.getDnaExample: + runGetDnaExample(args.pretty_print) + + req += args.endpoint + "?" + args.parameters + + # make http request and print the output + data = None + if args.debug: + print("request URL: %s\n" % req) + data = tryJsonRequest(req) + if data: + if args.pretty_print: + print(json.dumps(data, indent=4, separators=(",",":"))) + else: + print(json.dumps(data)) + +if __name__ == "__main__": + main()