# coding: utf-8

"""
    Airflow API

    Airflow API. All endpoints located under ``/api/v2`` can be used safely, are stable and backward compatible. Endpoints located under ``/ui`` are dedicated to the UI and are subject to breaking change depending on the need of the frontend. Users should not rely on those but use the public ones instead.

    The version of the OpenAPI document: 2
    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 datetime import datetime
from pydantic import BaseModel, ConfigDict, Field, StrictFloat, StrictInt, StrictStr
from typing import Any, ClassVar, Dict, List, Optional, Union
from typing_extensions import Annotated
from airflow_client.client.models.task_instance_state import TaskInstanceState
from typing import Optional, Set
from typing_extensions import Self

class TaskInstancesBatchBody(BaseModel):
    """
    Task Instance body for get batch.
    """ # noqa: E501
    dag_ids: Optional[List[StrictStr]] = None
    dag_run_ids: Optional[List[StrictStr]] = None
    duration_gte: Optional[Union[StrictFloat, StrictInt]] = None
    duration_lte: Optional[Union[StrictFloat, StrictInt]] = None
    end_date_gte: Optional[datetime] = None
    end_date_lte: Optional[datetime] = None
    executor: Optional[List[StrictStr]] = None
    logical_date_gte: Optional[datetime] = None
    logical_date_lte: Optional[datetime] = None
    order_by: Optional[StrictStr] = None
    page_limit: Optional[Annotated[int, Field(strict=True, ge=0)]] = 100
    page_offset: Optional[Annotated[int, Field(strict=True, ge=0)]] = 0
    pool: Optional[List[StrictStr]] = None
    queue: Optional[List[StrictStr]] = None
    run_after_gte: Optional[datetime] = None
    run_after_lte: Optional[datetime] = None
    start_date_gte: Optional[datetime] = None
    start_date_lte: Optional[datetime] = None
    state: Optional[List[Optional[TaskInstanceState]]] = None
    task_ids: Optional[List[StrictStr]] = None
    __properties: ClassVar[List[str]] = ["dag_ids", "dag_run_ids", "duration_gte", "duration_lte", "end_date_gte", "end_date_lte", "executor", "logical_date_gte", "logical_date_lte", "order_by", "page_limit", "page_offset", "pool", "queue", "run_after_gte", "run_after_lte", "start_date_gte", "start_date_lte", "state", "task_ids"]

    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 TaskInstancesBatchBody 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,
        )
        return _dict

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

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

        _obj = cls.model_validate({
            "dag_ids": obj.get("dag_ids"),
            "dag_run_ids": obj.get("dag_run_ids"),
            "duration_gte": obj.get("duration_gte"),
            "duration_lte": obj.get("duration_lte"),
            "end_date_gte": obj.get("end_date_gte"),
            "end_date_lte": obj.get("end_date_lte"),
            "executor": obj.get("executor"),
            "logical_date_gte": obj.get("logical_date_gte"),
            "logical_date_lte": obj.get("logical_date_lte"),
            "order_by": obj.get("order_by"),
            "page_limit": obj.get("page_limit") if obj.get("page_limit") is not None else 100,
            "page_offset": obj.get("page_offset") if obj.get("page_offset") is not None else 0,
            "pool": obj.get("pool"),
            "queue": obj.get("queue"),
            "run_after_gte": obj.get("run_after_gte"),
            "run_after_lte": obj.get("run_after_lte"),
            "start_date_gte": obj.get("start_date_gte"),
            "start_date_lte": obj.get("start_date_lte"),
            "state": obj.get("state"),
            "task_ids": obj.get("task_ids")
        })
        return _obj


