processing.py 3.6 KB
Newer Older
1
from array import array
A
arcticfaded 已提交
2 3 4
from inflection import underscore
from typing import Any, Dict, Optional
from pydantic import BaseModel, Field, create_model
5
from modules.processing import StableDiffusionProcessingTxt2Img, StableDiffusionProcessingImg2Img
A
arcticfaded 已提交
6 7 8
import inspect


A
arcticfaded 已提交
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
API_NOT_ALLOWED = [
    "self",
    "kwargs",
    "sd_model",
    "outpath_samples",
    "outpath_grids",
    "sampler_index",
    "do_not_save_samples",
    "do_not_save_grid",
    "extra_generation_params",
    "overlay_images",
    "do_not_reload_embeddings",
    "seed_enable_extras",
    "prompt_for_display",
    "sampler_noise_scheduler_override",
    "ddim_discretize"
]

A
arcticfaded 已提交
27 28 29 30 31 32 33 34 35
class ModelDef(BaseModel):
    """Assistance Class for Pydantic Dynamic Model Generation"""

    field: str
    field_alias: str
    field_type: Any
    field_value: Any


A
arcticfaded 已提交
36
class PydanticModelGenerator:
A
arcticfaded 已提交
37
    """
J
Jonathan 已提交
38 39 40
    Takes in created classes and stubs them out in a way FastAPI/Pydantic is happy about:
    source_data is a snapshot of the default values produced by the class
    params are the names of the actual keys required by __init__
A
arcticfaded 已提交
41 42 43 44 45
    """

    def __init__(
        self,
        model_name: str = None,
A
arcticfaded 已提交
46 47
        class_instance = None,
        additional_fields = None,
A
arcticfaded 已提交
48
    ):
A
arcticfaded 已提交
49 50 51 52
        def field_type_generator(k, v):
            # field_type = str if not overrides.get(k) else overrides[k]["type"]
            # print(k, v.annotation, v.default)
            field_type = v.annotation
A
arcticfaded 已提交
53 54 55
            
            return Optional[field_type]
        
A
arcticfaded 已提交
56 57 58 59 60 61 62 63
        def merge_class_params(class_):
            all_classes = list(filter(lambda x: x is not object, inspect.getmro(class_)))
            parameters = {}
            for classes in all_classes:
                parameters = {**parameters, **inspect.signature(classes.__init__).parameters}
            return parameters
            
                
A
arcticfaded 已提交
64
        self._model_name = model_name
A
arcticfaded 已提交
65
        self._class_data = merge_class_params(class_instance)
A
arcticfaded 已提交
66 67 68 69
        self._model_def = [
            ModelDef(
                field=underscore(k),
                field_alias=k,
A
arcticfaded 已提交
70 71
                field_type=field_type_generator(k, v),
                field_value=v.default
A
arcticfaded 已提交
72
            )
A
arcticfaded 已提交
73
            for (k,v) in self._class_data.items() if k not in API_NOT_ALLOWED
A
arcticfaded 已提交
74
        ]
A
arcticfaded 已提交
75 76 77 78 79 80 81
        
        for fields in additional_fields:
            self._model_def.append(ModelDef(
                field=underscore(fields["key"]), 
                field_alias=fields["key"], 
                field_type=fields["type"],
                field_value=fields["default"]))
A
arcticfaded 已提交
82 83 84 85 86 87 88 89 90 91 92

    def generate_model(self):
        """
        Creates a pydantic BaseModel
        from the json and overrides provided at initialization
        """
        fields = {
            d.field: (d.field_type, Field(default=d.field_value, alias=d.field_alias)) for d in self._model_def
        }
        DynamicModel = create_model(self._model_name, **fields)
        DynamicModel.__config__.allow_population_by_field_name = True
A
arcticfaded 已提交
93
        DynamicModel.__config__.allow_mutation = True
A
arcticfaded 已提交
94 95
        return DynamicModel
    
96
StableDiffusionTxt2ImgProcessingAPI = PydanticModelGenerator(
A
arcticfaded 已提交
97 98
    "StableDiffusionProcessingTxt2Img", 
    StableDiffusionProcessingTxt2Img,
A
arcticfaded 已提交
99
    [{"key": "sampler_index", "type": str, "default": "Euler"}]
100 101 102 103 104
).generate_model()

StableDiffusionImg2ImgProcessingAPI = PydanticModelGenerator(
    "StableDiffusionProcessingImg2Img", 
    StableDiffusionProcessingImg2Img,
S
Stephen 已提交
105
    [{"key": "sampler_index", "type": str, "default": "Euler"}, {"key": "init_images", "type": list, "default": None}, {"key": "denoising_strength", "type": float, "default": 0.75}, {"key": "mask", "type": str, "default": None}]
A
arcticfaded 已提交
106
).generate_model()