# 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 pydantic import BaseModel, ConfigDict
from typing import Any, ClassVar, Dict, List, Optional
from airflow_client.client.models.bulk_action_response import BulkActionResponse
from typing import Optional, Set
from typing_extensions import Self

class BulkResponse(BaseModel):
    """
    Serializer for responses to bulk entity operations.  This represents the results of create, update, and delete actions performed on entity in bulk. Each action (if requested) is represented as a field containing details about successful keys and any encountered errors. Fields are populated in the response only if the respective action was part of the request, else are set None.
    """ # noqa: E501
    create: Optional[BulkActionResponse] = None
    delete: Optional[BulkActionResponse] = None
    update: Optional[BulkActionResponse] = None
    __properties: ClassVar[List[str]] = ["create", "delete", "update"]

    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 BulkResponse 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 create
        if self.create:
            _dict['create'] = self.create.to_dict()
        # override the default output from pydantic by calling `to_dict()` of delete
        if self.delete:
            _dict['delete'] = self.delete.to_dict()
        # override the default output from pydantic by calling `to_dict()` of update
        if self.update:
            _dict['update'] = self.update.to_dict()
        return _dict

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

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

        _obj = cls.model_validate({
            "create": BulkActionResponse.from_dict(obj["create"]) if obj.get("create") is not None else None,
            "delete": BulkActionResponse.from_dict(obj["delete"]) if obj.get("delete") is not None else None,
            "update": BulkActionResponse.from_dict(obj["update"]) if obj.get("update") is not None else None
        })
        return _obj


