From 815b2423e28dce906bb763de81f2208fcfe69e57 Mon Sep 17 00:00:00 2001 From: Geoff Woodward Date: Wed, 30 Sep 2020 15:45:02 +0100 Subject: [PATCH 1/4] Moved API script to /JellyPy/scripts dir --- scripts/smsAPI/README.md | 16 ++ scripts/smsAPI/SMS_flow.png | Bin 0 -> 82789 bytes scripts/smsAPI/api_submission.py | 267 +++++++++++++++++++++++++++++++ scripts/smsAPI/config.py | 7 + 4 files changed, 290 insertions(+) create mode 100644 scripts/smsAPI/README.md create mode 100755 scripts/smsAPI/SMS_flow.png create mode 100644 scripts/smsAPI/api_submission.py create mode 100644 scripts/smsAPI/config.py diff --git a/scripts/smsAPI/README.md b/scripts/smsAPI/README.md new file mode 100644 index 0000000..d06ca32 --- /dev/null +++ b/scripts/smsAPI/README.md @@ -0,0 +1,16 @@ +# WGS PENGALLY SNPS using Nimagen RC-PCR kit on MiSeq +This project includes a script to parse GEL1001 csv messages and submit vcf payloads to the GEL WGS SMS service + +python api_submission.py ... + +*api_submission.py* +1) takes 1 or more GEL1001 csv file(s) as sample numbers are likely to be low at the beginning of service cases that need submission are likely to be spread over multiple worklists +2) requires a genotype directory with GATK filtered VCFs. +3) VCF files are parsed into payload text - removing non PASS SNPs / multiallelic loci / contigs (from the header) +4) parsed VCFs are saved in a central backup location to keep a reference of exact payload sent to the GEL SMS +5) Stringent logging of all processes stored in central backup location +6) Stringent error reporting to STDOUT as well as logs. + +![title](SMS_flow.png) + + diff --git a/scripts/smsAPI/SMS_flow.png b/scripts/smsAPI/SMS_flow.png new file mode 100755 index 0000000000000000000000000000000000000000..cbcd4cd8c99bd6985971bd40b5d207491fe9069d GIT binary patch literal 82789 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 Z5$0J*XCoQKb3g{@l+o!E#ABCk{|{#)5QG2# literal 0 HcmV?d00001 diff --git a/scripts/smsAPI/api_submission.py b/scripts/smsAPI/api_submission.py new file mode 100644 index 0000000..dfda3f9 --- /dev/null +++ b/scripts/smsAPI/api_submission.py @@ -0,0 +1,267 @@ +import requests +import base64 +import gzip +import glob +import argparse +import os +import csv +import datetime +import config +import json + +requests.packages.urllib3.disable_warnings() + +def getB64(): + """ base64 encodes the credentials for the API """ + message = ":".join([config.username, config.password]) + b64_message = base64.b64encode(message) + return b64_message + + +def getToken(b64, log): + """ + Gets authentication token for the WGS SMS service + uses a hardcoded string of our base64 encoded credentials + returns an access_token for authentication on the main API + """ + payload = {'grant_type': 'client_credentials'} + files = [] + headers = { + 'Authorization': 'Basic {}'.format(b64) + } + response = requests.request("POST", config.auth_url, headers=headers, data = payload, files = files) + payload = response.json() + updateLog(log, "Requesting Bearer Token from: {}".format(config.auth_url)) + updateLog(log, "\tsuccess: expires_in={}".format(payload['expires_in'])) + return payload['access_token'] + + +def retrieveVCF(token, referal, patient, lsid): + """ + requests the return of a previously uploaded VCF + requires authentication token, referal id, patient id, lab id. + prints the VCF to STDOUT + """ + url = config.sms_url + "/".join([referal, patient, lsid+"?="]) + payload = {} + headers = {'Authorization': 'Bearer {}'.format(token)} + response = requests.request("GET", url, headers = headers, data = payload) + print response.text.encode('utf8') + + +def uploadVCF(token, payload, referal, patient, lsid, log): + """ + Uses am API PUt command to upload a VCF + requires authentication token, referal id, patient id, lab id. + Reads VCF into string payload. + prints API response text to STDOUT + """ + url = config.sms_url + "/".join([referal, patient, lsid+"?="]) + headers = {'Content-Type': 'application/x-www-form-urlencoded', + 'Authorization': 'Bearer {}'.format(token)} + response = requests.request("PUT", url, headers = headers, data = payload) + r = json.loads(response.content) + updateLog(log, response.text.encode('utf8')) + return r['status'] + + +def uploadCases(token, samples, log): + """ loop over cases calling uploadVCF() """ + updateLog(log, "Uploading Cases to API") + responses={} + for case, details in samples.items(): + status = uploadVCF( + token, details['payload'], + details['ref_id'], details['p_id'], + details['lsid'], log) + responses.setdefault(status, []).append(case) + return responses + + +def load1001(gelcsvs, log): + """ + Parses 0..N GEL1001 message (CSV file) into a dictionary + of dictionaries. First layer is the samples by bnumber + then under this key there is a dictionary of GEL IDs. + Referral, Patient and Lims IDs + """ + updateLog(log, "Processing {} GEL1001 Messages".format(len(gelcsvs))) + samples={} + for x, gelcsv in enumerate(gelcsvs): + updateLog(log, "\t{}: loading {}".format(str(x+1), gelcsv)) + with open(gelcsv, 'r') as gel: + csvr = csv.reader(gel) + for row in csvr: + if row[0] == "referral_id": + continue + samples[row[8]] = { + 'ref_id': row[0], + 'p_id': row[3], + 'lsid': row[18] + } + updateLog(log, "\t\t{} total cases evaluated".format(len(samples.keys()))) + return samples + + +def processVCF(text, lsid, log): + """ + Parse the VCF file content - as list from readlines() + 1) replace Bnumber with the LSID + 2) remove >1300 contigs from the VCF payload. + 3) remove any poor QC variants (!PASS) + 4) remove any loci with multiallelic ALT fields + return parsed list of lines or 0 if <24 PASS loci + """ + parsed = [] + failed = [] + for line in text: + if line.startswith('##contig'): #remove 100's of CONTIGs from header + continue + if line.startswith('#CHROM'): # replace bnumber (VCF sample ID) with LSID + bits = line.split("\t") + bits[9] = lsid+'\n' + line = "\t".join(bits) + if line.startswith('chr'): + if not 'PASS' in line: # remove poor quality LOCI + failed.append(line) + continue + fields = line.split('\t') + ALT = fields[4] + if len(ALT) > 1: # remove multiallelic loci + failed.append(line) + continue + parsed.append(line) + + payload = "".join(parsed) + if len(failed) > 10: # if less than 24/34 PASS raise an Error + updateLog(log, '\t\t{} Failed QC after removing {} SNPs - not uploading to API'.format(lsid, str(len(failed)))) + raise ValueError('\tQC failure: {} SNPs omitted - not uploading to API'.format(str(len(failed)))) + else: + return payload + + +def saveParsedVCF(case, lsid, body, log): + date = datetime.date.today().strftime("%d%m%Y") + newfile=os.path.join(config.log_path, date, "{}_{}.vcf".format(case, lsid)) + updateLog(log, "\t\tSaving parsed VCF: {}".format(newfile)) + with open(newfile, 'w') as newvcf: + newvcf.write(body) + + +def prepareVCFs(samples, log): + """ + Loop over GEL1001 cases + 1) call readVCF() to load into memory + 2) call processVCF() to QC / update IDs etc + 3) return updated samples dictionary + """ + updateLog(log, "Preparing VCF files for upload") + for case, details in samples.items(): + if details['vcf'] == "na": + updateLog(log, "\tNo '*snp_genotype.vcf' found for pid: {} - CHECK!!".format(details['p_id'])) + else: + updateLog(log, "\tProcessing {}: {}".format(case, details['vcf'])) + payload = readVCF(details['vcf']) + try: + payload = processVCF(payload, details['lsid'], log) + saveParsedVCF(case, details['lsid'], payload, log) + samples[case]['payload'] = payload + except ValueError as e: + print e + samples[case]['payload'] = False + del(samples[case]) + continue + return samples + + +def readVCF(vcf): + """ read VCF into readlines object """ + vcfh = open(os.path.join(vcf), 'r') + vcf_list = vcfh.readlines() + return vcf_list + + +def findVCFs(samples, path, log): + """ + Search supplied directory for VCFs matching Bnumbers in the GEL1001 message(s). + VCFs are assigned to the sample dictionary if a vcf matches on bnumnber. + Returns an updated "samples" dictionary with full VCF paths + """ + updateLog(log, "Locating VCF files in: {}".format(path)) + pattern = "*snp_genotype.vcf" + files = glob.glob(os.path.join(path, pattern)) + for case, details in samples.items(): + print case + hits = [f for f in files if case in f] + if len(hits) > 0: + samples[case]['vcf'] = hits[0] + else: + samples[case]['vcf'] = "na" + if samples[case]['vcf'] == "na": + del(samples[case]) + + if len(samples) == 0: + print "No VCFs found - please check the filepath and try again" + exit() + + return samples + + +def initialiseLog(): + """ + Create log dir under date + return filehandle to log named __SMS_upload_log.txt + """ + date = datetime.date.today().strftime("%d%m%Y") + date_hm = datetime.datetime.today().strftime("%d%m%Y_%H%M") + logdir = os.path.join(config.log_path, date) + if not os.path.exists(logdir): + os.mkdir(logdir) + logfile = os.path.join(config.log_path, date, date_hm+"_SMS_upload_log.txt") + updateLog(logfile, "\n\n==================================") + updateLog(logfile, "INITIALISED API_SUBMISSION.PY") + updateLog(logfile, date_hm) + updateLog(logfile, "==================================") + return logfile + + +def updateLog(logpath, message): + """ writes the message to supplied filepath """ + with open(logpath, 'a') as logh: + logh.write(message+"\n") + + +def printSummary(responses, log): + """ + Prints a summary to STDOUT showing the number of succesful + (or not) submissions to the SMS API with a link to the logfile + """ + print ["{}: {}".format(r, len(c)) for r, c in responses.items()] + print "\nProcessing completed... please check:\n\t* {}\n ... for more details\n\n".format(log) + + +if __name__ == "__main__": + """ + This script submits WGS SNP VCFs to the Whole Genome Sequencing + SNP Matching System (WGS SMS). + To run this script you need to have the GEL1001 message(s) (CSV) + containing all of the relevant GEL IDS (referral, patient, lab) + The user must also supply the path of the VCFs. + Authentication tokens will be generated and the VCFs will + be automatically uploaded. + """ + parser = argparse.ArgumentParser() + parser.add_argument("folder", help="Path of folder containing WGS genotype VCF files", + type=str) + parser.add_argument("csv", help="Path of GEL1001 CSV file(s)", + type=str, nargs="+") + args = parser.parse_args() + + log = initialiseLog() + samples = load1001(args.csv, log) + samples = findVCFs(samples, args.folder, log) + data = prepareVCFs(samples, log) + basic = getB64() + token = getToken(basic, log) + responses = uploadCases(token, data, log) + printSummary(responses, log) \ No newline at end of file diff --git a/scripts/smsAPI/config.py b/scripts/smsAPI/config.py new file mode 100644 index 0000000..17848d0 --- /dev/null +++ b/scripts/smsAPI/config.py @@ -0,0 +1,7 @@ +username = '9a8d9d36-0a9a-492f-aa47-adbaa9cd385d' +password = 'S6a75P7RMvEF4PS01Awo2As9GyYYUqcycYv8UV6IjF8=' + +auth_url = "https://login.microsoftonline.com/afee026d-8f37-400e-8869-72d9124873e4/oauth2/token" +sms_url = "https://samplematchservice-gms-beta.genomicsengland.nhs.uk/sample_vcf/" + +log_path = "/mnt/K_wgs_logs/" \ No newline at end of file From 3485becb52f1f45e451240940a5eca1db908b675 Mon Sep 17 00:00:00 2001 From: Geoff Date: Wed, 30 Sep 2020 15:50:42 +0100 Subject: [PATCH 2/4] Update config.py anonymised config.py --- scripts/smsAPI/config.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/smsAPI/config.py b/scripts/smsAPI/config.py index 17848d0..8a38e5d 100644 --- a/scripts/smsAPI/config.py +++ b/scripts/smsAPI/config.py @@ -1,7 +1,7 @@ -username = '9a8d9d36-0a9a-492f-aa47-adbaa9cd385d' -password = 'S6a75P7RMvEF4PS01Awo2As9GyYYUqcycYv8UV6IjF8=' +username = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' +password = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' auth_url = "https://login.microsoftonline.com/afee026d-8f37-400e-8869-72d9124873e4/oauth2/token" sms_url = "https://samplematchservice-gms-beta.genomicsengland.nhs.uk/sample_vcf/" -log_path = "/mnt/K_wgs_logs/" \ No newline at end of file +log_path = "/path/to/log_stash/" From 840db793a74737a0a332bc69fbb1254036c4e971 Mon Sep 17 00:00:00 2001 From: Geoff Date: Wed, 30 Sep 2020 17:22:19 +0100 Subject: [PATCH 3/4] Update config.py changed username/password to: client_id/secret --- scripts/smsAPI/config.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/smsAPI/config.py b/scripts/smsAPI/config.py index 8a38e5d..dd8919a 100644 --- a/scripts/smsAPI/config.py +++ b/scripts/smsAPI/config.py @@ -1,5 +1,5 @@ -username = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' -password = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' +client_id = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' +secret = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' auth_url = "https://login.microsoftonline.com/afee026d-8f37-400e-8869-72d9124873e4/oauth2/token" sms_url = "https://samplematchservice-gms-beta.genomicsengland.nhs.uk/sample_vcf/" From 80a574d1373a3e1da47afb8e17fbe454e24160f8 Mon Sep 17 00:00:00 2001 From: Geoff Date: Wed, 30 Sep 2020 17:22:46 +0100 Subject: [PATCH 4/4] Update api_submission.py --- scripts/smsAPI/api_submission.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/smsAPI/api_submission.py b/scripts/smsAPI/api_submission.py index dfda3f9..510f044 100644 --- a/scripts/smsAPI/api_submission.py +++ b/scripts/smsAPI/api_submission.py @@ -13,7 +13,7 @@ def getB64(): """ base64 encodes the credentials for the API """ - message = ":".join([config.username, config.password]) + message = ":".join([config.client_id, config.secret]) b64_message = base64.b64encode(message) return b64_message @@ -264,4 +264,4 @@ def printSummary(responses, log): basic = getB64() token = getToken(basic, log) responses = uploadCases(token, data, log) - printSummary(responses, log) \ No newline at end of file + printSummary(responses, log)