# coding: utf-8

# (C) Copyright IBM Corp. 2019, 2020.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# IBM OpenAPI SDK Code Generator Version: 99-SNAPSHOT-a45d89ef-20201209-192237
"""
IBM Watson&trade; Natural Language Classifier uses machine learning algorithms to return
the top matching predefined classes for short text input. You create and train a
classifier to connect predefined classes to example texts so that the service can apply
those classes to new inputs.
"""

from datetime import datetime
from enum import Enum
from typing import BinaryIO, Dict, List
import json

from ibm_cloud_sdk_core import BaseService, DetailedResponse
from ibm_cloud_sdk_core.authenticators.authenticator import Authenticator
from ibm_cloud_sdk_core.get_authenticator import get_authenticator_from_environment
from ibm_cloud_sdk_core.utils import convert_model, datetime_to_string, string_to_datetime

from .common import get_sdk_headers

##############################################################################
# Service
##############################################################################


class NaturalLanguageClassifierV1(BaseService):
    """The Natural Language Classifier V1 service."""

    DEFAULT_SERVICE_URL = 'https://api.us-south.natural-language-classifier.watson.cloud.ibm.com'
    DEFAULT_SERVICE_NAME = 'natural_language_classifier'

    def __init__(
        self,
        authenticator: Authenticator = None,
        service_name: str = DEFAULT_SERVICE_NAME,
    ) -> None:
        """
        Construct a new client for the Natural Language Classifier service.

        :param Authenticator authenticator: The authenticator specifies the authentication mechanism.
               Get up to date information from https://github.com/IBM/python-sdk-core/blob/master/README.md
               about initializing the authenticator of your choice.
        """  
        print(
            """
            On 9 August 2021, IBM announced the deprecation of the Natural Language Classifier service.
            The service will no longer be available from 8 August 2022. As of 9 September 2021, you will not be able to create new instances. 
            Existing instances will be supported until 8 August 2022. Any instance that still exists on that date will be deleted.
            For more information, see https://cloud.ibm.com/docs/natural-language-classifier?topic=natural-language-classifier-migrating
            """
        ) 
        if not authenticator:
            authenticator = get_authenticator_from_environment(service_name)
        BaseService.__init__(self,
                             service_url=self.DEFAULT_SERVICE_URL,
                             authenticator=authenticator)
        self.configure_service(service_name)

    #########################
    # Classify text
    #########################

    def classify(self, classifier_id: str, text: str,
                 **kwargs) -> DetailedResponse:
        """
        Classify a phrase.

        Returns label information for the input. The status must be `Available` before you
        can use the classifier to classify text.

        :param str classifier_id: Classifier ID to use.
        :param str text: The submitted phrase. The maximum length is 2048
               characters.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `Classification` object
        """

        if classifier_id is None:
            raise ValueError('classifier_id must be provided')
        if text is None:
            raise ValueError('text must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='classify')
        headers.update(sdk_headers)

        data = {'text': text}
        data = {k: v for (k, v) in data.items() if v is not None}
        data = json.dumps(data)
        headers['content-type'] = 'application/json'

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        path_param_keys = ['classifier_id']
        path_param_values = self.encode_path_vars(classifier_id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/v1/classifiers/{classifier_id}/classify'.format(
            **path_param_dict)
        request = self.prepare_request(method='POST',
                                       url=url,
                                       headers=headers,
                                       data=data)

        response = self.send(request)
        return response

    def classify_collection(self, classifier_id: str,
                            collection: List['ClassifyInput'],
                            **kwargs) -> DetailedResponse:
        """
        Classify multiple phrases.

        Returns label information for multiple phrases. The status must be `Available`
        before you can use the classifier to classify text.
        Note that classifying Japanese texts is a beta feature.

        :param str classifier_id: Classifier ID to use.
        :param List[ClassifyInput] collection: The submitted phrases.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `ClassificationCollection` object
        """

        if classifier_id is None:
            raise ValueError('classifier_id must be provided')
        if collection is None:
            raise ValueError('collection must be provided')
        collection = [convert_model(x) for x in collection]
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='classify_collection')
        headers.update(sdk_headers)

        data = {'collection': collection}
        data = {k: v for (k, v) in data.items() if v is not None}
        data = json.dumps(data)
        headers['content-type'] = 'application/json'

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        path_param_keys = ['classifier_id']
        path_param_values = self.encode_path_vars(classifier_id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/v1/classifiers/{classifier_id}/classify_collection'.format(
            **path_param_dict)
        request = self.prepare_request(method='POST',
                                       url=url,
                                       headers=headers,
                                       data=data)

        response = self.send(request)
        return response

    #########################
    # Manage classifiers
    #########################

    def create_classifier(self, training_metadata: BinaryIO,
                          training_data: BinaryIO,
                          **kwargs) -> DetailedResponse:
        """
        Create classifier.

        Sends data to create and train a classifier and returns information about the new
        classifier.

        :param BinaryIO training_metadata: Metadata in JSON format. The metadata
               identifies the language of the data, and an optional name to identify the
               classifier. Specify the language with the 2-letter primary language code as
               assigned in ISO standard 639.
               Supported languages are English (`en`), Arabic (`ar`), French (`fr`),
               German, (`de`), Italian (`it`), Japanese (`ja`), Korean (`ko`), Brazilian
               Portuguese (`pt`), and Spanish (`es`).
        :param BinaryIO training_data: Training data in CSV format. Each text value
               must have at least one class. The data can include up to 3,000 classes and
               20,000 records. For details, see [Data
               preparation](https://cloud.ibm.com/docs/natural-language-classifier?topic=natural-language-classifier-using-your-data).
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `Classifier` object
        """

        if training_metadata is None:
            raise ValueError('training_metadata must be provided')
        if training_data is None:
            raise ValueError('training_data must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='create_classifier')
        headers.update(sdk_headers)

        form_data = []
        form_data.append(('training_metadata', (None, training_metadata,
                                                'application/json')))
        form_data.append(('training_data', (None, training_data, 'text/csv')))

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/v1/classifiers'
        request = self.prepare_request(method='POST',
                                       url=url,
                                       headers=headers,
                                       files=form_data)

        response = self.send(request)
        return response

    def list_classifiers(self, **kwargs) -> DetailedResponse:
        """
        List classifiers.

        Returns an empty array if no classifiers are available.

        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `ClassifierList` object
        """

        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='list_classifiers')
        headers.update(sdk_headers)

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        url = '/v1/classifiers'
        request = self.prepare_request(method='GET', url=url, headers=headers)

        response = self.send(request)
        return response

    def get_classifier(self, classifier_id: str, **kwargs) -> DetailedResponse:
        """
        Get information about a classifier.

        Returns status and other information about a classifier.

        :param str classifier_id: Classifier ID to query.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `Classifier` object
        """

        if classifier_id is None:
            raise ValueError('classifier_id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='get_classifier')
        headers.update(sdk_headers)

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        path_param_keys = ['classifier_id']
        path_param_values = self.encode_path_vars(classifier_id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/v1/classifiers/{classifier_id}'.format(**path_param_dict)
        request = self.prepare_request(method='GET', url=url, headers=headers)

        response = self.send(request)
        return response

    def delete_classifier(self, classifier_id: str,
                          **kwargs) -> DetailedResponse:
        """
        Delete classifier.

        :param str classifier_id: Classifier ID to delete.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse
        """

        if classifier_id is None:
            raise ValueError('classifier_id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V1',
                                      operation_id='delete_classifier')
        headers.update(sdk_headers)

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        headers['Accept'] = 'application/json'

        path_param_keys = ['classifier_id']
        path_param_values = self.encode_path_vars(classifier_id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/v1/classifiers/{classifier_id}'.format(**path_param_dict)
        request = self.prepare_request(method='DELETE',
                                       url=url,
                                       headers=headers)

        response = self.send(request)
        return response


##############################################################################
# Models
##############################################################################


class Classification():
    """
    Response from the classifier for a phrase.

    :attr str classifier_id: (optional) Unique identifier for this classifier.
    :attr str url: (optional) Link to the classifier.
    :attr str text: (optional) The submitted phrase.
    :attr str top_class: (optional) The class with the highest confidence.
    :attr List[ClassifiedClass] classes: (optional) An array of up to ten
          class-confidence pairs sorted in descending order of confidence.
    """

    def __init__(self,
                 *,
                 classifier_id: str = None,
                 url: str = None,
                 text: str = None,
                 top_class: str = None,
                 classes: List['ClassifiedClass'] = None) -> None:
        """
        Initialize a Classification object.

        :param str classifier_id: (optional) Unique identifier for this classifier.
        :param str url: (optional) Link to the classifier.
        :param str text: (optional) The submitted phrase.
        :param str top_class: (optional) The class with the highest confidence.
        :param List[ClassifiedClass] classes: (optional) An array of up to ten
               class-confidence pairs sorted in descending order of confidence.
        """
        self.classifier_id = classifier_id
        self.url = url
        self.text = text
        self.top_class = top_class
        self.classes = classes

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'Classification':
        """Initialize a Classification object from a json dictionary."""
        args = {}
        if 'classifier_id' in _dict:
            args['classifier_id'] = _dict.get('classifier_id')
        if 'url' in _dict:
            args['url'] = _dict.get('url')
        if 'text' in _dict:
            args['text'] = _dict.get('text')
        if 'top_class' in _dict:
            args['top_class'] = _dict.get('top_class')
        if 'classes' in _dict:
            args['classes'] = [
                ClassifiedClass.from_dict(x) for x in _dict.get('classes')
            ]
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a Classification object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'classifier_id') and self.classifier_id is not None:
            _dict['classifier_id'] = self.classifier_id
        if hasattr(self, 'url') and self.url is not None:
            _dict['url'] = self.url
        if hasattr(self, 'text') and self.text is not None:
            _dict['text'] = self.text
        if hasattr(self, 'top_class') and self.top_class is not None:
            _dict['top_class'] = self.top_class
        if hasattr(self, 'classes') and self.classes is not None:
            _dict['classes'] = [x.to_dict() for x in self.classes]
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this Classification object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'Classification') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'Classification') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class ClassificationCollection():
    """
    Response from the classifier for multiple phrases.

    :attr str classifier_id: (optional) Unique identifier for this classifier.
    :attr str url: (optional) Link to the classifier.
    :attr List[CollectionItem] collection: (optional) An array of classifier
          responses for each submitted phrase.
    """

    def __init__(self,
                 *,
                 classifier_id: str = None,
                 url: str = None,
                 collection: List['CollectionItem'] = None) -> None:
        """
        Initialize a ClassificationCollection object.

        :param str classifier_id: (optional) Unique identifier for this classifier.
        :param str url: (optional) Link to the classifier.
        :param List[CollectionItem] collection: (optional) An array of classifier
               responses for each submitted phrase.
        """
        self.classifier_id = classifier_id
        self.url = url
        self.collection = collection

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ClassificationCollection':
        """Initialize a ClassificationCollection object from a json dictionary."""
        args = {}
        if 'classifier_id' in _dict:
            args['classifier_id'] = _dict.get('classifier_id')
        if 'url' in _dict:
            args['url'] = _dict.get('url')
        if 'collection' in _dict:
            args['collection'] = [
                CollectionItem.from_dict(x) for x in _dict.get('collection')
            ]
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ClassificationCollection object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'classifier_id') and self.classifier_id is not None:
            _dict['classifier_id'] = self.classifier_id
        if hasattr(self, 'url') and self.url is not None:
            _dict['url'] = self.url
        if hasattr(self, 'collection') and self.collection is not None:
            _dict['collection'] = [x.to_dict() for x in self.collection]
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this ClassificationCollection object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ClassificationCollection') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ClassificationCollection') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class ClassifiedClass():
    """
    Class and confidence.

    :attr float confidence: (optional) A decimal percentage that represents the
          confidence that Watson has in this class. Higher values represent higher
          confidences.
    :attr str class_name: (optional) Class label.
    """

    def __init__(self,
                 *,
                 confidence: float = None,
                 class_name: str = None) -> None:
        """
        Initialize a ClassifiedClass object.

        :param float confidence: (optional) A decimal percentage that represents
               the confidence that Watson has in this class. Higher values represent
               higher confidences.
        :param str class_name: (optional) Class label.
        """
        self.confidence = confidence
        self.class_name = class_name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ClassifiedClass':
        """Initialize a ClassifiedClass object from a json dictionary."""
        args = {}
        if 'confidence' in _dict:
            args['confidence'] = _dict.get('confidence')
        if 'class_name' in _dict:
            args['class_name'] = _dict.get('class_name')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ClassifiedClass object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'confidence') and self.confidence is not None:
            _dict['confidence'] = self.confidence
        if hasattr(self, 'class_name') and self.class_name is not None:
            _dict['class_name'] = self.class_name
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this ClassifiedClass object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ClassifiedClass') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ClassifiedClass') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class Classifier():
    """
    A classifier for natural language phrases.

    :attr str name: (optional) User-supplied name for the classifier.
    :attr str url: Link to the classifier.
    :attr str status: (optional) The state of the classifier.
    :attr str classifier_id: Unique identifier for this classifier.
    :attr datetime created: (optional) Date and time (UTC) the classifier was
          created.
    :attr str status_description: (optional) Additional detail about the status.
    :attr str language: (optional) The language used for the classifier.
    """

    def __init__(self,
                 url: str,
                 classifier_id: str,
                 *,
                 name: str = None,
                 status: str = None,
                 created: datetime = None,
                 status_description: str = None,
                 language: str = None) -> None:
        """
        Initialize a Classifier object.

        :param str url: Link to the classifier.
        :param str classifier_id: Unique identifier for this classifier.
        :param str name: (optional) User-supplied name for the classifier.
        :param str language: (optional) The language used for the classifier.
        """
        self.name = name
        self.url = url
        self.status = status
        self.classifier_id = classifier_id
        self.created = created
        self.status_description = status_description
        self.language = language

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'Classifier':
        """Initialize a Classifier object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'url' in _dict:
            args['url'] = _dict.get('url')
        else:
            raise ValueError(
                'Required property \'url\' not present in Classifier JSON')
        if 'status' in _dict:
            args['status'] = _dict.get('status')
        if 'classifier_id' in _dict:
            args['classifier_id'] = _dict.get('classifier_id')
        else:
            raise ValueError(
                'Required property \'classifier_id\' not present in Classifier JSON'
            )
        if 'created' in _dict:
            args['created'] = string_to_datetime(_dict.get('created'))
        if 'status_description' in _dict:
            args['status_description'] = _dict.get('status_description')
        if 'language' in _dict:
            args['language'] = _dict.get('language')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a Classifier object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'url') and self.url is not None:
            _dict['url'] = self.url
        if hasattr(self, 'status') and getattr(self, 'status') is not None:
            _dict['status'] = getattr(self, 'status')
        if hasattr(self, 'classifier_id') and self.classifier_id is not None:
            _dict['classifier_id'] = self.classifier_id
        if hasattr(self, 'created') and getattr(self, 'created') is not None:
            _dict['created'] = datetime_to_string(getattr(self, 'created'))
        if hasattr(self, 'status_description') and getattr(
                self, 'status_description') is not None:
            _dict['status_description'] = getattr(self, 'status_description')
        if hasattr(self, 'language') and self.language is not None:
            _dict['language'] = self.language
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this Classifier object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'Classifier') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'Classifier') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class StatusEnum(str, Enum):
        """
        The state of the classifier.
        """
        NON_EXISTENT = 'Non Existent'
        TRAINING = 'Training'
        FAILED = 'Failed'
        AVAILABLE = 'Available'
        UNAVAILABLE = 'Unavailable'


class ClassifierList():
    """
    List of available classifiers.

    :attr List[Classifier] classifiers: The classifiers available to the user.
          Returns an empty array if no classifiers are available.
    """

    def __init__(self, classifiers: List['Classifier']) -> None:
        """
        Initialize a ClassifierList object.

        :param List[Classifier] classifiers: The classifiers available to the user.
               Returns an empty array if no classifiers are available.
        """
        self.classifiers = classifiers

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ClassifierList':
        """Initialize a ClassifierList object from a json dictionary."""
        args = {}
        if 'classifiers' in _dict:
            args['classifiers'] = [
                Classifier.from_dict(x) for x in _dict.get('classifiers')
            ]
        else:
            raise ValueError(
                'Required property \'classifiers\' not present in ClassifierList JSON'
            )
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ClassifierList object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'classifiers') and self.classifiers is not None:
            _dict['classifiers'] = [x.to_dict() for x in self.classifiers]
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this ClassifierList object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ClassifierList') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ClassifierList') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class ClassifyInput():
    """
    Request payload to classify.

    :attr str text: The submitted phrase. The maximum length is 2048 characters.
    """

    def __init__(self, text: str) -> None:
        """
        Initialize a ClassifyInput object.

        :param str text: The submitted phrase. The maximum length is 2048
               characters.
        """
        self.text = text

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ClassifyInput':
        """Initialize a ClassifyInput object from a json dictionary."""
        args = {}
        if 'text' in _dict:
            args['text'] = _dict.get('text')
        else:
            raise ValueError(
                'Required property \'text\' not present in ClassifyInput JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ClassifyInput object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'text') and self.text is not None:
            _dict['text'] = self.text
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this ClassifyInput object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ClassifyInput') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ClassifyInput') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class CollectionItem():
    """
    Response from the classifier for a phrase in a collection.

    :attr str text: (optional) The submitted phrase. The maximum length is 2048
          characters.
    :attr str top_class: (optional) The class with the highest confidence.
    :attr List[ClassifiedClass] classes: (optional) An array of up to ten
          class-confidence pairs sorted in descending order of confidence.
    """

    def __init__(self,
                 *,
                 text: str = None,
                 top_class: str = None,
                 classes: List['ClassifiedClass'] = None) -> None:
        """
        Initialize a CollectionItem object.

        :param str text: (optional) The submitted phrase. The maximum length is
               2048 characters.
        :param str top_class: (optional) The class with the highest confidence.
        :param List[ClassifiedClass] classes: (optional) An array of up to ten
               class-confidence pairs sorted in descending order of confidence.
        """
        self.text = text
        self.top_class = top_class
        self.classes = classes

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'CollectionItem':
        """Initialize a CollectionItem object from a json dictionary."""
        args = {}
        if 'text' in _dict:
            args['text'] = _dict.get('text')
        if 'top_class' in _dict:
            args['top_class'] = _dict.get('top_class')
        if 'classes' in _dict:
            args['classes'] = [
                ClassifiedClass.from_dict(x) for x in _dict.get('classes')
            ]
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a CollectionItem object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'text') and self.text is not None:
            _dict['text'] = self.text
        if hasattr(self, 'top_class') and self.top_class is not None:
            _dict['top_class'] = self.top_class
        if hasattr(self, 'classes') and self.classes is not None:
            _dict['classes'] = [x.to_dict() for x in self.classes]
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this CollectionItem object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'CollectionItem') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'CollectionItem') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other
