# coding: utf-8

"""
    Mixpeek API

    This is the Mixpeek API, providing access to various endpoints for data processing and retrieval.

    The version of the OpenAPI document: 1.3.0
    Contact: info@mixpeek.com
    Generated by OpenAPI Generator (https://openapi-generator.tech)

    Do not edit the class manually.
"""  # noqa: E501


from __future__ import annotations
import pprint
import re  # noqa: F401
import json

from pydantic import BaseModel, ConfigDict, Field, StrictStr
from typing import Any, ClassVar, Dict, List, Optional
from mixpeek.models.task_response_inputs_inner import TaskResponseInputsInner
from mixpeek.models.task_status_enum import TaskStatusEnum
from mixpeek.models.task_type import TaskType
from typing import Optional, Set
from typing_extensions import Self

class TaskResponse(BaseModel):
    """
    Task response model returned by the API.  Extends TaskModel with additional convenience fields for API responses. This is the model returned when you GET /v1/tasks/{task_id}.  Additional Fields:     error_message: Convenience field that surfaces errors from additional_data                   for easier error handling in client code.  Inheritance:     Inherits all fields and documentation from TaskModel, including:     - task_id: Unique identifier     - task_type: Operation type     - status: Current status     - inputs: Input parameters     - outputs: Output results     - additional_data: Metadata and context  Storage Architecture:     Same as TaskModel - stored in Redis (24hr TTL) with MongoDB fallback.  Usage:     This model is automatically returned by task API endpoints. You don't     need to construct it manually - just call GET /v1/tasks/{task_id}.  Error Handling:     Check the error_message field for a user-friendly error string, or     additional_data['error'] for the full error details.  Example Response:     {         \"task_id\": \"task_abc123\",         \"task_type\": \"api_buckets_batches_process\",         \"status\": \"FAILED\",         \"inputs\": [\"batch_xyz\"],         \"outputs\": null,         \"additional_data\": {             \"error\": \"Failed to process batch: Object not found\",             \"batch_id\": \"batch_xyz\"         },         \"error_message\": \"Failed to process batch: Object not found\"     }
    """ # noqa: E501
    task_id: StrictStr = Field(description="Unique identifier for the task. REQUIRED. Used to poll task status via GET /v1/tasks/{task_id}. This ID is also stored on parent resources (batches, clusters, etc.) for cross-referencing. Format: UUID v4 or custom string identifier.")
    task_type: TaskType = Field(description="Type of operation this task represents. REQUIRED. Identifies the specific async operation being performed. Used for filtering and categorizing tasks. Common types: api_buckets_batches_process, engine_cluster_build, api_taxonomies_execute. See TaskType enum for complete list of supported operations.")
    status: TaskStatusEnum = Field(description="Current status of the task. REQUIRED. Indicates the current state of the async operation. Terminal statuses (COMPLETED, FAILED, CANCELED) indicate the task has finished and will not change. Active statuses (PENDING, IN_PROGRESS, PROCESSING) indicate the task is still running and should be polled. Use this field to determine when to stop polling.")
    inputs: Optional[List[TaskResponseInputsInner]] = Field(default=None, description="Input parameters or data used to start the task. OPTIONAL. May include IDs, configuration objects, or file references. Useful for debugging and understanding what data the task processed. Format: List of strings (IDs) or objects (configuration). Example: ['batch_id_123'] or [{'bucket_id': 'bkt_abc', 'config': {...}}]")
    outputs: Optional[List[TaskResponseInputsInner]] = Field(default=None, description="Output results produced by the task. OPTIONAL. Populated when task completes successfully. May include processed file IDs, result metrics, or status summaries. Check this field after task reaches COMPLETED status to get results. Format: List of strings (output IDs) or objects (result data).")
    additional_data: Optional[Dict[str, Any]] = Field(default=None, description="Additional metadata and context for the task. OPTIONAL. Contains job IDs, error details, progress info, and other task-specific metadata.   Common fields (all task types): - 'error': Error message if task failed - 'job_id': Ray job ID for engine tasks - 'from_mongodb': True if retrieved from MongoDB fallback (not Redis)   Batch-specific fields (task_type=api_buckets_batches_process): - 'batch_id': Batch identifier (REQUIRED) - 'bucket_id': Source bucket identifier (REQUIRED) - 'namespace_id': Namespace identifier (REQUIRED) - 'current_tier': Currently processing tier number, 0-indexed (OPTIONAL, None if not started) - 'total_tiers': Total number of tiers in the batch pipeline (REQUIRED) - 'collection_ids': Array of ALL collection IDs across all tiers (REQUIRED) - 'object_count': Number of objects being processed (REQUIRED) - 'sample_object_ids': First 5 object IDs for debugging/display (OPTIONAL)   Performance Note: Full object_ids array is NOT stored in task metadata to avoid bloating task documents (batches with 10k+ objects would add 200KB+ per task). For full object list, query the batch directly via GET /v1/buckets/{bucket_id}/batches/{batch_id}.   Note: For detailed per-tier status, use GET /v1/buckets/{bucket_id}/batches/{batch_id} to access the tier_tasks[] array which contains individual tier statuses, collection_ids, and timestamps for each tier.")
    error: Optional[StrictStr] = Field(default=None, description="Flattened error message for convenient error handling. OPTIONAL. Automatically populated from additional_data['error'] when the task has FAILED status. This is a convenience field - the full error details are always available in additional_data['error']. Use this field for displaying errors to users or logging. Will be None if task has not failed or if no error details are available. Serialized as 'error' in API responses for backward compatibility.")
    __properties: ClassVar[List[str]] = ["task_id", "task_type", "status", "inputs", "outputs", "additional_data", "error"]

    model_config = ConfigDict(
        populate_by_name=True,
        validate_assignment=True,
        protected_namespaces=(),
    )


    def to_str(self) -> str:
        """Returns the string representation of the model using alias"""
        return pprint.pformat(self.model_dump(by_alias=True))

    def to_json(self) -> str:
        """Returns the JSON representation of the model using alias"""
        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead
        return json.dumps(self.to_dict())

    @classmethod
    def from_json(cls, json_str: str) -> Optional[Self]:
        """Create an instance of TaskResponse from a JSON string"""
        return cls.from_dict(json.loads(json_str))

    def to_dict(self) -> Dict[str, Any]:
        """Return the dictionary representation of the model using alias.

        This has the following differences from calling pydantic's
        `self.model_dump(by_alias=True)`:

        * `None` is only added to the output dict for nullable fields that
          were set at model initialization. Other fields with value `None`
          are ignored.
        """
        excluded_fields: Set[str] = set([
        ])

        _dict = self.model_dump(
            by_alias=True,
            exclude=excluded_fields,
            exclude_none=True,
        )
        # override the default output from pydantic by calling `to_dict()` of each item in inputs (list)
        _items = []
        if self.inputs:
            for _item_inputs in self.inputs:
                if _item_inputs:
                    _items.append(_item_inputs.to_dict())
            _dict['inputs'] = _items
        # override the default output from pydantic by calling `to_dict()` of each item in outputs (list)
        _items = []
        if self.outputs:
            for _item_outputs in self.outputs:
                if _item_outputs:
                    _items.append(_item_outputs.to_dict())
            _dict['outputs'] = _items
        return _dict

    @classmethod
    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:
        """Create an instance of TaskResponse from a dict"""
        if obj is None:
            return None

        if not isinstance(obj, dict):
            return cls.model_validate(obj)

        _obj = cls.model_validate({
            "task_id": obj.get("task_id"),
            "task_type": obj.get("task_type"),
            "status": obj.get("status"),
            "inputs": [TaskResponseInputsInner.from_dict(_item) for _item in obj["inputs"]] if obj.get("inputs") is not None else None,
            "outputs": [TaskResponseInputsInner.from_dict(_item) for _item in obj["outputs"]] if obj.get("outputs") is not None else None,
            "additional_data": obj.get("additional_data"),
            "error": obj.get("error")
        })
        return _obj


