# coding: utf-8

"""
    FastAPI

    No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)

    The version of the OpenAPI document: 0.1.0
    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 typing import Dict, List, Optional, Union
from pydantic.v1 import BaseModel, Field, StrictBool, StrictFloat, StrictInt, StrictStr, confloat, conint, conlist, constr
from clients.image_gen.models.fixed_random_seed import FixedRandomSeed
from clients.image_gen.models.image_encoding import ImageEncoding
from clients.image_gen.models.scheduler import Scheduler
from clients.image_gen.models.sdxl_styles import SDXLStyles

class ImageGenerationRequest(BaseModel):
    """
    Generate one or more images based on the given parameters.  # noqa: E501
    """
    prompt: constr(strict=True, max_length=10000) = Field(..., description="Text describing the image content to generate.")
    prompt_2: Optional[constr(strict=True, max_length=10000)] = Field(None, description="Text with a high-level description of the image to generate. Used only by SD XL.")
    negative_prompt: Optional[constr(strict=True, max_length=10000)] = Field(None, description="Text describing image traits to avoid during generation.")
    negative_prompt_2: Optional[constr(strict=True, max_length=10000)] = Field(None, description="Text with a high level description of things to avoid during generation. Used only by SD XL.")
    checkpoint: Optional[StrictStr] = Field(None, description="Custom checkpoint to be used during image generation.")
    controlnet: Optional[StrictStr] = Field(None, description="ControlNet to be used during image generation")
    vae: Optional[StrictStr] = Field(None, description="Custom VAE to be used during image generation.")
    textual_inversions: Optional[Dict[str, StrictStr]] = Field(None, description="A dictionary of textual inversions to be used during image generation. Textual inversions as keys and trigger words as values.")
    loras: Optional[Dict[str, Union[StrictFloat, StrictInt]]] = Field(None, description="A dictionary of LoRAs to apply. LoRAs as keys and their weights (float) as values.")
    sampler: Optional[Scheduler] = None
    height: Optional[StrictInt] = Field(None, description="Integer representing the height of image to generate. None will default to 512 for SD 1.5 and 1024 for SD XL and SSD. Supported resolutions (w,h): SDXL={(1536, 640), (768, 1344), (832, 1216), (1344, 768), (1152, 896), (640, 1536), (1216, 832), (896, 1152), (1024, 1024)}, SD1.5={(768, 576), (1024, 576), (640, 512), (384, 704), (640, 768), (640, 640), (1024, 768), (1536, 1024), (768, 1024), (576, 448), (1024, 1024), (896, 896), (704, 1216), (512, 512), (448, 576), (832, 512), (512, 704), (576, 768), (1216, 704), (512, 768), (512, 832), (1024, 1536), (576, 1024), (704, 384), (768, 512)}, SSD={(1536, 640), (768, 1344), (832, 1216), (1344, 768), (1152, 896), (640, 1536), (1216, 832), (896, 1152), (1024, 1024)}")
    width: Optional[StrictInt] = Field(None, description="Integer representing the width of image to generate. None will default to 512 for SD 1.5 and 1024 for SD XL and SSD. Supported resolutions (w,h): SDXL={(1536, 640), (768, 1344), (832, 1216), (1344, 768), (1152, 896), (640, 1536), (1216, 832), (896, 1152), (1024, 1024)}, SD1.5={(768, 576), (1024, 576), (640, 512), (384, 704), (640, 768), (640, 640), (1024, 768), (1536, 1024), (768, 1024), (576, 448), (1024, 1024), (896, 896), (704, 1216), (512, 512), (448, 576), (832, 512), (512, 704), (576, 768), (1216, 704), (512, 768), (512, 832), (1024, 1536), (576, 1024), (704, 384), (768, 512)}, SSD={(1536, 640), (768, 1344), (832, 1216), (1344, 768), (1152, 896), (640, 1536), (1216, 832), (896, 1152), (1024, 1024)}")
    cfg_scale: Optional[Union[confloat(le=50.0, strict=True), conint(le=50, strict=True)]] = Field(12.0, description="Floating-point number represeting how closely to adhere to prompt description. Must be a positive number no greater than 50.0.")
    steps: Optional[conint(strict=True, le=200)] = Field(30, description="Integer repreenting how many steps of diffusion to run. Must be greater than 0 and less than or equal to 200.")
    num_images: Optional[conint(strict=True, le=16)] = Field(1, description="Integer representing how many output images to generate with a single prompt/configuration.")
    seed: Optional[FixedRandomSeed] = None
    controlnet_image: Optional[StrictStr] = Field(None, description="Controlnet image encoded in b64 string for guiding image generation. Required for controlnet engines.")
    init_image: Optional[StrictStr] = Field(None, description="Starting point image encoded in b64 string for Image to Image generation mode.")
    mask_image: Optional[StrictStr] = Field(None, description="b64 encoded mask image for inpainting. White area should indicate where to paint.")
    strength: Optional[Union[confloat(le=1.0, ge=0.0, strict=True), conint(le=1, ge=0, strict=True)]] = Field(0.8, description="Floating-point number indicating how much creative the Image to Image generation mode should be. Must be greater than 0 and less than or equal to 1.0.")
    style_preset: Optional[SDXLStyles] = None
    use_refiner: Optional[StrictBool] = Field(True, description="Whether to enable and apply the SDXL refiner model to the image generation.")
    high_noise_frac: Optional[Union[confloat(le=1.0, ge=0.0, strict=True), conint(le=1, ge=0, strict=True)]] = Field(0.8, description="Floating-point number that defines the fraction of steps to perform with the base model. Used only by SD XL. Must be greater than or equal to 0.0 and less than or equal to 1.0.")
    controlnet_conditioning_scale: Optional[Union[StrictFloat, StrictInt]] = Field(1.0, description="How strong the effect of the controlnet should be.")
    controlnet_early_stop: Optional[Union[confloat(le=1.0, ge=0.0, strict=True), conint(le=1, ge=0, strict=True)]] = Field(None, description="If provided, indicates fraction of steps at which to stop applying controlnet. This can be used to sometimes generate better outputs.")
    controlnet_preprocess: Optional[StrictBool] = Field(True, description="Whether to apply automatic ControlNet preprocessing.")
    clip_skip: Optional[StrictInt] = Field(None, description="Optionally skip later layers of the text encoder. Higher values lead to more abstract interpretations of the prompt.")
    outpainting: Optional[StrictBool] = Field(False, description="Whether the request requires outpainting or not. If so, special preprocessing is applied for better results.")
    enable_safety: Optional[StrictBool] = Field(False, description="Boolean defining whether to use safety checker system on generated outputs or not.")
    image_encoding: Optional[ImageEncoding] = None
    transfer_images: Optional[Dict[str, conlist(StrictStr)]] = Field(None, description="A dictionary containing a mapping of trigger words to a list of sample images which demonstrate the desired object or style to transfer.")
    force_asset_download: Optional[StrictBool] = Field(False, description="[Internal] Boolean defining if assets must be re-downloaded into the cache even if present.")
    force_asset_gpu_copy: Optional[StrictBool] = Field(False, description="[Internal] Boolean defining if assets must to be copied into the GPU even if present.")
    __properties = ["prompt", "prompt_2", "negative_prompt", "negative_prompt_2", "checkpoint", "controlnet", "vae", "textual_inversions", "loras", "sampler", "height", "width", "cfg_scale", "steps", "num_images", "seed", "controlnet_image", "init_image", "mask_image", "strength", "style_preset", "use_refiner", "high_noise_frac", "controlnet_conditioning_scale", "controlnet_early_stop", "controlnet_preprocess", "clip_skip", "outpainting", "enable_safety", "image_encoding", "transfer_images", "force_asset_download", "force_asset_gpu_copy"]

    class Config:
        """Pydantic configuration"""
        allow_population_by_field_name = True
        validate_assignment = True

    def to_str(self) -> str:
        """Returns the string representation of the model using alias"""
        return pprint.pformat(self.dict(by_alias=True))

    def to_json(self) -> str:
        """Returns the JSON representation of the model using alias"""
        return json.dumps(self.to_dict())

    @classmethod
    def from_json(cls, json_str: str) -> ImageGenerationRequest:
        """Create an instance of ImageGenerationRequest from a JSON string"""
        return cls.from_dict(json.loads(json_str))

    def to_dict(self):
        """Returns the dictionary representation of the model using alias"""
        _dict = self.dict(by_alias=True,
                          exclude={
                          },
                          exclude_none=True)
        # override the default output from pydantic by calling `to_dict()` of seed
        if self.seed:
            _dict['seed'] = self.seed.to_dict()
        # override the default output from pydantic by calling `to_dict()` of each value in transfer_images (dict of array)
        _field_dict_of_array = {}
        if self.transfer_images:
            for _key in self.transfer_images:
                if self.transfer_images[_key]:
                    _field_dict_of_array[_key] = [
                        _item.to_dict() for _item in self.transfer_images[_key]
                    ]
            _dict['transfer_images'] = _field_dict_of_array
        return _dict

    @classmethod
    def from_dict(cls, obj: dict) -> ImageGenerationRequest:
        """Create an instance of ImageGenerationRequest from a dict"""
        if obj is None:
            return None

        if not isinstance(obj, dict):
            return ImageGenerationRequest.parse_obj(obj)

        _obj = ImageGenerationRequest.parse_obj({
            "prompt": obj.get("prompt"),
            "prompt_2": obj.get("prompt_2"),
            "negative_prompt": obj.get("negative_prompt"),
            "negative_prompt_2": obj.get("negative_prompt_2"),
            "checkpoint": obj.get("checkpoint"),
            "controlnet": obj.get("controlnet"),
            "vae": obj.get("vae"),
            "textual_inversions": obj.get("textual_inversions"),
            "loras": obj.get("loras"),
            "sampler": obj.get("sampler"),
            "height": obj.get("height"),
            "width": obj.get("width"),
            "cfg_scale": obj.get("cfg_scale") if obj.get("cfg_scale") is not None else 12.0,
            "steps": obj.get("steps") if obj.get("steps") is not None else 30,
            "num_images": obj.get("num_images") if obj.get("num_images") is not None else 1,
            "seed": FixedRandomSeed.from_dict(obj.get("seed")) if obj.get("seed") is not None else None,
            "controlnet_image": obj.get("controlnet_image"),
            "init_image": obj.get("init_image"),
            "mask_image": obj.get("mask_image"),
            "strength": obj.get("strength") if obj.get("strength") is not None else 0.8,
            "style_preset": obj.get("style_preset"),
            "use_refiner": obj.get("use_refiner") if obj.get("use_refiner") is not None else True,
            "high_noise_frac": obj.get("high_noise_frac") if obj.get("high_noise_frac") is not None else 0.8,
            "controlnet_conditioning_scale": obj.get("controlnet_conditioning_scale") if obj.get("controlnet_conditioning_scale") is not None else 1.0,
            "controlnet_early_stop": obj.get("controlnet_early_stop"),
            "controlnet_preprocess": obj.get("controlnet_preprocess") if obj.get("controlnet_preprocess") is not None else True,
            "clip_skip": obj.get("clip_skip"),
            "outpainting": obj.get("outpainting") if obj.get("outpainting") is not None else False,
            "enable_safety": obj.get("enable_safety") if obj.get("enable_safety") is not None else False,
            "image_encoding": obj.get("image_encoding"),
            "transfer_images": obj.get("transfer_images"),
            "force_asset_download": obj.get("force_asset_download") if obj.get("force_asset_download") is not None else False,
            "force_asset_gpu_copy": obj.get("force_asset_gpu_copy") if obj.get("force_asset_gpu_copy") is not None else False
        })
        return _obj


