Exemplo n.º 1
0
def api_variant_create(variant_chgvs=None, caller=None, api_key=None):
    # print(request.form)
    # print(request.args)
    # get params
    # swagger/curl sends request.args e.g.
    # curl -X POST "http://10.34.20.79:5001/api/variant/create?variant_chgvs=NM_005422.2%3Ac.5040G%3ET&api_key=XXX" -H  "accept: application/json"
    # while
    # urllib3 request from create_vars_batch.py sends request.form
    if request.args.get('variant_chgvs') and \
            request.args.get('caller') and \
            request.args.get('api_key'):
        variant_chgvs = request.args.get('variant_chgvs', type=str)
        caller = request.args.get('caller', type=str)
        api_key = request.args.get('api_key', type=str)
    elif 'variant_chgvs' in request.form and \
            'caller' in request.form and \
            'api_key' in request.form:
        variant_chgvs = request.form['variant_chgvs']
        caller = request.form['caller']
        api_key = request.form['api_key']
    else:
        if caller == 'cli':
            return jsonify(mobidetails_error='I cannot fetch the right parameters')
        else:
            flash('I cannot fetch the right parameters', 'w3-pale-red')
            return redirect(url_for('md.index'))
    if variant_chgvs is not None and \
            caller is not None and \
            api_key is not None:
        db = get_db()
        curs = db.cursor(cursor_factory=psycopg2.extras.DictCursor)
        # mobiuser_id = None
        res_check_api_key = md_utilities.check_api_key(db, api_key)
        if 'mobidetails_error' in res_check_api_key:
            if caller == 'cli':
                return jsonify(res_check_api_key)
            else:
                flash(res_check_api_key['mobidetails_error'], 'w3-pale-red')
                return redirect(url_for('md.index'))
        else:
            g.user = res_check_api_key['mobiuser']
        if md_utilities.check_caller(caller) == 'Invalid caller submitted':
            if caller == 'cli':
                return jsonify(mobidetails_error='Invalid caller submitted')
            else:
                flash('Invalid caller submitted to API.', 'w3-pale-red')
                return redirect(url_for('md.index'))
        # if len(api_key) != 43:
        #     return jsonify(mobidetails_error='Invalid API key')
        # else:
        #     curs.execute(
        #         "SELECT * FROM mobiuser WHERE api_key = %s",
        #         (api_key,)
        #     )
        #     res = curs.fetchone()
        #     if res is None:
        #         return jsonify(mobidetails_error='Unknown API key')
        #     else:
        #         g.user = res
        # if variant_chgvs is None:
        #     return jsonify(mobidetails_error='No variant submitted')
        variant_regexp = md_utilities.regexp['variant']
        match_object = re.search(rf'^([Nn][Mm]_\d+)\.(\d{{1,2}}):c\.({variant_regexp})', urllib.parse.unquote(variant_chgvs))
        if match_object:
            # match_object = re.search(r'^([Nn][Mm]_\d+)\.(\d{1,2}):c\.(.+)', variant_chgvs)
            acc_no, acc_version, new_variant = match_object.group(1), match_object.group(2), match_object.group(3)
            new_variant = new_variant.replace(" ", "").replace("\t", "")
            # new_variant = new_variant.replace("\t", "")
            original_variant = new_variant
            curs.execute(
                "SELECT id FROM variant_feature WHERE c_name = %s AND gene_name[2] = %s",
                (new_variant, acc_no)
            )
            res = curs.fetchone()
            if res is not None:
                if caller == 'cli':
                    return jsonify(
                        mobidetails_id=res['id'],
                        url='{0}{1}'.format(
                            request.host_url[:-1],
                            url_for('md.variant', variant_id=res['id'])
                        )
                    )
                else:
                    return redirect(url_for('md.variant', variant_id=res['id']))
                
            else:
                # creation
                # get gene
                curs.execute(
                    "SELECT name[1] as gene FROM gene WHERE name[2] = %s",
                    (acc_no,)
                )
                res_gene = curs.fetchone()
                if res_gene is None:
                    return jsonify(mobidetails_error='The gene corresponding to {} is not yet present in MobiDetails'.format(acc_no))
               
                vv_base_url = md_utilities.get_vv_api_url()
                if not vv_base_url:
                    close_db()
                    if caller == 'cli':
                        return jsonify(mobidetails_error='Variant Validator looks down!.')
                    else:
                        flash('TVariant Validator looks down!.', 'w3-pale-red')
                        return redirect(url_for('md.index'))
                vv_url = "{0}VariantValidator/variantvalidator/GRCh38/{1}.{2}:{3}/all?content-type=application/json".format(
                    vv_base_url, acc_no, acc_version, new_variant
                )
                vv_key_var = "{0}.{1}:c.{2}".format(acc_no, acc_version, new_variant)

                try:
                    http = urllib3.PoolManager(cert_reqs='CERT_REQUIRED', ca_certs=certifi.where())
                    vv_data = json.loads(http.request('GET', vv_url).data.decode('utf-8'))
                except Exception:
                    close_db()
                    if caller == 'cli':
                        return jsonify(mobidetails_error='Variant Validator did not return any value for the variant {}.'.format(new_variant))
                    else:
                        try:
                            flash('There has been a issue with the annotation of the variant via VariantValidator. \
                                  The error is the following: {}'.format(vv_data['validation_warning_1']['validation_warnings']), 'w3-pale-red')
                        except Exception:
                            flash('There has been a issue with the annotation of the variant via VariantValidator. \
                                  Sorry for the inconvenience. You may want to try directly in MobiDetails.', 'w3-pale-red')
                        return redirect(url_for('md.index'))
                if re.search('[di][neu][psl]', new_variant):
                    # need to redefine vv_key_var for indels as the variant name returned by vv is likely to be different form the user's
                    for key in vv_data.keys():
                        if re.search('{0}.{1}'.format(acc_no, acc_version), key):
                            vv_key_var = key
                            # print(key)
                            var_obj = re.search(r':c\.(.+)$', key)
                            if var_obj is not None:
                                new_variant = var_obj.group(1)
                creation_dict = md_utilities.create_var_vv(
                    vv_key_var, res_gene['gene'], acc_no,
                    'c.{}'.format(new_variant), original_variant,
                    acc_version, vv_data, 'api', db, g
                )
                if caller == 'cli':
                    return jsonify(creation_dict)
                else:
                    return redirect(url_for('md.variant', variant_id=creation_dict['mobidetails_id']))
        else:
            if caller == 'cli':
                return jsonify(mobidetails_error='Malformed query {}'.format(urllib.parse.unquote(variant_chgvs)))
            else:
                flash('The query seems to be malformed: {}.'.format(urllib.parse.unquote(variant_chgvs)), 'w3-pale-red')
                return redirect(url_for('md.index'))
    else:
        if caller == 'cli':
            return jsonify(mobidetails_error='Invalid parameters')
        else:
            flash('The submitted parameters looks invalid!!!', 'w3-pale-red')
            return redirect(url_for('md.index'))
Exemplo n.º 2
0
def api_variant_create_rs(rs_id=None, caller=None, api_key=None):
     # get params
    if request.args.get('rs_id') and \
            request.args.get('caller') and \
            request.args.get('api_key'):
        rs_id = request.args.get('rs_id', type=str)
        caller = request.args.get('caller', type=str)
        api_key = request.args.get('api_key', type=str)
    elif 'rs_id' in request.form and \
            'caller' in request.form and \
            'api_key' in request.form:
        rs_id = request.form['rs_id']
        caller = request.form['caller']
        api_key = request.form['api_key']
    else:
        if caller == 'cli':
            return jsonify(mobidetails_error='I cannot fetch the right parameters')
        else:
            flash('I cannot fetch the right parameters for MD API.', 'w3-pale-red')
            return redirect(url_for('md.index'))
    db = get_db()
    curs = db.cursor(cursor_factory=psycopg2.extras.DictCursor)
    # check api key
    res_check_api_key = md_utilities.check_api_key(db, api_key)
    if 'mobidetails_error' in res_check_api_key:
        if caller == 'cli':
            return jsonify(res_check_api_key)
        else:
            flash(res_check_api_key['mobidetails_error'], 'w3-pale-red')
            return redirect(url_for('md.index'))
    else:
        g.user = res_check_api_key['mobiuser']
    # check caller
    if md_utilities.check_caller(caller) == 'Invalid caller submitted':
        if caller == 'cli':
            return jsonify(mobidetails_error='Invalid caller submitted')
        else:
            flash('Invalid caller submitted to the API.', 'w3-pale-red')
            return redirect(url_for('md.index'))
    # check rs_id
    trunc_rs_id = None
    match_obj = re.search(r'^rs(\d+)$', rs_id)
    if match_obj:
        trunc_rs_id = match_obj.group(1)
        # check if rsid exists
        curs.execute(
            "SELECT a.c_name, a.id, b.name[2] as nm, b.nm_version FROM variant_feature a, gene b WHERE a.gene_name = b.name AND a.dbsnp_id = %s",
            (trunc_rs_id,)
        )
        res_rs = curs.fetchall()
        if res_rs:
            vars_rs = {}
            for var in res_rs:
                current_var = '{0}.{1}:c.{2}'.format(var['nm'], var['nm_version'], var['c_name'])
                vars_rs[current_var] = {
                    'mobidetails_id': var['id'],
                    'url': '{0}{1}'.format(
                        request.host_url[:-1],
                        url_for('md.variant', variant_id=var['id'])
                    )
                }
            if caller == 'cli':
                    return jsonify(vars_rs)
            else:
                if len(res_rs) == 1:
                    return redirect(url_for('md.variant', variant_id=res_rs['id']))
                else:                  
                    return redirect(url_for('md.variant_multiple', vars_rs=vars_rs))
        # use putalyzer to get HGVS noemclatures
        http = urllib3.PoolManager(cert_reqs='CERT_REQUIRED', ca_certs=certifi.where())
        mutalyzer_url = "{0}getdbSNPDescriptions?rs_id={1}".format(
            md_utilities.urls['mutalyzer_api_json'], rs_id
        )
        # returns sthg like
        # ["NC_000011.10:g.112088901C>T", "NC_000011.9:g.111959625C>T", "NG_012337.3:g.7055C>T", "NM_003002.4:c.204C>T", "NM_003002.3:c.204C>T", "NM_001276506.2:c.204C>T", "NM_001276506.1:c.204C>T", "NR_077060.2:n.239C>T", "NR_077060.1:n.288C>T", "NM_001276504.2:c.87C>T", "NM_001276504.1:c.87C>T", "NG_033145.1:g.2898G>A"]
        try:
            mutalyzer_data = json.loads(http.request('GET', mutalyzer_url).data.decode('utf-8'))
        except Exception:
            close_db()
            if caller == 'cli':
                return jsonify(mobidetails_error='Mutalyzer did not return any value for the variant {}.'.format(rs_id))
            else:
                flash('Mutalyzer did not return any value for the variant {}'.format(rs_id), 'w3-pale-red')
                return redirect(url_for('md.index'))
        # print(mutalyzer_data)
        md_response = {}
        # md_nm = list of NM recorded in MD, to be sure not to consider unexisting NM acc no
        # md_nm = []
        hgvs_nc = []
        gene_names = []
        # can_nm = None
        for hgvs in mutalyzer_data:  # works for exonic variants because mutalyzer returns no NM for intronic variants
            variant_regexp = md_utilities.regexp['variant']
            # match_nm = re.search(rf'^(NM_\d+)\.\d+:c\.({variant_regexp})$', hgvs)
            # if match_nm:
            #     current_nm = match_nm.group(1)
            #     # get list of NM recorded in MD
            #     if not md_nm:
            #         curs.execute(
            #             "SELECT name[2] as nm FROM gene WHERE name[1] = (SELECT name[1] FROM gene WHERE name[2] = %s)",
            #             (current_nm,)
            #         )
            #         res_nm_all = curs.fetchall()
            #         if res_nm_all:
            #             for nm in res_nm_all:
            #                 md_nm.append(nm[0])
            #     if current_nm in md_nm:
            #         # check if variant with same name already recorded => at least we do not query multiple times for these
            #         curs.execute(
            #             "SELECT id FROM variant_feature WHERE dbsnp_id = %s AND c_name = %s",
            #             (trunc_rs_id, match_nm.group(2),)
            #         )
            #         res_known = curs.fetchall()
            #         if not res_known:
            #             # get gene and MD current NM version
            #             curs.execute(
            #                 "SELECT nm_version FROM gene WHERE name[2] = %s",
            #                 (current_nm,)
            #             )
            #             res_nm = curs.fetchone()
            #             if res_nm:
            #                 md_api_url = '{0}{1}'.format(request.host_url[:-1], url_for('api.api_variant_create'))
            #                 variant_chgvs = '{0}.{1}:c.{2}'.format(current_nm, res_nm['nm_version'], match_nm.group(2))
            #                 data = {
            #                     'variant_chgvs': urllib.parse.quote(variant_chgvs),
            #                     'caller': 'cli',
            #                     'api_key': api_key
            #                 }
            #                 try:
            #                     md_response[variant_chgvs] = json.loads(http.request('POST', md_api_url, headers=md_utilities.api_agent, fields=data).data.decode('utf-8'))
            #                 except Exception:
            #                     md_response[variant_chgvs] = {'mobidetails_error': 'MobiDetails returned an unexpected error for your request {0}: {1}'.format(rs_id, variant_chgvs)}
            #             else:
            #                 continue
            #         else:
            #             continue
            #     else:
            #         continue
            # intronic variant?
            # we need HGVS genomic to launch the API but also the gene - got from NG
            # f-strings usage https://stackoverflow.com/questions/6930982/how-to-use-a-variable-inside-a-regular-expression
            # https://www.python.org/dev/peps/pep-0498/
            match_nc = re.search(rf'^(NC_0000\d{{2}}\.\d{{1,2}}):g\.({variant_regexp})$', hgvs)
            if match_nc and \
                    not md_response:
                # if hg38, we keep it in a variable that can be useful later
                curs.execute(
                    "SELECT name, genome_version FROM chromosomes WHERE ncbi_name = %s",
                    (match_nc.group(1),)
                )
                res_chr = curs.fetchone()
                if res_chr and \
                        res_chr['genome_version'] == 'hg38':
                    hgvs_nc.append(hgvs)
                    # look for gene name
                    positions = md_utilities.compute_start_end_pos(match_nc.group(2))
                    # print("SELECT a.name[1] as hgnc FROM gene a, segment b WHERE a.name = b.gene_name AND a.chr = {0} AND {1} BETWEEN SYMMETRIC # b.segment_start AND b.segment_end".format(res_chr['name'], positions[0]))
                    if not gene_names:
                        curs.execute(
                            "SELECT DISTINCT(a.name[1]) as hgnc FROM gene a, segment b WHERE a.name = b.gene_name AND a.chr = %s AND %s BETWEEN SYMMETRIC b.segment_start AND b.segment_end",
                            (res_chr['name'], positions[0])
                        )
                        res_gene = curs.fetchall()
                        if res_gene:
                            for hgnc_name in res_gene:
                                gene_names.append(hgnc_name[0])
            # match_ng = re.search(rf'^(NG_\d+)\.\d+:g\.{variant_regexp}$', hgvs)
            # if match_ng and \
            #         not gene_name and \
            #         not md_response:
            #     # we need to get the gene name that can be useful later
            #     curs.execute(
            #         "SELECT name[1] as hgnc FROM gene WHERE ng LIKE %s AND canonical = 't'",
            #         ('{}%'.format(match_ng.group(1)),)
            #     )
            #     res_gene = curs.fetchone()
            #     if res_gene:
            #         gene_name = res_gene['hgnc']
            else:
                continue
        # do we have an intronic variant?
        if hgvs_nc and \
                gene_names:  # and \
                # not md_response:
            md_api_url = '{0}{1}'.format(request.host_url[:-1], url_for('api.api_variant_g_create'))
            for var_hgvs_nc in hgvs_nc:
                for gene_hgnc in gene_names:
                    data = {
                        'variant_ghgvs': urllib.parse.quote(var_hgvs_nc),
                        'gene_hgnc': gene_hgnc,
                        'caller': 'cli',
                        'api_key': api_key
                    }
                    try:
                        # print('{0}-{1}'.format(var_hgvs_nc, gene_hgnc))
                        md_response[var_hgvs_nc] = json.loads(http.request('POST', md_api_url, headers=md_utilities.api_agent, fields=data).data.decode('utf-8'))
                    except Exception as e:
                        md_response[var_hgvs_nc] = {'mobidetails_error': 'MobiDetails returned an unexpected error for your request {0}: {1}'.format(rs_id, var_hgvs_nc)}
                        md_utilities.send_error_email(
                            md_utilities.prepare_email_html(
                                'MobiDetails API error',
                                '<p>Error with MDAPI file writing for {0} ({1})<br /> - from {2} with args: {3}</p>'.format(
                                    rs_id,
                                    var_hgvs_nc,
                                    os.path.basename(__file__),
                                    e.args
                                )
                            ),
                            '[MobiDetails - MDAPI Error]'
                        )
        if md_response:
            if caller == 'cli':
                return jsonify(md_response)
            else:
                if len(md_response) == 1:
                    for var in md_response:
                        if 'mobidetails_error' in md_response[var]:
                            flash(md_response[var]['mobidetails_error'], 'w3-pale-red')
                            return redirect(url_for('md.index'))
                        return redirect(url_for('md.variant', variant_id=md_response[var]['mobidetails_id']))
                else:
                    
                    return render_template('md/variant_multiple.html', vars_rs=md_response)

        # md_utilities.api_end_according_to_caller(
        #     caller=caller,
        #     message='Using Mutalyzer, we did not find any suitable variant corresponding to your request {}'.format(rs_id),
        #     url=url_for('md.index')
        # )
        if caller == 'cli':
            return jsonify(mobidetails_error='Using Mutalyzer, we did not find any suitable variant corresponding to your request {}'.format(rs_id))
        else:
            flash('Using <a href="https://www.mutalyzer.nl/snp-converter?rs_id={0}", target="_blank">Mutalyzer</a>, we did not find any suitable variant corresponding to your request {0}'.format(rs_id), 'w3-pale-red')
            return redirect(url_for('md.index'))
    else:
        if caller == 'cli':
            return jsonify(mobidetails_error='Invalid rs id provided')
        else:
            flash('Invalid rs id provided', 'w3-pale-red')
            return redirect(url_for('md.index'))
Exemplo n.º 3
0
def test_check_caller(caller, result):
    assert md_utilities.check_caller(caller) == result
Exemplo n.º 4
0
def api_variant_g_create(variant_ghgvs=None, gene=None, caller=None, api_key=None):
    # get params
    if request.args.get('variant_ghgvs') and \
            request.args.get('gene_hgnc') and \
            request.args.get('caller') and \
            request.args.get('api_key'):
        variant_ghgvs = request.args.get('variant_ghgvs', type=str)
        gene = request.args.get('gene_hgnc', type=str)
        caller = request.args.get('caller', type=str)
        api_key = request.args.get('api_key', type=str)
    elif 'variant_ghgvs' in request.form and \
            'gene_hgnc' in request.form and \
            'caller' in request.form and \
            'api_key' in request.form:
        variant_ghgvs = request.form['variant_ghgvs']
        gene = request.form['gene_hgnc']
        caller = request.form['caller']
        api_key = request.form['api_key']
    else:
        if caller == 'cli':
            return jsonify(mobidetails_error='I cannot fetch the right parameters')
        else:
            flash('I cannot fetch the right parameters', 'w3-pale-red')
            return redirect(url_for('md.index'))
    if variant_ghgvs is not None and \
            gene is not None and \
            caller is not None and \
            api_key is not None:
        db = get_db()
        curs = db.cursor(cursor_factory=psycopg2.extras.DictCursor)
        # mobiuser_id = None
        res_check_api_key = md_utilities.check_api_key(db, api_key)
        if 'mobidetails_error' in res_check_api_key:
            if caller == 'cli':
                return jsonify(res_check_api_key)
            else:
                flash(res_check_api_key['mobidetails_error'], 'w3-pale-red')
                return redirect(url_for('md.index'))
        else:
            g.user = res_check_api_key['mobiuser']

        if md_utilities.check_caller(caller) == 'Invalid caller submitted':
            if caller == 'cli':
                return jsonify(mobidetails_error='Invalid caller submitted')
            else:
                flash('Invalid caller submitted to API.', 'w3-pale-red')
                return redirect(url_for('md.index'))

        # check gene exists
        curs.execute(
            "SELECT name, nm_version FROM gene WHERE name[1] = %s AND canonical = 't'",
            (gene,)
        )
        res_gene = curs.fetchone()
        if res_gene:
            variant_regexp = md_utilities.regexp['variant']
            match_object = re.search(rf'^([Nn][Cc]_0000\d{{2}}\.\d{{1,2}}):g\.({variant_regexp})', urllib.parse.unquote(variant_ghgvs))
            if match_object:
                ncbi_chr, g_var = match_object.group(1), match_object.group(2)
                # 1st check hg38
                curs.execute(
                    "SELECT * FROM chromosomes WHERE ncbi_name = %s",
                    (ncbi_chr,)
                )
                res = curs.fetchone()
                if res and \
                        res['genome_version'] == 'hg38':
                    genome_version, chrom = res['genome_version'], res['name']
                    # check if variant exists
                    curs.execute(
                        "SELECT feature_id FROM variant WHERE genome_version = %s AND g_name = %s AND chr = %s",
                        (genome_version, g_var, chrom)
                    )
                    res = curs.fetchone()
                    if res:
                        if caller == 'cli':                            
                            return jsonify(
                                mobidetails_id=res['feature_id'],
                                url='{0}{1}'.format(
                                    request.host_url[:-1],
                                    url_for('md.variant', variant_id=res['feature_id'])
                                )
                            )
                        else:
                            return redirect(url_for('md.variant', variant_id=res['feature_id']))
                    else:
                        # creation
                        vv_base_url = md_utilities.get_vv_api_url()
                        if not vv_base_url:
                            close_db()
                            if caller == 'cli':
                                return jsonify(mobidetails_error='Variant Validator looks down!.')
                            else:
                                flash('Variant Validator looks down!.', 'w3-pale-red')
                                return redirect(url_for('md.index'))
                        
                        vv_url = "{0}VariantValidator/variantvalidator/GRCh38/{1}/all?content-type=application/json".format(
                            vv_base_url, variant_ghgvs
                        )
                        # print(vv_url)
                        # vv_key_var = "{0}.{1}:c.{2}".format(acc_no, acc_version, new_variant)

                        try:
                            http = urllib3.PoolManager(cert_reqs='CERT_REQUIRED', ca_certs=certifi.where())
                            vv_data = json.loads(http.request('GET', vv_url).data.decode('utf-8'))
                        except Exception:
                            close_db()
                            if caller == 'cli':
                                return jsonify(mobidetails_error='Variant Validator did not return any value for the variant {}.'.format(urllib.parse.unquote(variant_ghgvs)))
                            else:
                                try:
                                    flash('There has been a issue with the annotation of the variant via VariantValidator. \
                                          The error is the following: {}'.format(vv_data['validation_warning_1']['validation_warnings']), 'w3-pale-red')
                                except Exception:
                                    flash('There has been a issue with the annotation of the variant via VariantValidator. \
                                          Sorry for the inconvenience. You may want to try directly in MobiDetails.', 'w3-pale-red')
                                return redirect(url_for('md.index'))
                        # look for gene acc #
                        # print(vv_data)
                        new_variant = None
                        vv_key_var = None
                        res_gene_non_can_list = []
                        # we still need a list of non canonical NM for the gene of interest
                        curs.execute(
                            "SELECT name, nm_version FROM gene WHERE name[1] = %s AND canonical = 'f'",
                            (gene,)
                        )
                        res_gene_non_can = curs.fetchall()
                        for transcript in res_gene_non_can:
                            res_gene_non_can_list.append('{0}.{1}'.format(transcript['name'][1], transcript['nm_version']))
                        for key in vv_data.keys():
                            variant_regexp = md_utilities.regexp['variant']
                            match_obj = re.search(rf'^([Nn][Mm]_\d+)\.(\d{{1,2}}):c\.({variant_regexp})', key)
                            if match_obj:
                                new_variant = match_obj.group(3)
                                # print("{0}-{1}-{2}-{3}".format(match_obj.group(1), res_gene['name'][1], match_obj.group(2), res_gene['nm_version']))
                                if match_obj.group(1) == res_gene['name'][1] and \
                                        str(match_obj.group(2)) == str(res_gene['nm_version']):
                                    # treat canonical as priority
                                    vv_key_var = "{0}.{1}:c.{2}".format(match_obj.group(1), match_obj.group(2), match_obj.group(3))
                                    break
                                elif not vv_key_var:
                                    # take into account non canonical isoforms
                                    # print('{0}.{1}'.format(match_obj.group(1), match_obj.group(2)))
                                    # print(res_gene_non_can_list)
                                    if '{0}.{1}'.format(match_obj.group(1), match_obj.group(2)) in res_gene_non_can_list:
                                        vv_key_var = "{0}.{1}:c.{2}".format(match_obj.group(1), match_obj.group(2), match_obj.group(3))
                        if vv_key_var:
                            # print(vv_key_var)
                            creation_dict = md_utilities.create_var_vv(
                                vv_key_var, res_gene['name'][0], res_gene['name'][1],
                                'c.{}'.format(new_variant), new_variant,
                                res_gene['nm_version'], vv_data, 'api', db, g
                            )
                            if caller == 'cli':
                                return jsonify(creation_dict)
                            else:
                                return redirect(url_for('md.variant', variant_id=creation_dict['mobidetails_id']))
                        else:
                            if caller == 'cli':
                                return jsonify(mobidetails_error='Could not create variant {} (possibly considered as intergenic).'.format(urllib.parse.unquote(variant_ghgvs)), variant_validator_output=vv_data)
                            else:
                                try:
                                    flash('There has been a issue with the annotation of the variant via VariantValidator. \
                                          The error is the following: {}'.format(vv_data['validation_warning_1']['validation_warnings']), 'w3-pale-red')
                                except Exception:
                                    flash('There has been a issue with the annotation of the variant via VariantValidator. \
                                          Sorry for the inconvenience. You may want to try directly in MobiDetails.', 'w3-pale-red')
                                return redirect(url_for('md.index'))

                else:
                    if caller == 'cli':
                        return jsonify(mobidetails_error='Unknown chromosome {} submitted or bad genome version (hg38 only)'.format(ncbi_chr))
                    else:
                        flash('The submitted chromosome or genome version looks corrupted (hg38 only).', 'w3-pale-red')
                        return redirect(url_for('md.index'))
            else:
                if caller == 'cli':
                    return jsonify(mobidetails_error='Malformed query {}'.format(urllib.parse.unquote(variant_ghgvs)))
                else:
                    flash('The query seems to be malformed: {}.'.format(urllib.parse.unquote(variant_ghgvs)), 'w3-pale-red')
                    return redirect(url_for('md.index'))
        else:
            if caller == 'cli':
                return jsonify(mobidetails_error='Unknown gene {} submitted'.format(gene))
            else:
                flash('Unknown gene {} submitted'.format(gene), 'w3-pale-red')
                return redirect(url_for('md.index'))
    else:
        if caller == 'cli':
            return jsonify(mobidetails_error='Invalid parameters')
        else:
            flash('The submitted parameters looks invalid!!!', 'w3-pale-red')
            return redirect(url_for('md.index'))
Exemplo n.º 5
0
def api_variant_create(variant_chgvs=None, caller=None, api_key=None):
    # get params
    caller = md_utilities.get_post_param(request, 'caller')
    variant_chgvs = md_utilities.get_post_param(request, 'variant_chgvs')
    api_key = md_utilities.get_post_param(request, 'api_key')
    if variant_chgvs and \
            caller and \
            api_key:
        db = get_db()
        curs = db.cursor(cursor_factory=psycopg2.extras.DictCursor)
        # mobiuser_id = None
        res_check_api_key = md_utilities.check_api_key(db, api_key)
        if 'mobidetails_error' in res_check_api_key:
            if caller == 'cli':
                return jsonify(res_check_api_key)
            else:
                flash(res_check_api_key['mobidetails_error'], 'w3-pale-red')
                return redirect(url_for('md.index'))
        else:
            g.user = res_check_api_key['mobiuser']
        if md_utilities.check_caller(caller) == 'Invalid caller submitted':
            if caller == 'cli':
                return jsonify(mobidetails_error='Invalid caller submitted')
            else:
                flash('Invalid caller submitted to API.', 'w3-pale-red')
                return redirect(url_for('md.index'))

        variant_regexp = md_utilities.regexp['variant']
        match_object = re.search(
            rf'^([Nn][Mm]_\d+)\.(\d{{1,2}}):c\.({variant_regexp})',
            urllib.parse.unquote(variant_chgvs))
        if match_object:
            # match_object = re.search(r'^([Nn][Mm]_\d+)\.(\d{1,2}):c\.(.+)', variant_chgvs)
            acc_no, submitted_nm_version, new_variant = match_object.group(
                1), match_object.group(2), match_object.group(3)
            # acc_no, acc_version, new_variant = match_object.group(1), match_object.group(2), match_object.group(3)
            new_variant = new_variant.replace(" ", "").replace("\t", "")
            # new_variant = new_variant.replace("\t", "")
            original_variant = new_variant
            curs.execute(
                "SELECT id FROM variant_feature WHERE c_name = %s AND gene_name[2] = %s",
                (new_variant, acc_no))
            res = curs.fetchone()
            if res is not None:
                if caller == 'cli':
                    return jsonify(mobidetails_id=res['id'],
                                   url='{0}{1}'.format(
                                       request.host_url[:-1],
                                       url_for('md.variant',
                                               variant_id=res['id'])))
                else:
                    return redirect(url_for('md.variant',
                                            variant_id=res['id']))

            else:
                # creation
                # get gene
                curs.execute(
                    "SELECT name[1] as gene, nm_version FROM gene WHERE name[2] = %s and variant_creation = 'ok'",
                    (acc_no, ))
                res_gene = curs.fetchone()
                if res_gene is None:
                    if caller == 'cli':
                        return jsonify(
                            mobidetails_error=
                            'The gene corresponding to {} is not yet available for variant annotation in MobiDetails'
                            .format(acc_no))
                    else:
                        flash(
                            'The gene corresponding to {} is not available for variant annotation in MobiDetails.'
                            .format(acc_no), 'w3-pale-red')
                        return redirect(url_for('md.index'))
                if int(res_gene['nm_version']) != int(submitted_nm_version):
                    if caller == 'cli':
                        return jsonify(
                            mobidetails_error=
                            'The RefSeq accession number submitted ({0}) for {1} does not match MobiDetail\'s ({2}).'
                            .format(submitted_nm_version, acc_no,
                                    res_gene['nm_version']))
                    else:
                        flash(
                            'The RefSeq accession number submitted ({0}) for {1} does not match MobiDetail\'s ({2}).'
                            .format(submitted_nm_version, acc_no,
                                    res_gene['nm_version']), 'w3-pale-red')
                        return redirect(url_for('md.index'))
                acc_version = res_gene['nm_version']
                vv_base_url = md_utilities.get_vv_api_url()
                if not vv_base_url:
                    close_db()
                    if caller == 'cli':
                        return jsonify(
                            mobidetails_error='Variant Validator looks down!.')
                    else:
                        flash('Variant Validator looks down!.', 'w3-pale-red')
                        return redirect(url_for('md.index'))
                vv_url = "{0}VariantValidator/variantvalidator/GRCh38/{1}.{2}:{3}/all?content-type=application/json".format(
                    vv_base_url, acc_no, acc_version, new_variant)
                vv_key_var = "{0}.{1}:c.{2}".format(acc_no, acc_version,
                                                    new_variant)

                try:
                    http = urllib3.PoolManager(cert_reqs='CERT_REQUIRED',
                                               ca_certs=certifi.where())
                    vv_data = json.loads(
                        http.request('GET', vv_url).data.decode('utf-8'))
                except Exception:
                    close_db()
                    if caller == 'cli':
                        return jsonify(
                            mobidetails_error=
                            'Variant Validator did not return any value for the variant {}.'
                            .format(new_variant))
                    else:
                        try:
                            flash(
                                'There has been a issue with the annotation of the variant via VariantValidator. \
                                  The error is the following: {}'.format(
                                    vv_data['validation_warning_1']
                                    ['validation_warnings']), 'w3-pale-red')
                        except Exception:
                            flash(
                                'There has been a issue with the annotation of the variant via VariantValidator. \
                                  Sorry for the inconvenience. You may want to try directly in MobiDetails.',
                                'w3-pale-red')
                        return redirect(url_for('md.index'))
                if re.search('[di][neu][psl]', new_variant):
                    # need to redefine vv_key_var for indels as the variant name returned by vv is likely to be different form the user's
                    for key in vv_data.keys():
                        if re.search('{0}.{1}'.format(acc_no, acc_version),
                                     key):
                            vv_key_var = key
                            # print(key)
                            var_obj = re.search(r':c\.(.+)$', key)
                            if var_obj is not None:
                                new_variant = var_obj.group(1)
                creation_dict = md_utilities.create_var_vv(
                    vv_key_var, res_gene['gene'], acc_no,
                    'c.{}'.format(new_variant), original_variant, acc_version,
                    vv_data, 'api', db, g)
                if 'mobidetails_error' in creation_dict:
                    if caller == 'cli':
                        return jsonify(creation_dict)
                    else:
                        flash(creation_dict['mobidetails_error'],
                              'w3-pale-red')
                        return redirect(url_for('md.index'))
                if caller == 'cli':
                    return jsonify(creation_dict)
                else:
                    return redirect(
                        url_for('md.variant',
                                variant_id=creation_dict['mobidetails_id']))
        else:
            if caller == 'cli':
                return jsonify(mobidetails_error='Malformed query {}'.format(
                    urllib.parse.unquote(variant_chgvs)))
            else:
                flash(
                    'The query seems to be malformed: {}.'.format(
                        urllib.parse.unquote(variant_chgvs)), 'w3-pale-red')
                return redirect(url_for('md.index'))
    else:
        if caller == 'cli':
            return jsonify(mobidetails_error='Invalid parameters')
        else:
            flash('The submitted parameters looks invalid!!!', 'w3-pale-red')
            return redirect(url_for('md.index'))