From 68fb7d06f78b1734c6601f5f0afda147b2820c10 Mon Sep 17 00:00:00 2001 From: Bryce Date: Thu, 28 Sep 2023 23:32:30 -0700 Subject: [PATCH] fix: pydantic models for http server working now. Fixes #380 --- .gitignore | 1 + README.md | 4 ++ imaginairy/http/stablestudio/models.py | 4 +- imaginairy/http/utils.py | 4 +- imaginairy/schema.py | 22 ++++----- requirements-dev.in | 2 + requirements-dev.txt | 54 ++++++++++++----------- setup.py | 3 +- tests/constraints.txt | 3 ++ tests/test_schema/test_lazy_load_image.py | 11 +++++ 10 files changed, 66 insertions(+), 42 deletions(-) create mode 100644 tests/constraints.txt diff --git a/.gitignore b/.gitignore index 5158cd8a..ed9b55a6 100644 --- a/.gitignore +++ b/.gitignore @@ -30,3 +30,4 @@ tests/vastai_cli.py **/.eggs /img_size_memory_usage.csv /tests/test_cluster_output/ +/.env diff --git a/README.md b/README.md index 49b8e91e..8ad46a24 100644 --- a/README.md +++ b/README.md @@ -493,6 +493,10 @@ A: The AI models are cached in `~/.cache/` (or `HUGGINGFACE_HUB_CACHE`). To dele ## ChangeLog +**13.2.1** +- fix: pydantic models for http server working now. Fixes #380 +- fix: install triton so annoying message is gone + **13.2.0** - fix: allow tile_mode to be set to True or False for backward compatibility - fix: various pydantic issues have been resolved diff --git a/imaginairy/http/stablestudio/models.py b/imaginairy/http/stablestudio/models.py index 2af0ff05..1d30928d 100644 --- a/imaginairy/http/stablestudio/models.py +++ b/imaginairy/http/stablestudio/models.py @@ -119,5 +119,5 @@ class StableStudioBatchResponse(BaseModel): images: List[StableStudioImage] -StableStudioInput.update_forward_refs() -StableStudioImage.update_forward_refs() +StableStudioInput.model_rebuild() +StableStudioImage.model_rebuild() diff --git a/imaginairy/http/utils.py b/imaginairy/http/utils.py index 2d91e53a..68551961 100644 --- a/imaginairy/http/utils.py +++ b/imaginairy/http/utils.py @@ -5,7 +5,7 @@ def generate_image(prompt): - """ImaginPrompt to generated image.""" + """ImaginePrompt to generated image.""" result = next(imagine([prompt])) img = result.images["generated"] img_io = BytesIO() @@ -27,7 +27,7 @@ def __get_validators__(cls): yield cls.validate @classmethod - def validate(cls, v): + def validate(cls, v, info): if isinstance(v, bytes): return v if isinstance(v, str): diff --git a/imaginairy/schema.py b/imaginairy/schema.py index 0ee4563c..2ed54893 100644 --- a/imaginairy/schema.py +++ b/imaginairy/schema.py @@ -90,6 +90,12 @@ def __getattr__(self, key): self._load_img() return getattr(self._img, key) + def __setstate__(self, state): + self.__dict__.update(state) + + def __getstate__(self): + return self.__dict__ + def _load_img(self): if self._img is None: from PIL import Image, ImageOps @@ -192,16 +198,10 @@ def __repr__(self): shows filepath or url if available. """ - return f"" - - -# -# LazyLoadingImage = Annotated[ -# _LazyLoadingImage, -# AfterValidator(_LazyLoadingImage.validate), -# PlainSerializer(lambda i: str(i), return_type=str), -# WithJsonSchema({"type": "string"}, mode="serialization"), -# ] + try: + return f"" + except Exception as e: # noqa + return f"" class ControlNetInput(BaseModel): @@ -245,7 +245,7 @@ def __repr__(self): return f"{self.weight}*({self.text})" -class ImaginePrompt(BaseModel): +class ImaginePrompt(BaseModel, protected_namespaces=()): prompt: Optional[List[WeightedPrompt]] = Field(default=None, validate_default=True) negative_prompt: Optional[List[WeightedPrompt]] = Field( default=None, validate_default=True diff --git a/requirements-dev.in b/requirements-dev.in index d1310ac7..b69f06a9 100644 --- a/requirements-dev.in +++ b/requirements-dev.in @@ -10,3 +10,5 @@ pytest-randomly pytest-sugar responses wheel + +-c tests/constraints.txt \ No newline at end of file diff --git a/requirements-dev.txt b/requirements-dev.txt index 982c56ea..89056ed5 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -16,7 +16,7 @@ anyio==3.7.1 # via # fastapi # starlette -astroid==2.15.6 +astroid==2.15.8 # via pylint async-timeout==4.0.3 # via aiohttp @@ -42,13 +42,13 @@ click-help-colors==0.9.2 # via imaginAIry (setup.py) click-shell==2.1 # via imaginAIry (setup.py) -contourpy==1.1.0 +contourpy==1.1.1 # via matplotlib coverage==7.3.1 # via -r requirements-dev.in -cycler==0.11.0 +cycler==0.12.0 # via matplotlib -diffusers==0.20.2 +diffusers==0.21.3 # via imaginAIry (setup.py) dill==0.3.7 # via pylint @@ -62,9 +62,9 @@ facexlib==0.3.0 # via imaginAIry (setup.py) fairscale==0.4.13 # via imaginAIry (setup.py) -fastapi==0.103.1 +fastapi==0.103.2 # via imaginAIry (setup.py) -filelock==3.12.3 +filelock==3.12.4 # via # diffusers # huggingface-hub @@ -77,7 +77,7 @@ frozenlist==1.4.0 # via # aiohttp # aiosignal -fsspec[http]==2023.9.0 +fsspec[http]==2023.9.2 # via # huggingface-hub # pytorch-lightning @@ -87,7 +87,7 @@ ftfy==6.1.1 # open-clip-torch h11==0.14.0 # via uvicorn -huggingface-hub==0.17.1 +huggingface-hub==0.17.3 # via # diffusers # open-clip-torch @@ -98,7 +98,7 @@ idna==3.4 # anyio # requests # yarl -imageio==2.31.3 +imageio==2.31.4 # via imaginAIry (setup.py) importlib-metadata==6.8.0 # via diffusers @@ -120,10 +120,12 @@ lightning-utilities==0.9.0 # via # pytorch-lightning # torchmetrics -llvmlite==0.40.1 +llvmlite==0.41.0 # via numba matplotlib==3.7.3 - # via filterpy + # via + # -c tests/constraints.txt + # filterpy mccabe==0.7.0 # via # pylama @@ -136,10 +138,11 @@ mypy-extensions==1.0.0 # via # black # typing-inspect -numba==0.57.1 +numba==0.58.0 # via facexlib numpy==1.24.4 # via + # -c tests/constraints.txt # contourpy # diffusers # facexlib @@ -159,7 +162,7 @@ omegaconf==2.3.0 # via imaginAIry (setup.py) open-clip-torch==2.20.0 # via imaginAIry (setup.py) -opencv-python==4.8.0.76 +opencv-python==4.8.1.78 # via # facexlib # imaginAIry (setup.py) @@ -178,7 +181,7 @@ pathspec==0.11.2 # via # black # pycln -pillow==10.0.0 +pillow==10.0.1 # via # diffusers # facexlib @@ -202,11 +205,11 @@ pycln==2.2.2 # via -r requirements-dev.in pycodestyle==2.11.0 # via pylama -pydantic==2.3.0 +pydantic==2.4.2 # via # fastapi # imaginAIry (setup.py) -pydantic-core==2.6.3 +pydantic-core==2.10.1 # via pydantic pydocstyle==6.3.0 # via pylama @@ -214,7 +217,7 @@ pyflakes==3.1.0 # via pylama pylama==8.4.1 # via -r requirements-dev.in -pylint==2.17.5 +pylint==2.17.6 # via -r requirements-dev.in pyparsing==3.1.1 # via matplotlib @@ -257,7 +260,7 @@ requests==2.31.0 # transformers responses==0.23.3 # via -r requirements-dev.in -ruff==0.0.288 +ruff==0.0.291 # via -r requirements-dev.in safetensors==0.3.3 # via @@ -312,7 +315,7 @@ torch==1.13.1 # torchvision torchdiffeq==0.2.3 # via imaginAIry (setup.py) -torchmetrics==1.1.2 +torchmetrics==1.2.0 # via # imaginAIry (setup.py) # pytorch-lightning @@ -330,18 +333,17 @@ tqdm==4.66.1 # open-clip-torch # pytorch-lightning # transformers -transformers==4.33.1 +transformers==4.33.3 # via imaginAIry (setup.py) typer==0.9.0 # via pycln -types-pyyaml==6.0.12.11 +types-pyyaml==6.0.12.12 # via responses -typing-extensions==4.7.1 +typing-extensions==4.8.0 # via # astroid # black # fastapi - # filelock # huggingface-hub # libcst # lightning-utilities @@ -355,13 +357,13 @@ typing-extensions==4.7.1 # uvicorn typing-inspect==0.9.0 # via libcst -urllib3==2.0.4 +urllib3==2.0.5 # via # requests # responses uvicorn==0.23.2 # via imaginAIry (setup.py) -wcwidth==0.2.6 +wcwidth==0.2.7 # via ftfy wheel==0.41.2 # via -r requirements-dev.in @@ -369,5 +371,5 @@ wrapt==1.15.0 # via astroid yarl==1.9.2 # via aiohttp -zipp==3.16.2 +zipp==3.17.0 # via importlib-metadata diff --git a/setup.py b/setup.py index ad59c31a..b7a8887d 100644 --- a/setup.py +++ b/setup.py @@ -103,9 +103,10 @@ def get_git_revision_hash() -> str: "scipy<1.11", "timm>=0.4.12,!=0.9.0,!=0.9.1", # for vendored blip "torchdiffeq>=0.2.0", - "transformers>=4.19.2", "torchmetrics>=0.6.0", "torchvision>=0.13.1", + "transformers>=4.19.2", + "triton>=2.0.0; sys_platform!='darwin' and platform_machine!='aarch64'", "kornia>=0.6", "uvicorn>=0.16.0", "xformers>=0.0.16; sys_platform!='darwin' and platform_machine!='aarch64'", diff --git a/tests/constraints.txt b/tests/constraints.txt new file mode 100644 index 00000000..ae31b21c --- /dev/null +++ b/tests/constraints.txt @@ -0,0 +1,3 @@ +# held back for python 3.8 compatability +matplotlib<3.8.0 +numpy<1.25.0 \ No newline at end of file diff --git a/tests/test_schema/test_lazy_load_image.py b/tests/test_schema/test_lazy_load_image.py index 2dd29339..23f80db2 100644 --- a/tests/test_schema/test_lazy_load_image.py +++ b/tests/test_schema/test_lazy_load_image.py @@ -101,3 +101,14 @@ def test_image_deserialization(red_path, red_url): for row in rows: obj = TestModel.model_validate(row) assert obj.header_img.size == (512, 512) + + +def test_image_state(red_path): + """I dont remember what this fixes. Maybe the ability of pydantic to copy an object?.""" + img = LazyLoadingImage(filepath=red_path) + + # bypass init + img2 = LazyLoadingImage.__new__(LazyLoadingImage) + img2.__setstate__(img.__getstate__()) + + assert repr(img) == repr(img2)