# coding: utf-8

"""
    Example.com

    This is an **example** API to demonstrate features of the OpenAPI specification. # Introduction This API definition is intended to to be a good starting point for describing your API in [OpenAPI/Swagger format](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md). It also demonstrates features of the [create-openapi-repo](https://github.com/Redocly/create-openapi-repo) tool and the [Redoc](https://github.com/Redocly/Redoc) documentation engine. Beyond the standard OpenAPI syntax, we use a few  [vendor extensions](https://github.com/Redocly/Redoc/blob/master/docs/redoc-vendor-extensions.md). # OpenAPI Specification The goal of The OpenAPI Specification is to define a standard, language-agnostic interface to REST APIs which allows both humans and computers to discover and understand the capabilities of the service without access to source code, documentation, or through network traffic inspection. When properly defined via OpenAPI, a consumer can  understand and interact with the remote service with a minimal amount of implementation logic. Similar to what interfaces have done for lower-level programming, OpenAPI removes the guesswork in calling the service. 

    The version of the OpenAPI document: 1.0.0
    Contact: contact@example.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 datetime import date, datetime
from pydantic import BaseModel, ConfigDict, Field, SecretStr, StrictBool, StrictFloat, StrictInt, StrictStr, field_validator
from typing import Any, ClassVar, Dict, List, Optional, Union
from typing_extensions import Annotated
from typing import Optional, Set
from typing_extensions import Self

class ModelSchema(BaseModel):
    """
    ModelSchema
    """ # noqa: E501
    string_property: Optional[StrictStr] = Field(default=None, description="Property name's description (type is string)", alias="stringProperty")
    read_only_string_property: Optional[StrictStr] = Field(default=None, description="Notice this only appears in the response.", alias="readOnlyStringProperty")
    write_only_string_property: Optional[StrictStr] = Field(default=None, description="Notice this only appears in the request.", alias="writeOnlyStringProperty")
    min_length_string: Optional[Annotated[str, Field(min_length=4, strict=True)]] = Field(default=None, description="Property name's description (type is string)", alias="minLengthString")
    max_length_string: Optional[Annotated[str, Field(strict=True, max_length=140)]] = Field(default=None, description="Property name's description (type is string)", alias="maxLengthString")
    min_and_max_length_string: Optional[Annotated[str, Field(min_length=4, strict=True, max_length=140)]] = Field(default=None, description="Property name's description (type is string)", alias="minAndMaxLengthString")
    nullable_or_string_property: Optional[StrictStr] = Field(default=None, description="Property name's description (type is string or null)", alias="nullableOrStringProperty")
    string_enum_values: Optional[StrictStr] = Field(default=None, description="Property name's description (type is string)", alias="stringEnumValues")
    string_date_time: Optional[datetime] = Field(default=None, description="Property name's description (type is string, format is date-time)", alias="stringDateTime")
    string_date: Optional[date] = Field(default=None, description="Property name's description (type is string, format is date-time)", alias="stringDate")
    string_email: Optional[StrictStr] = Field(default=None, description="Property name's description (type is string, format is email)", alias="stringEmail")
    string_ip_address_v4: Optional[StrictStr] = Field(default=None, description="Property name's description (type is string, format is ipv4 address)", alias="stringIpAddressV4")
    string_ip_address_v6: Optional[StrictStr] = Field(default=None, description="Property name's description (type is string, format is ipv6 address)", alias="stringIpAddressV6")
    string_password: Optional[SecretStr] = Field(default=None, description="Property name's description (type is string, format is password)", alias="stringPassword")
    string_hostname: Optional[StrictStr] = Field(default=None, description="Property name's description (type is string, format is hostname)", alias="stringHostname")
    string_uri: Optional[StrictStr] = Field(default=None, description="Property name's description (type is string, format is uri)", alias="stringUri")
    string_uuid: Optional[StrictStr] = Field(default=None, description="Property name's description (type is string, format is uuid)", alias="stringUuid")
    number_property: Optional[Union[StrictFloat, StrictInt]] = Field(default=None, description="Property name's description (type is number)", alias="numberProperty")
    number_float: Optional[Union[StrictFloat, StrictInt]] = Field(default=None, description="Property name's description (type is number, format is float)", alias="numberFloat")
    number_double: Optional[Union[StrictFloat, StrictInt]] = Field(default=None, description="Property name's description (type is number, format is double)", alias="numberDouble")
    number_greater_than_or_equals: Optional[Union[Annotated[float, Field(strict=True, ge=5)], Annotated[int, Field(strict=True, ge=5)]]] = Field(default=None, description="Property name's description (type is number)", alias="numberGreaterThanOrEquals")
    number_greater_than: Optional[Union[StrictFloat, StrictInt]] = Field(default=None, description="Property name's description (type is number)", alias="numberGreaterThan")
    number_less_than: Optional[Union[StrictFloat, StrictInt]] = Field(default=None, description="Property name's description (type is number)", alias="numberLessThan")
    number_less_than_or_equals: Optional[Union[Annotated[float, Field(le=8, strict=True)], Annotated[int, Field(le=8, strict=True)]]] = Field(default=None, description="Property name's description (type is number)", alias="numberLessThanOrEquals")
    number_range: Optional[Union[Annotated[float, Field(le=8, strict=True, ge=5)], Annotated[int, Field(le=8, strict=True, ge=5)]]] = Field(default=None, description="Property name's description (type is number)", alias="numberRange")
    number_range_exclusive_maximum: Optional[Union[Annotated[float, Field(strict=True, ge=5)], Annotated[int, Field(strict=True, ge=5)]]] = Field(default=None, description="Property name's description (type is number)", alias="numberRangeExclusiveMaximum")
    number_range_exclusive_minimum_and_maximum: Optional[Union[StrictFloat, StrictInt]] = Field(default=None, description="Property name's description (type is number)", alias="numberRangeExclusiveMinimumAndMaximum")
    number_multiple_of: Optional[Union[Annotated[float, Field(multiple_of=2, strict=True)], Annotated[int, Field(strict=True)]]] = Field(default=None, description="Property name's description (type is number)", alias="numberMultipleOf")
    integer_type: Optional[StrictInt] = Field(default=None, description="Property name's description (type is integer)", alias="integerType")
    integer32bit: Optional[StrictInt] = Field(default=None, description="Property name's description (type is integer, format is int32)")
    integer64bit: Optional[StrictInt] = Field(default=None, description="Property name's description (type is integer, format is int64)")
    boolean_property: Optional[StrictBool] = Field(default=None, description="Property name's description (type is boolean)", alias="booleanProperty")
    __properties: ClassVar[List[str]] = ["stringProperty", "readOnlyStringProperty", "writeOnlyStringProperty", "minLengthString", "maxLengthString", "minAndMaxLengthString", "nullableOrStringProperty", "stringEnumValues", "stringDateTime", "stringDate", "stringEmail", "stringIpAddressV4", "stringIpAddressV6", "stringPassword", "stringHostname", "stringUri", "stringUuid", "numberProperty", "numberFloat", "numberDouble", "numberGreaterThanOrEquals", "numberGreaterThan", "numberLessThan", "numberLessThanOrEquals", "numberRange", "numberRangeExclusiveMaximum", "numberRangeExclusiveMinimumAndMaximum", "numberMultipleOf", "integerType", "integer32bit", "integer64bit", "booleanProperty"]

    @field_validator('string_enum_values')
    def string_enum_values_validate_enum(cls, value):
        """Validates the enum"""
        if value is None:
            return value

        if value not in set(['sample', 'example', 'specimen', 'case', 'instance', 'illustration']):
            raise ValueError("must be one of enum values ('sample', 'example', 'specimen', 'case', 'instance', 'illustration')")
        return value

    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 ModelSchema 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.
        * OpenAPI `readOnly` fields are excluded.
        """
        excluded_fields: Set[str] = set([
            "read_only_string_property",
        ])

        _dict = self.model_dump(
            by_alias=True,
            exclude=excluded_fields,
            exclude_none=True,
        )
        # set to None if nullable_or_string_property (nullable) is None
        # and model_fields_set contains the field
        if self.nullable_or_string_property is None and "nullable_or_string_property" in self.model_fields_set:
            _dict['nullableOrStringProperty'] = None

        return _dict

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

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

        _obj = cls.model_validate({
            "stringProperty": obj.get("stringProperty"),
            "readOnlyStringProperty": obj.get("readOnlyStringProperty"),
            "writeOnlyStringProperty": obj.get("writeOnlyStringProperty"),
            "minLengthString": obj.get("minLengthString"),
            "maxLengthString": obj.get("maxLengthString"),
            "minAndMaxLengthString": obj.get("minAndMaxLengthString"),
            "nullableOrStringProperty": obj.get("nullableOrStringProperty"),
            "stringEnumValues": obj.get("stringEnumValues"),
            "stringDateTime": obj.get("stringDateTime"),
            "stringDate": obj.get("stringDate"),
            "stringEmail": obj.get("stringEmail"),
            "stringIpAddressV4": obj.get("stringIpAddressV4"),
            "stringIpAddressV6": obj.get("stringIpAddressV6"),
            "stringPassword": obj.get("stringPassword"),
            "stringHostname": obj.get("stringHostname"),
            "stringUri": obj.get("stringUri"),
            "stringUuid": obj.get("stringUuid"),
            "numberProperty": obj.get("numberProperty"),
            "numberFloat": obj.get("numberFloat"),
            "numberDouble": obj.get("numberDouble"),
            "numberGreaterThanOrEquals": obj.get("numberGreaterThanOrEquals"),
            "numberGreaterThan": obj.get("numberGreaterThan"),
            "numberLessThan": obj.get("numberLessThan"),
            "numberLessThanOrEquals": obj.get("numberLessThanOrEquals"),
            "numberRange": obj.get("numberRange"),
            "numberRangeExclusiveMaximum": obj.get("numberRangeExclusiveMaximum"),
            "numberRangeExclusiveMinimumAndMaximum": obj.get("numberRangeExclusiveMinimumAndMaximum"),
            "numberMultipleOf": obj.get("numberMultipleOf"),
            "integerType": obj.get("integerType"),
            "integer32bit": obj.get("integer32bit"),
            "integer64bit": obj.get("integer64bit"),
            "booleanProperty": obj.get("booleanProperty")
        })
        return _obj


