# 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, StrictBool, StrictInt, StrictStr
from typing import Any, ClassVar, Dict, List, Optional
from typing_extensions import Annotated
from airflow_client.client.models.reprocess_behavior import ReprocessBehavior
from typing import Optional, Set
from typing_extensions import Self

class BackfillResponse(BaseModel):
    """
    Base serializer for Backfill.
    """ # noqa: E501
    completed_at: Optional[datetime] = None
    created_at: datetime
    dag_display_name: StrictStr
    dag_id: StrictStr
    dag_run_conf: Dict[str, Any]
    from_date: datetime
    id: Annotated[int, Field(strict=True, ge=0)]
    is_paused: StrictBool
    max_active_runs: StrictInt
    reprocess_behavior: ReprocessBehavior
    to_date: datetime
    updated_at: datetime
    __properties: ClassVar[List[str]] = ["completed_at", "created_at", "dag_display_name", "dag_id", "dag_run_conf", "from_date", "id", "is_paused", "max_active_runs", "reprocess_behavior", "to_date", "updated_at"]

    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 BackfillResponse 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 BackfillResponse from a dict"""
        if obj is None:
            return None

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

        _obj = cls.model_validate({
            "completed_at": obj.get("completed_at"),
            "created_at": obj.get("created_at"),
            "dag_display_name": obj.get("dag_display_name"),
            "dag_id": obj.get("dag_id"),
            "dag_run_conf": obj.get("dag_run_conf"),
            "from_date": obj.get("from_date"),
            "id": obj.get("id"),
            "is_paused": obj.get("is_paused"),
            "max_active_runs": obj.get("max_active_runs"),
            "reprocess_behavior": obj.get("reprocess_behavior"),
            "to_date": obj.get("to_date"),
            "updated_at": obj.get("updated_at")
        })
        return _obj


