<commit_before># -*- coding: utf-8 -*-

import json
import logging
from collections import Iterable

import numpy as np

from pybel.struct import union
from pybel.utils import list2tuple
from .pipeline import Pipeline
from .selection import get_subgraph
from .selection.induce_subgraph import (
    NONNODE_SEED_TYPES, SEED_TYPE_ANNOTATION, SEED_TYPE_INDUCTION, SEED_TYPE_NEIGHBORS, SEED_TYPE_SAMPLE,
)

log = logging.getLogger(__name__)

SEED_TYPE_KEY = 'type'
SEED_DATA_KEY = 'data'


class Query:
    """Wraps a query over the network store"""

    def __init__(self, network_ids=None, seeding=None, pipeline=None):
        """
        :param iter[int] network_ids: Database network identifiers identifiers
        :param Optional[list[dict]] seeding:
        :param Optional[Pipeline] pipeline: Instance of a pipeline
        """
        if not network_ids:
            self.network_ids = []
        else:
            if not isinstance(network_ids, Iterable):
                raise TypeError('network identifiers is not list: {}'.format(network_ids))

            network_ids = list(network_ids)

            if any(not isinstance(entry, int) for entry in network_ids):
                raise TypeError('network identifiers entry is not int: {}'.format(network_ids))

            self.network_ids = network_ids

        self.seeding = seeding or []
        self.pipeline = pipeline or Pipeline()

    def append_network(self, network_id):
        """Adds a network to this query

        :param int network_id: The database identifier of the network
        """
        self.network_ids.append(network_id)

    def append_seed(self, seed_type, data):
        """Add a seeding

        :param str seed_type:
        :param data:
        """
        self.seeding.append({
            SEED_TYPE_KEY: seed_type,
            SEED_DATA_KEY: data
        })

    def append_seeding_induction(self, data):
        """Adds a seed induction method

        :param list[tuple] data: A list of PyBEL node tuples
        """
        self.append_seed(SEED_TYPE_INDUCTION, data)

    def append_seeding_neighbors(self, data):
        """Adds a seed by neighbors

        :param list[tuple] data:
        """
        self.append_seed(SEED_TYPE_NEIGHBORS, data)

    def append_seeding_annotation(self, annotation, values):
        """Adds a seed induction method for single annotation's values

        :param str annotation: The annotation to filter by
        :param set[str] values: The values of the annotation to keep
        """
        self.append_seed(SEED_TYPE_ANNOTATION, {
            'annotations': {
                annotation: values
            }
        })

    def append_seeding_sample(self):
        """Adds seed induction methods.

        Kwargs can have ``number_edges`` or ``number_seed_nodes``.
        """
        self.append_seed(SEED_TYPE_SAMPLE, {
            'seed': np.random.randint(0, np.iinfo('i').max)
        })

    def append_pipeline(self, name, *args, **kwargs):
        """Adds an entry to the pipeline

        :param str name: The name of the function
        :return: This pipeline for fluid query building<commit_msg>Update documentation<commit_after># -*- coding: utf-8 -*-

import json
import logging
from collections import Iterable

import numpy as np

from pybel.struct import union
from pybel.utils import list2tuple
from .pipeline import Pipeline
from .selection import get_subgraph
from .selection.induce_subgraph import (
    NONNODE_SEED_TYPES, SEED_TYPE_ANNOTATION, SEED_TYPE_INDUCTION, SEED_TYPE_NEIGHBORS, SEED_TYPE_SAMPLE,
)

log = logging.getLogger(__name__)

SEED_TYPE_KEY = 'type'
SEED_DATA_KEY = 'data'


class Query:
    """Wraps a query over the network store"""

    def __init__(self, network_ids=None, seeding=None, pipeline=None):
        """
        :param iter[int] network_ids: Database network identifiers identifiers
        :param Optional[list[dict]] seeding:
        :param Optional[Pipeline] pipeline: Instance of a pipeline
        """
        if not network_ids:
            self.network_ids = []
        else:
            if not isinstance(network_ids, Iterable):
                raise TypeError('network identifiers is not list: {}'.format(network_ids))

            network_ids = list(network_ids)

            if any(not isinstance(entry, int) for entry in network_ids):
                raise TypeError('network identifiers entry is not int: {}'.format(network_ids))

            self.network_ids = network_ids

        self.seeding = seeding or []
        self.pipeline = pipeline or Pipeline()

    def append_network(self, network_id):
        """Adds a network to this query

        :param int network_id: The database identifier of the network
        """
        self.network_ids.append(network_id)

    def append_seed(self, seed_type, data):
        """Add a seeding

        :param str seed_type:
        :param data:
        """
        self.seeding.append({
            SEED_TYPE_KEY: seed_type,
            SEED_DATA_KEY: data
        })

    def append_seeding_induction(self, nodes):
        """Adds a seed induction method

        :param list[tuple] nodes: A list of PyBEL node tuples
        """
        self.append_seed(SEED_TYPE_INDUCTION, nodes)

    def append_seeding_neighbors(self, nodes):
        """Adds a seed by neighbors

        :param list[tuple] nodes: A list of PyBEL node tuples
        """
        self.append_seed(SEED_TYPE_NEIGHBORS, nodes)

    def append_seeding_annotation(self, annotation, values):
        """Adds a seed induction method for single annotation's values

        :param str annotation: The annotation to filter by
        :param set[str] values: The values of the annotation to keep
        """
        self.append_seed(SEED_TYPE_ANNOTATION, {
            'annotations': {
                annotation: values
            }
        })

    def append_seeding_sample(self, **kwargs):
        """Adds seed induction methods.

        Kwargs can have ``number_edges`` or ``number_seed_nodes``.
        """
        data = {
            'seed': np.random.randint(0, np.iinfo('i').max)
        }
        data.update(kwargs)

        self.append_seed(SEED_TYPE_SAMPLE, data)

    def append_pipeline(self, name, *args, **kwargs):
        """Adds an entry to the pipeline

        :param str name: The name of the function
        :return: This pipeline for fluid query building
{'fraction_non_alphanumeric': 0.08896185115697311, 'fraction_numerical': 0.0009380863039399625, 'mean_word_length': 2.547975596228508, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3710099', 'n_tokens_mistral': 1869, 'n_tokens_neox': 1801, 'n_words': 538}