diff --git a/oktoberfest/predict/dlomix.py b/oktoberfest/predict/dlomix.py index 75bbbfd..947f6b7 100644 --- a/oktoberfest/predict/dlomix.py +++ b/oktoberfest/predict/dlomix.py @@ -254,13 +254,12 @@ def __init__(self, model_type: str, model_path: Path, output_path: Path, batch_s _download_baseline_model(model_path) self.model = load_keras_model(str(model_path)) - def predict(self, data: Spectra, dataset_name: str, keep_dataset: bool = True, **kwargs) -> dict[str, np.ndarray]: + def predict(self, data: Spectra, dataset_name: str, keep_dataset: bool = True) -> dict[str, np.ndarray]: """Create predictions for dataset using Keras model. :param data: spectral library to predict features for :param dataset_name: Name of the dataset for storing processed files for DLomix :param keep_dataset: Whether to keep or discard the pre-processed dataset after inference - :param kwargs: In place to catch keyword arguments for other predictor implementations. :return: a dictionary containing predicted features (key: feature type) and a mask of the ion annotations of the predicted feature matrix (key: 'annotation') diff --git a/oktoberfest/predict/koina.py b/oktoberfest/predict/koina.py index 7c7f8fb..b179d4d 100644 --- a/oktoberfest/predict/koina.py +++ b/oktoberfest/predict/koina.py @@ -1,25 +1,18 @@ +from __future__ import annotations + import logging -import time -import warnings -from collections.abc import Generator, KeysView -from functools import partial -from typing import Optional, Union +from typing import TYPE_CHECKING -import numpy as np import pandas as pd -from tqdm.auto import tqdm -from tritonclient.grpc import ( - InferenceServerClient, - InferenceServerException, - InferInput, - InferRequestedOutput, - InferResult, -) +from koinapy.grpc import Koina as _KoinaGRPC from ..data.spectra import Spectra logger = logging.getLogger(__name__) +if TYPE_CHECKING: + import numpy as np + alternative_column_map = { "peptide_sequences": "MODIFIED_SEQUENCE", @@ -30,396 +23,10 @@ } -class Koina: - """A class for interacting with Koina models for inference.""" - - model_inputs: dict[str, str] - model_outputs: dict[str, np.ndarray] - batch_size: int - _response_dict: dict[int, Union[InferResult, InferenceServerException]] - - def __init__( - self, - model_name: str, - server_url: str = "koina.wilhelmlab.org:443", - ssl: bool = True, - targets: Optional[list[str]] = None, - disable_progress_bar: bool = False, - ): - """ - Initialize a KoinaModel instance with the specified parameters. - - This constructor initializes the KoinaModel instance, connecting it to the specified Inference Server. - It checks the availability of the server, the specified model, retrieves input and output information, - and determines the maximum batch size supported by the model's configuration. - Note: To use this class, ensure that the inference server is properly configured and running, - and that the specified model is available on the server. - - :param model_name: The name of the Koina model to be used for inference. - :param server_url: The URL of the inference server. Defaults to "koina.wilhelmlab.org:443". - :param ssl: Indicates whether to use SSL for communication with the server. Defaults to True. - :param targets: An optional list of targets to predict. If this is None, all model targets are - predicted and received. - :param disable_progress_bar: Whether to disable the progress bar showing the progress of predictions. - """ - self.model_inputs = {} - self.model_outputs = {} - self._response_dict = {} - - self.model_name = model_name - self.url = server_url - self.ssl = ssl - self.disable_progress_bar = disable_progress_bar - self.client = InferenceServerClient(url=server_url, ssl=ssl) - - self.type_convert = { - "FP32": np.dtype("float32"), - "BYTES": np.dtype("O"), - "INT16": np.dtype("int16"), - "INT32": np.dtype("int32"), - "INT64": np.dtype("int64"), - } - - self._is_server_ready() - self._is_model_ready() - - self.__get_inputs() - self.__get_outputs(targets) - self.__get_batchsize() - - @property - def response_dict(self): - """The dictionary containing raw InferenceResult/InferenceServerException objects (values) for a given request_id (key).""" - return self._response_dict - - def _is_server_ready(self): - """ - Check if the inference server is live and accessible. - - This method checks the availability of the inference server and raises an exception if it is not live or - accessible. It ensures that the server is properly running and can be used for inference with the Koina - model. Note: This method is primarily for internal use and typically called during model initialization. - - :raises ValueError: If the server responds with a not live status - :raises InferenceServerException: If an exception occured while querying the server for its status. - """ - try: - if not self.client.is_server_live(): - raise ValueError("Server not yet started.") - except InferenceServerException as e: - if self.url in ["koina.wilhelmlab.org:443", "koina.proteomicsdb.org:443"]: - if self.ssl: - raise InferenceServerException( - "The public koina network seems to be inaccessible at the moment. " - "Please notify ludwig.lautenbacher@tum.de." - ) from e - else: - raise InferenceServerException("To use the public koina network you need to set `ssl=True`.") from e - raise InferenceServerException("Unknown error occured.", e.status(), e.debug_details()) from e - - def _is_model_ready(self): - """ - Check if the specified model is available on the server. - - This method checks if the specified Koina model is available on the inference server. If the model is not - available, it raises an exception indicating that the model is not accessible at the provided server URL. - Note: This method is primarily for internal use and typically called during model initialization. - - :raises ValueError: If the specified model is not available at the server. - :raises InferenceServerException: If an exception occured while querying the server for available models. - """ - try: - if not self.client.is_model_ready(self.model_name): - raise ValueError(f"The model {self.model_name} is not available at {self.url}") - except InferenceServerException as e: - raise InferenceServerException("Unknown error occured.", e.status(), e.debug_details()) from e - - def __get_inputs(self): - """ - Retrieve the input names and datatypes for the model. - - This method fetches the names and data types of the input tensors for the Koina model and stores them in - the 'model_inputs' attribute. Note: This method is for internal use and is typically called during model - initialization. - - :raises InferenceServerException: If an exception occured while querying the server for model inputs. - """ - try: - self.model_inputs = {i.name: i.datatype for i in self.client.get_model_metadata(self.model_name).inputs} - except InferenceServerException as e: - raise InferenceServerException("Unknown error occured.", e.status(), e.debug_details()) from e - - def __get_outputs(self, targets: Optional[list] = None): - """ - Retrieve the output names and datatypes for the model. - - This method fetches the names and data types of the output tensors for the Koina model and stores them in - the 'model_outputs' attribute. If a list of target names is supplied, the tensors are filtered for those. - In case that the targets contain a name that is not a valid output of the requested model, a ValueError is - raised. Note: This method is for internal use and is typically called during model initialization. - - :param targets: An optional list of target names to filter the predictions for. If this is None, all targets - are added to list of output tensors to predict. - :raises ValueError: If a target supplied is not a valid output name of the requested model. - :raises InferenceServerException: If an exception occured while querying the server for model metadata. - """ - try: - model_outputs = self.client.get_model_metadata(self.model_name).outputs - model_targets = [out.name for out in model_outputs] - - if targets is None: - targets = model_targets - else: - for target in targets: - if target not in model_targets: - raise ValueError( - f"The supplied target {target} is not a valid output target of the model. " - f"Valid targets are {model_targets}." - ) - for i in model_outputs: - if i.name in targets: - self.model_outputs[i.name] = i.datatype - except InferenceServerException as e: - raise InferenceServerException("Unknown error occured.", e.status(), e.debug_details()) from e - - def __get_batchsize(self): - """ - Get the maximum batch size supported by the model's configuration. - - This method determines the maximum batch size supported by the Koina model's configuration and stores it - in the 'batchsize' attribute. Note: This method is for internal use and is typically called during model - initialization. - :raises InferenceServerException: If an exception occured while querying the server for the max batchsize. - """ - try: - self.batchsize = self.client.get_model_config(self.model_name).config.max_batch_size - except InferenceServerException as e: - raise InferenceServerException("Unknown error occured.", e.status(), e.debug_details()) from e - - @staticmethod - def __get_batch_outputs(names: KeysView[str]) -> list[InferRequestedOutput]: - """ - Create InferRequestedOutput objects for the given output names. - - This method generates InferRequestedOutput objects for the specified output names. InferRequestedOutput objects - are used to request specific outputs when performing inference. Note: This method is for internal use and is - typically called during inference. - - :param names: A list of output names for which InferRequestedOutput objects should be created. - - :return: A list of InferRequestedOutput objects. - """ - return [InferRequestedOutput(name) for name in names] - - def __get_batch_inputs(self, data: dict[str, np.ndarray]) -> list[InferInput]: - """ - Prepare a list of InferInput objects for the input data. - - This method prepares a list of InferInput objects for the provided input data. InferInput objects are used to - specify the input tensors and their data when performing inference. Note: This method is for internal use and - is typically called during inference. +class Koina(_KoinaGRPC): + """Extension of the Koina GRPC class in koinapy, to add required logic for Oktoberfest.""" - :param data: A dictionary containing input data for inference. Keys are input names, and values are numpy arrays. - - :return: A list of InferInput objects for the input data. - """ - batch_inputs = [] - for iname, idtype in self.model_inputs.items(): - batch_inputs.append(InferInput(iname, (len(data[next(iter(data))]), 1), idtype)) - batch_inputs[-1].set_data_from_numpy(data[iname].reshape(-1, 1).astype(self.type_convert[idtype])) - return batch_inputs - - def __extract_predictions(self, infer_result: InferResult) -> dict[str, np.ndarray]: - """ - Extract the predictions from an inference result. - - This method extracts the predictions from an inference result and organizes them in a dictionary with output - names as keys and corresponding arrays as values. Note: This method is for internal use and is typically called - during inference. - - :param infer_result: The result of an inference operation. - - :return: A dictionary containing the extracted predictions. Keys are output names, and values are numpy arrays. - """ - predictions = {} - for oname in self.model_outputs.keys(): - predictions[oname] = infer_result.as_numpy(oname) - return predictions - - def __predict_batch(self, data: dict[str, np.ndarray]) -> dict[str, np.ndarray]: - """ - Perform batch inference and return the predictions. - - This method performs batch inference on the provided input data using the configured Koina model and returns the - predictions. Note: This method is for internal use and is typically called during inference. - - :param data: A dictionary containing input data for batch inference. Keys are input names, and values are numpy arrays. - - :return: A dictionary containing the model's predictions. Keys are output names, and values are numpy arrays - representing the model's output. - """ - batch_outputs = self.__get_batch_outputs(self.model_outputs.keys()) - batch_inputs = self.__get_batch_inputs(data) - infer_result = self.client.infer(self.model_name, inputs=batch_inputs, outputs=batch_outputs) - - return self.__extract_predictions(infer_result) - - def __predict_sequential(self, data: dict[str, np.ndarray]) -> dict[str, np.ndarray]: - """ - Perform sequential inference and return the predictions. - - This method performs sequential inference on the provided input data using the configured Koina model. It processes - the input data batch by batch and returns the predictions. - Note: This method is for internal use and is typically called during inference. - - :param data: A dictionary containing input data for inference. Keys are input names, and values are numpy arrays. - - :return: A dictionary containing the model's predictions. Keys are output names, and values are numpy arrays representing - the model's output. - """ - predictions: dict[str, np.ndarray] = {} - for data_batch in tqdm(self.__slice_dict(data, self.batchsize), desc="Getting predictions"): - pred_batch = self.__predict_batch(data_batch) - if predictions: - predictions = self.__merge_array_dict(predictions, pred_batch) - else: - predictions = pred_batch # Only first iteration to initialize dict keys - return predictions - - @staticmethod - def __slice_dict(data: dict[str, np.ndarray], batchsize: int) -> Generator[dict[str, np.ndarray], None, None]: - """ - Slice the input data into batches of a specified batch size. - - This method takes the input data and divides it into smaller batches, each containing 'batchsize' elements. It yields - these batches one at a time, allowing for batched processing of input data. Note: This method is for internal use and - is typically called during batched inference. - - :param data: A dictionary containing input data for batch inference. Keys are input names, and values are numpy arrays. - :param batchsize: The desired batch size for slicing the data. - - :yield: A dictionary containing a batch of input data with keys and values corresponding to the input names and - batched arrays. - """ - len_inputs = list(data.values())[0].shape[0] - for i in range(0, len_inputs, batchsize): - dict_slice = {} - for k, v in data.items(): - dict_slice[k] = v[i : i + batchsize] - yield dict_slice - - @staticmethod - def __merge_array_dict(d1: dict[str, np.ndarray], d2: dict[str, np.ndarray]) -> dict[str, np.ndarray]: - """ - Merge two dictionaries of arrays. - - This method takes two dictionaries, 'd1' and 'd2', each containing arrays with identical keys. It merges the - arrays from both dictionaries, creating a new dictionary with the same keys and combined arrays. Note: This - method is for internal use and is typically called during batched inference. - - :param d1: A dictionary containing arrays. - :param d2: Another dictionary containing arrays with the same keys as d1. - - :raises NotImplementedError: If the keys in 'd1' and 'd2' do not match. - :return: A dictionary containing merged arrays with the same keys as d1 and d2. - """ - if d1.keys() != d2.keys(): - raise NotImplementedError(f"Keys in dictionary need to be equal {d1.keys(), d2.keys()}") - out = {} - for k in d1.keys(): - out[k] = np.concatenate([d1[k], d2[k]]) - return out - - @staticmethod - def __merge_list_dict_array(dict_list: list[dict[str, np.ndarray]]) -> dict[str, np.ndarray]: - """ - Merge a list of dictionaries of arrays. - - This method takes a list of dictionaries, where each dictionary contains arrays with identical keys. It merges - the arrays from all dictionaries in the list, creating a new dictionary with the same keys and combined arrays. - Note: This method is for internal use and is typically called during batched inference. - - :param dict_list: A list of dictionaries, each containing arrays with the same keys. - :raises NotImplementedError: If the keys of all dictionaries in the list do not match. - - :return: A dictionary containing merged arrays with the same keys as the dictionaries in the list. - """ - tmp = [x.keys() for x in dict_list] - if not np.all([tmp[0] == x for x in tmp]): - raise NotImplementedError(f"Keys of all dictionaries in the list need to be equal {tmp}") - out = {} - for k in tmp[0]: - out[k] = np.concatenate([x[k] for x in dict_list]) - return out - - def __async_callback( - self, - infer_results: dict[int, Union[dict[str, np.ndarray], InferenceServerException]], - request_id: int, - result: Optional[InferResult], - error: Optional[InferenceServerException], - ): - """ - Callback function for asynchronous inference. - - This method serves as a callback function for asynchronous inference. It is invoked when an asynchronous - inference task is completed. The result of the task is appended to the 'infer_results' list, and any - encountered error is checked and handled appropriately. Note: This method is for internal use and is typically - called during asynchronous inference. - - :param infer_results: A dictionary to which the results of asynchronous inference will be added. - :param request_id: The request id used as key in the infer_results dictionary - :param result: The result of an asynchronous inference operation. - :param error: An error, if any, encountered during asynchronous inference. - """ - if error: - infer_results[request_id] = error - else: - infer_results[request_id] = self.__extract_predictions(result) - - def __async_predict_batch( - self, - data: dict[str, np.ndarray], - infer_results: dict[int, Union[dict[str, np.ndarray], InferenceServerException]], - request_id: int, - timeout: int = 60000, - retries: int = 5, - ): - """ - Perform asynchronous batch inference on the given data using the Koina model. - - This method initiates asynchronous batch inference on the provided input data using the configured Koina model. - Results will be appended to the 'infer_results' list as they become available. The 'id' parameter is used to - identify and order the results. The method will return when the inference request is completed or when the - 'timeout' is reached. - - :param data: A dictionary containing input data for batch inference. Keys are input names, and values are numpy arrays. - :param infer_results: A dictionary to which the results of asynchronous inference will be added. - :param request_id: An identifier for the inference request, used to track the order of completion. - :param timeout: The maximum time (in seconds) to wait for the inference to complete. Defaults to 10 seconds. - :param retries: The maximum number of requests in case of failure - :yield: None, this is to separate async clien infer from checking the result - """ - batch_outputs = self.__get_batch_outputs(self.model_outputs.keys()) - batch_inputs = self.__get_batch_inputs(data) - - for i in range(retries): - if i > 0: # need to yield first, before doing sth, but only after first time - yield - if isinstance(infer_results.get(request_id), InferResult): - break - self.client.async_infer( - model_name=self.model_name, - request_id=str(request_id), - inputs=batch_inputs, - callback=partial(self.__async_callback, infer_results, request_id), - outputs=batch_outputs, - client_timeout=timeout, - ) - - def predict( - self, data: Union[dict[str, np.ndarray], pd.DataFrame, Spectra], _async: bool = True, debug=False, **kwargs - ) -> dict[str, np.ndarray]: + def predict(self, data: dict[str, np.ndarray] | pd.DataFrame | Spectra, **kwargs) -> dict[str, np.ndarray]: """ Perform inference on the given data using the Koina model. @@ -432,117 +39,26 @@ def predict( :param data: A dictionary or dataframe containing input data for inference. For the dictionary, keys are input names, and values are numpy arrays. In case of a dataframe, the input fields for the requested model must be present in the column names. - :param _async: If True, perform asynchronous inference; if False, perform sequential inference. Defaults to True. - :param debug: If True and using _async mode, store raw InferResult / InferServerException dictionary for later analysis. - :param kwargs: In place to catch keyword arguments for other predictor implementations. - + :param kwargs: Additional params that are forwarded to super().predict :return: A dictionary containing the model's predictions. Keys are output names, and values are numpy arrays representing the model's output. - :Example: - - .. code-block:: python - - >>> model = Koina("Prosit_2019_intensity") - >>> size=5 - >>> input_data = { - >>> "peptide_sequences": np.array(["PEPTIDEK" for _ in range(size)]), - >>> "precursor_charges": np.array([2 for _ in range(size)]), - >>> "collision_energies": np.array([20 for _ in range(size)]), - >>> "fragmentation_types": np.array(["HCD" for _ in range(size)]), - >>> "instrument_types": np.array(["QE" for _ in range(size)]) - >>> } - >>> predictions = model.predict(input_data) + Example:: + model = Koina("Prosit_2019_intensity") + input_data = { + "peptide_sequences": np.array(["PEPTIDEK" for _ in range(size)]), + "precursor_charges": np.array([2 for _ in range(size)]), + "collision_energies": np.array([20 for _ in range(size)]), + "fragmentation_types": np.array(["HCD" for _ in range(size)]), + "instrument_types": np.array(["QE" for _ in range(size)]) + } + predictions = model.predict(input_data) """ if isinstance(data, Spectra): data = data.obs if isinstance(data, pd.DataFrame): data = { - input_field: data[alternative_column_map[input_field]].to_numpy() + input_field: data[[alternative_column_map[input_field]]].to_numpy() for input_field in self.model_inputs.keys() } - if _async: - return self.__predict_async(data, debug=debug) - else: - return self.__predict_sequential(data) - - def __predict_async(self, data: dict[str, np.ndarray], debug=False) -> dict[str, np.ndarray]: - """ - Perform asynchronous inference on the given data using the Koina model. - - This method performs asynchronous inference on the provided input data using the configured Koina model. - Asynchronous inference allows for parallel processing of input data, potentially leading to faster results. - The method will return when all asynchronous inference tasks are complete. Note: Ensure that the model and server - are properly configured and that the input data matches the model's input requirements. - - :param data: A dictionary containing input data for inference. Keys are input names, and values are numpy arrays. - :param debug: If True, store raw InferResult / InferServerException dictionary for later analysis. - - :return: A dictionary containing the model's predictions. Keys are output names, and values are numpy arrays - representing the model's output. - """ - infer_results: dict[int, Union[dict[str, np.ndarray], InferenceServerException]] = {} - tasks = [] - for i, data_batch in enumerate(self.__slice_dict(data, self.batchsize)): - tasks.append(self.__async_predict_batch(data_batch, infer_results, request_id=i, retries=3)) - next(tasks[i]) - - n_tasks = i + 1 - with tqdm(total=n_tasks, desc="Getting predictions", disable=self.disable_progress_bar) as pbar: - unfinished_tasks = [i for i in range(n_tasks)] - while pbar.n < n_tasks: - time.sleep(0.5) - new_unfinished_tasks = [] - for j in unfinished_tasks: - result = infer_results.get(j) - if result is None: - new_unfinished_tasks.append(j) - elif isinstance(result, dict): - pbar.n += 1 - else: # unexpected result / exception -> try again - try: - del infer_results[j] - next(tasks[j]) - logger.warning(f"Unexpected response for batch {j}. Retrying...") - new_unfinished_tasks.append(j) - except StopIteration: - logger.error(f"Unexpected response for batch {j}. Max retries exceeded. Stopping.") - pbar.n += 1 - infer_results[j] = result - - unfinished_tasks = new_unfinished_tasks - pbar.refresh() - - return self.__handle_results(infer_results, debug) - - def __handle_results( - self, infer_results: dict[int, Union[dict[str, np.ndarray], InferenceServerException]], debug: bool - ) -> dict[str, np.ndarray]: - """ - Handles the results. - - :param infer_results: The dictionary containing the inferred results - :param debug: whether to store the infer_results in the response_dict attribute - - :raises InferenceServerException: If at least one batch of predictions could not be inferred. - - :return: A dictionary containing the model's predictions. Keys are output names, and values are numpy arrays - representing the model's output. - """ - if debug: - self._response_dict = infer_results - try: - # sort according to request id - infer_results_to_return = [infer_results[i] for i in range(len(infer_results))] - return self.__merge_list_dict_array(infer_results_to_return) - except AttributeError: - for res in infer_results.values(): - if isinstance(res, InferenceServerException): - warnings.warn(res.message(), stacklevel=1) - else: - raise InferenceServerException( - """ - At least one request failed. Check the error message above and try again. - To get a list of responses run koina.predict(..., debug = True), then call koina.response_dict - """ - ) from None + return super().predict(inputs=data, **kwargs) diff --git a/oktoberfest/predict/predictor.py b/oktoberfest/predict/predictor.py index 6656fcc..de6394f 100644 --- a/oktoberfest/predict/predictor.py +++ b/oktoberfest/predict/predictor.py @@ -1,9 +1,10 @@ from __future__ import annotations import importlib +import inspect import logging from pathlib import Path -from typing import TYPE_CHECKING, Optional, Union +from typing import TYPE_CHECKING, Any, Optional, Union import numpy as np import pandas as pd @@ -44,7 +45,6 @@ def from_koina( server_url: str = "koina.wilhelmlab.org:443", ssl: bool = True, targets: Optional[list[str]] = None, - disable_progress_bar: bool = False, ) -> Predictor: """Create Koina predictor.""" return Predictor( @@ -53,7 +53,6 @@ def from_koina( server_url=server_url, ssl=ssl, targets=targets, - disable_progress_bar=disable_progress_bar, ), model_name=model_name, ) @@ -103,6 +102,17 @@ def from_config(cls, config: Config, model_type: str, **kwargs) -> Predictor: model_type, model_path, output_folder, config.dlomix_inference_batch_size, download ) + def _filter_kwargs(self, **kwargs) -> dict[str, Any]: + """ + Get only arguments accepted by predictor implementation's predict() method from arbitrary set of kwargs. + + :param kwargs: Set of keyword arguments + + :return: Filtered set of keyword arguments + """ + signature = inspect.signature(self._predictor.predict) + return {key: value for key, value in kwargs.items() if key in signature.parameters} + def predict_intensities(self, data: Spectra, chunk_idx: Optional[list[pd.Index]] = None, **kwargs): """ Generate intensity predictions and add them to the provided data object. @@ -224,7 +234,7 @@ def predict_at_once(self, data: Spectra, **kwargs) -> dict[str, np.ndarray]: >>> predictions = intensity_predictor.predict_at_once(data=library) >>> print(predictions) """ - return self._predictor.predict(data, **kwargs) + return self._predictor.predict(data, **self._filter_kwargs(**kwargs)) def predict_in_chunks(self, data: Spectra, chunk_idx: list[pd.Index], **kwargs) -> dict[str, list[np.ndarray]]: """ @@ -269,7 +279,7 @@ def predict_in_chunks(self, data: Spectra, chunk_idx: list[pd.Index], **kwargs) """ results = [] for idx in chunk_idx: - results.append(self._predictor.predict(data[idx], **kwargs)) + results.append(self._predictor.predict(data[idx], **self._filter_kwargs(**kwargs))) ret_val = {key: [item[key] for item in results] for key in results[0].keys()} return ret_val diff --git a/oktoberfest/runner.py b/oktoberfest/runner.py index f171ce3..9bb4352 100644 --- a/oktoberfest/runner.py +++ b/oktoberfest/runner.py @@ -391,7 +391,7 @@ def generate_spectral_lib(config_path: Union[str, Path]): spec_library = _speclib_from_digestion(config) predictors = { - model_key: pr.Predictor.from_config(config, model_type=model_key, disable_progress_bar=True) + model_key: pr.Predictor.from_config(config, model_type=model_key) for model_key in config.models } diff --git a/poetry.lock b/poetry.lock index cc8638e..fd62da3 100644 --- a/poetry.lock +++ b/poetry.lock @@ -2426,6 +2426,22 @@ files = [ {file = "kiwisolver-1.4.7.tar.gz", hash = "sha256:9893ff81bd7107f7b685d3017cc6583daadb4fc26e4a888350df530e41980a60"}, ] +[[package]] +name = "koinapy" +version = "0.0.7" +description = "Python client to communicate with Koina." +optional = false +python-versions = "<3.13,>=3.8" +files = [ + {file = "koinapy-0.0.7-py3-none-any.whl", hash = "sha256:2c76de08f70ada30f28cbdbe51ac04c2a8853b015e356c7d530559194db90632"}, + {file = "koinapy-0.0.7.tar.gz", hash = "sha256:62796fb2efbd933012b10fec8a665e3a61a1b1a3dcb6afda427da54f0aac8ee8"}, +] + +[package.dependencies] +pandas = "*" +tqdm = "*" +tritonclient = {version = ">=2.23,<2.41 || >2.41", extras = ["grpc"], markers = "python_version >= \"3.8\" and python_version < \"3.11\""} + [[package]] name = "libclang" version = "18.1.1" @@ -6245,14 +6261,14 @@ threadpoolctl = ">=3.1.0,<4.0.0" [[package]] name = "tritonclient" -version = "2.47.0" +version = "2.49.0" description = "Python client library and utilities for communicating with Triton Inference Server" optional = false python-versions = "*" files = [ - {file = "tritonclient-2.47.0-py3-none-any.whl", hash = "sha256:a731aebceb69e9d0508fef1dd4e703730b70b4dd5ab283d9d836823897a0561b"}, - {file = "tritonclient-2.47.0-py3-none-manylinux1_x86_64.whl", hash = "sha256:754ab373a45306be0c45afbcde06838179d04561694f6d15e138530153aee581"}, - {file = "tritonclient-2.47.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:5500ef5637ac3ed7ceeac3740ca28fc6acb94473cc49b261a86dc4cb55267179"}, + {file = "tritonclient-2.49.0-py3-none-any.whl", hash = "sha256:8715c8f82061e9e2d85242c903e72e68c070c6845c0334fa88fc9f44a1904e77"}, + {file = "tritonclient-2.49.0-py3-none-manylinux1_x86_64.whl", hash = "sha256:e7b40ba11056c93da434bc8a8b302c0a337489923a0a747c5d313314baa26db3"}, + {file = "tritonclient-2.49.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:cc2350bbb6c2df4fab958435a29b7bb437693732bca72a4d658b0400d9f524e6"}, ] [package.dependencies] @@ -7073,4 +7089,4 @@ dlomix = ["dlomix", "tensorflow"] [metadata] lock-version = "2.0" python-versions = ">=3.9.0,<3.11.0" -content-hash = "027e0d7685638d75f1fa6a1b4c9f522b59c7be1999ef98150882b34cb7b59d60" +content-hash = "2648532d4651f82963ee5936884e52e09f6a4e63ff480dd03038a3d7c52a9b38" diff --git a/pyproject.toml b/pyproject.toml index a84ebda..bc65174 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -32,11 +32,11 @@ seaborn = ">=0.12.2,<0.14.0" spectrum_fundamentals = ">=0.7.3,<0.8.0" spectrum-io = ">=0.6.2,<0.7.0" picked_group_fdr = ">=0.7.1" -tritonclient = {extras = ["grpc"], version = ">=2.47.0,<2.48"} dlomix = {extras = ["rltl-report", "wandb"], git = "git@github.com:wilhelm-lab/dlomix.git", branch = "feature/bmpc", optional = true} tensorflow = {version = ">=2.13,<2.16", extras = ["and-cuda"], optional = true} wandb = {version = "^0.17.5", optional = true} +koinapy = "^0.0.7" [tool.poetry.dev-dependencies] pytest = ">=6.2.3" diff --git a/requirements.txt b/requirements.txt index 786e03d..1a1b3d1 100644 --- a/requirements.txt +++ b/requirements.txt @@ -34,7 +34,7 @@ flake8-docstrings==1.7.0 ; python_full_version >= "3.9.0" and python_full_versio flake8-rst-docstrings==0.3.0 ; python_full_version >= "3.9.0" and python_full_version < "3.11.0" flake8==7.1.1 ; python_full_version >= "3.9.0" and python_full_version < "3.11.0" fonttools==4.53.1 ; python_version >= "3.9" and python_full_version < "3.11.0" -grpcio==1.66.1 ; python_full_version >= "3.9.0" and python_full_version < "3.11.0" +grpcio==1.66.1 ; python_full_version >= "3.9.0" and python_version < "3.11" h11==0.14.0 ; python_version >= "3.9" and python_full_version < "3.11.0" h5py==3.11.0 ; python_version >= "3.9" and python_full_version < "3.11.0" identify==2.6.0 ; python_version >= "3.9" and python_full_version < "3.11.0" @@ -47,6 +47,7 @@ jinja2==3.1.4 ; python_version >= "3.9" and python_full_version < "3.11.0" job-pool==0.2.6 ; python_full_version >= "3.9.0" and python_full_version < "3.11.0" joblib==1.4.2 ; python_version >= "3.9" and python_full_version < "3.11.0" kiwisolver==1.4.7 ; python_version >= "3.9" and python_full_version < "3.11.0" +koinapy==0.0.7 ; python_full_version >= "3.9.0" and python_full_version < "3.11.0" llvmlite==0.42.0 ; python_version >= "3.9" and python_full_version < "3.11.0" lxml==5.3.0 ; python_full_version >= "3.9.0" and python_full_version < "3.11.0" markdown-it-py==3.0.0 ; python_full_version >= "3.9.0" and python_full_version < "3.11.0" @@ -65,7 +66,7 @@ nodeenv==1.9.1 ; python_version >= "3.9" and python_full_version < "3.11.0" numba==0.59.1 ; python_version >= "3.9" and python_full_version < "3.11.0" numpy==1.24.4 ; python_version >= "3.9" and python_version < "3.11" openpyxl==3.1.5 ; python_full_version >= "3.9.0" and python_full_version < "3.11.0" -packaging==24.1 ; python_version >= "3.9" and python_full_version < "3.11.0" +packaging==24.1 ; python_version >= "3.9" and python_version < "3.11" pandas==2.2.2 ; python_version >= "3.9" and python_full_version < "3.11.0" pathspec==0.12.1 ; python_full_version >= "3.9.0" and python_full_version < "3.11.0" pbr==6.1.0 ; python_full_version >= "3.9.0" and python_full_version < "3.11.0" @@ -76,7 +77,7 @@ platformdirs==4.3.2 ; python_version >= "3.9" and python_full_version < "3.11.0" pluggy==1.5.0 ; python_full_version >= "3.9.0" and python_full_version < "3.11.0" pre-commit-hooks==4.6.0 ; python_full_version >= "3.9.0" and python_full_version < "3.11.0" pre-commit==3.8.0 ; python_version >= "3.9" and python_full_version < "3.11.0" -protobuf==4.25.4 ; python_full_version >= "3.9.0" and python_full_version < "3.11.0" +protobuf==4.25.4 ; python_full_version >= "3.9.0" and python_version < "3.11" psutil==6.0.0 ; python_full_version >= "3.9.0" and python_full_version < "3.11.0" pyarrow==17.0.0 ; python_full_version >= "3.9.0" and python_full_version < "3.11.0" pycodestyle==2.12.1 ; python_full_version >= "3.9.0" and python_full_version < "3.11.0" @@ -91,7 +92,7 @@ pyparsing==3.1.4 ; python_version >= "3.9" and python_full_version < "3.11.0" pyteomics==4.7.3 ; python_full_version >= "3.9.0" and python_full_version < "3.11.0" pytest==8.3.3 ; python_full_version >= "3.9.0" and python_full_version < "3.11.0" python-dateutil==2.9.0.post0 ; python_version >= "3.9" and python_full_version < "3.11.0" -python-rapidjson==1.20 ; python_full_version >= "3.9.0" and python_full_version < "3.11.0" +python-rapidjson==1.20 ; python_full_version >= "3.9.0" and python_version < "3.11" pytz==2024.2 ; python_version >= "3.9" and python_full_version < "3.11.0" pyupgrade==3.17.0 ; python_version >= "3.9" and python_full_version < "3.11.0" pyyaml==6.0.2 ; python_version >= "3.9" and python_full_version < "3.11.0" @@ -135,14 +136,14 @@ toml==0.10.2 ; python_full_version >= "3.9.0" and python_full_version < "3.11.0" tomli==2.0.1 ; python_version >= "3.9" and python_version < "3.11" tqdm==4.66.5 ; python_full_version >= "3.9.0" and python_full_version < "3.11.0" triqler==0.7.3 ; python_full_version >= "3.9.0" and python_full_version < "3.11.0" -tritonclient[grpc]==2.47.0 ; python_full_version >= "3.9.0" and python_full_version < "3.11.0" +tritonclient[grpc]==2.49.0 ; python_full_version >= "3.9.0" and python_version < "3.11" typeguard==4.3.0 ; python_full_version >= "3.9.0" and python_full_version < "3.11.0" typer==0.12.5 ; python_full_version >= "3.9.0" and python_full_version < "3.11.0" types-attrs==19.1.0 ; python_full_version >= "3.9.0" and python_full_version < "3.11.0" types-requests==2.32.0.20240907 ; python_full_version >= "3.9.0" and python_full_version < "3.11.0" typing-extensions==4.12.2 ; python_version >= "3.9" and python_version < "3.11" tzdata==2024.1 ; python_version >= "3.9" and python_full_version < "3.11.0" -urllib3==2.2.3 ; python_version >= "3.9" and python_full_version < "3.11.0" +urllib3==2.2.3 ; python_version >= "3.9" and python_version < "3.11" uvicorn==0.30.6 ; python_version >= "3.9" and python_full_version < "3.11.0" virtualenv==20.26.4 ; python_version >= "3.9" and python_full_version < "3.11.0" watchfiles==0.24.0 ; python_version >= "3.9" and python_full_version < "3.11.0" diff --git a/tests/unit_tests/test_predict.py b/tests/unit_tests/test_predict.py index 4e50360..4a84db3 100644 --- a/tests/unit_tests/test_predict.py +++ b/tests/unit_tests/test_predict.py @@ -30,7 +30,7 @@ def test_prosit_tmt(self): model_name="Prosit_2020_intensity_TMT", server_url="koina.wilhelmlab.org:443", ssl=True, - targets=["intensities", "annotation"], + # targets=["intensities", "annotation"], ) intensity_predictor.predict_intensities(data=library)