# 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, StrictInt, StrictStr
from typing import Any, ClassVar, Dict, List, Optional
from airflow_client.client.models.asset_alias_response import AssetAliasResponse
from airflow_client.client.models.dag_schedule_asset_reference import DagScheduleAssetReference
from airflow_client.client.models.task_outlet_asset_reference import TaskOutletAssetReference
from typing import Optional, Set
from typing_extensions import Self

class AssetResponse(BaseModel):
    """
    Asset serializer for responses.
    """ # noqa: E501
    aliases: List[AssetAliasResponse]
    consuming_dags: List[DagScheduleAssetReference]
    created_at: datetime
    extra: Optional[Dict[str, Any]] = None
    group: StrictStr
    id: StrictInt
    name: StrictStr
    producing_tasks: List[TaskOutletAssetReference]
    updated_at: datetime
    uri: StrictStr
    __properties: ClassVar[List[str]] = ["aliases", "consuming_dags", "created_at", "extra", "group", "id", "name", "producing_tasks", "updated_at", "uri"]

    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 AssetResponse 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 aliases (list)
        _items = []
        if self.aliases:
            for _item_aliases in self.aliases:
                if _item_aliases:
                    _items.append(_item_aliases.to_dict())
            _dict['aliases'] = _items
        # override the default output from pydantic by calling `to_dict()` of each item in consuming_dags (list)
        _items = []
        if self.consuming_dags:
            for _item_consuming_dags in self.consuming_dags:
                if _item_consuming_dags:
                    _items.append(_item_consuming_dags.to_dict())
            _dict['consuming_dags'] = _items
        # override the default output from pydantic by calling `to_dict()` of each item in producing_tasks (list)
        _items = []
        if self.producing_tasks:
            for _item_producing_tasks in self.producing_tasks:
                if _item_producing_tasks:
                    _items.append(_item_producing_tasks.to_dict())
            _dict['producing_tasks'] = _items
        return _dict

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

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

        _obj = cls.model_validate({
            "aliases": [AssetAliasResponse.from_dict(_item) for _item in obj["aliases"]] if obj.get("aliases") is not None else None,
            "consuming_dags": [DagScheduleAssetReference.from_dict(_item) for _item in obj["consuming_dags"]] if obj.get("consuming_dags") is not None else None,
            "created_at": obj.get("created_at"),
            "extra": obj.get("extra"),
            "group": obj.get("group"),
            "id": obj.get("id"),
            "name": obj.get("name"),
            "producing_tasks": [TaskOutletAssetReference.from_dict(_item) for _item in obj["producing_tasks"]] if obj.get("producing_tasks") is not None else None,
            "updated_at": obj.get("updated_at"),
            "uri": obj.get("uri")
        })
        return _obj


