<commit_before>import json

import requests
from requests_toolbelt.multipart.encoder import MultipartEncoder

from installed_clients.AbstractHandleClient import \
    AbstractHandle as HandleService
from installed_clients.AssemblySequenceAPIServiceClient import AssemblySequenceAPI


class GenomeInterfaceV1:
    def __init__(self, workspace_client, services):
        self.ws = workspace_client
        self.handle_url = services['handle_service_url']
        self.shock_url = services['shock_service_url']
        self.sw_url = services['service_wizard_url']

    # Input params:
    # typedef structure {
    #     string ref;
    #     list <int> included_feature_position_index;
    #     list <string> ref_path_to_genome;
    # } GenomeSelectorV1;
    #
    # typedef structure {
    #     list <GenomeSelectorV1> genomes;

    #     list <string> included_fields;
    #     list <string> included_feature_fields;

    #     boolean ignore_errors;
    #     boolean no_data;
    #     boolean no_metadata;
    # } GetGenomeParamsV1;
    #
    def _check_bool(self, params, key, default):
        if key in params:
            if not isinstance(params[key], bool) and params[key] not in {0, 1}:
                raise ValueError(
                    '{} input field must be a boolean'.format(key))
            return params[key]
        return default

    def get_genome(self, ctx, params):

        object_specifications = self.build_object_specifications(params)

        getObjParams = {'objects': object_specifications}

        getObjParams['no_data'] = self._check_bool(params, 'no_data', 0)
        getObjParams['ignoreErrors'] = self._check_bool(params, 'ignoreErrors', 0)
        downgrade = self._check_bool(params, 'downgrade', 1)
        no_merge = self._check_bool(params, 'no_merge', 0)
        no_metadata = self._check_bool(params, 'no_metadata', 0)

        self.validate_proper_ws_type(object_specifications, getObjParams['ignoreErrors'], 'Genome')
        data = self.ws.get_objects2(getObjParams)['data']
        for i, genome in enumerate(data):
            if downgrade:
                data[i]['data'] = self.downgrade_genome(genome.get('data', {}), not no_merge)

        if no_metadata:
            data = [{'data': obj['data']} for obj in data]

        returnPackage = {'genomes': data}
        return returnPackage

    @staticmethod
    def downgrade_genome(genome_data, merge=True):
        """This reverts a genome to an older style for back compatibility"""
        print("Downgrading Genome for back compatibility")
        ont_present = genome_data.get('ontologies_present', {})
        ont_ref = genome_data.get('ontology_events',
                                  [{"ontology_ref": ""}])[0]['ontology_ref']

        for feat_array in (('features', 'gene'), ('mrnas', 'mRNA'),
                           ('cdss', 'CDS'), ('non_coding_features', 'gene')):
            feature_list = []
            for feat in genome_data.get(feat_array[0], []):
                if 'type' not in feat:
                    feat['type'] = feat_array[1]
                if feat.get("aliases") and isinstance(feat['aliases'][0], list):
                    feat['aliases'] = [x[1] for x in feat['aliases']]
                if feat.get('functions'):
                    feat['function'] = "; ".join(feat['functions'])
                for ont, terms in feat.get('ontology_terms', {}).items():
                    for _id, term in terms.items():
                        if "term_lineage" in feat['ontology_terms'][ont][_id]:
                            continue  # don't change a properly styled feature
                        feat['ontology_terms'][ont][_id] = {
                            "evidence": [],
                            "id": _id,
                            "ontology_ref": ont_ref,
                            "term_lineage": [],
                            "term_name": ont_present.get(ont, {}).get(_id, "")
                        }<commit_msg>some Prokka annotated genomes (new version) may not have the 'ontology_ref' key in 'ontology_events', change made to handle that scenario<commit_after>import json

import requests
from requests_toolbelt.multipart.encoder import MultipartEncoder

from installed_clients.AbstractHandleClient import \
    AbstractHandle as HandleService
from installed_clients.AssemblySequenceAPIServiceClient import AssemblySequenceAPI


class GenomeInterfaceV1:
    def __init__(self, workspace_client, services):
        self.ws = workspace_client
        self.handle_url = services['handle_service_url']
        self.shock_url = services['shock_service_url']
        self.sw_url = services['service_wizard_url']

    # Input params:
    # typedef structure {
    #     string ref;
    #     list <int> included_feature_position_index;
    #     list <string> ref_path_to_genome;
    # } GenomeSelectorV1;
    #
    # typedef structure {
    #     list <GenomeSelectorV1> genomes;

    #     list <string> included_fields;
    #     list <string> included_feature_fields;

    #     boolean ignore_errors;
    #     boolean no_data;
    #     boolean no_metadata;
    # } GetGenomeParamsV1;
    #
    def _check_bool(self, params, key, default):
        if key in params:
            if not isinstance(params[key], bool) and params[key] not in {0, 1}:
                raise ValueError(
                    '{} input field must be a boolean'.format(key))
            return params[key]
        return default

    def get_genome(self, ctx, params):

        object_specifications = self.build_object_specifications(params)

        getObjParams = {'objects': object_specifications}

        getObjParams['no_data'] = self._check_bool(params, 'no_data', 0)
        getObjParams['ignoreErrors'] = self._check_bool(params, 'ignoreErrors', 0)
        downgrade = self._check_bool(params, 'downgrade', 1)
        no_merge = self._check_bool(params, 'no_merge', 0)
        no_metadata = self._check_bool(params, 'no_metadata', 0)

        self.validate_proper_ws_type(object_specifications, getObjParams['ignoreErrors'], 'Genome')
        data = self.ws.get_objects2(getObjParams)['data']
        for i, genome in enumerate(data):
            if downgrade:
                data[i]['data'] = self.downgrade_genome(genome.get('data', {}), not no_merge)

        if no_metadata:
            data = [{'data': obj['data']} for obj in data]

        returnPackage = {'genomes': data}
        return returnPackage

    @staticmethod
    def downgrade_genome(genome_data, merge=True):
        """This reverts a genome to an older style for back compatibility"""
        print("Downgrading Genome for back compatibility")
        ont_present = genome_data.get('ontologies_present', {})
        ont_events = genome_data.get('ontology_events', [{"ontology_ref": ""}])
        ont_ref = ont_events[0].get('ontology_ref', "")

        for feat_array in (('features', 'gene'), ('mrnas', 'mRNA'),
                           ('cdss', 'CDS'), ('non_coding_features', 'gene')):
            feature_list = []
            for feat in genome_data.get(feat_array[0], []):
                if 'type' not in feat:
                    feat['type'] = feat_array[1]
                if feat.get("aliases") and isinstance(feat['aliases'][0], list):
                    feat['aliases'] = [x[1] for x in feat['aliases']]
                if feat.get('functions'):
                    feat['function'] = "; ".join(feat['functions'])
                for ont, terms in feat.get('ontology_terms', {}).items():
                    for _id, term in terms.items():
                        if "term_lineage" in feat['ontology_terms'][ont][_id]:
                            continue  # don't change a properly styled feature
                        feat['ontology_terms'][ont][_id] = {
                            "evidence": [],
                            "id": _id,
                            "ontology_ref": ont_ref,
                            "term_lineage": [],
                            "term_name": ont_present.get(ont, {}).get(_id, "")
                        }
{'fraction_non_alphanumeric': 0.1152324431256182, 'fraction_numerical': 0.0042037586547972305, 'mean_word_length': 2.270926000808734, 'pattern_counts': {'":': 12, '<': 13, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6636815', 'n_tokens_mistral': 2329, 'n_tokens_neox': 2209, 'n_words': 518}