Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 46 additions & 14 deletions invokeai/app/api/routers/images.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
import io
from fastapi import HTTPException, Path, Query, Request, Response, UploadFile
from typing import Optional
from fastapi import Body, HTTPException, Path, Query, Request, Response, UploadFile
from fastapi.routing import APIRouter
from fastapi.responses import FileResponse
from PIL import Image
from invokeai.app.models.image import (
ImageCategory,
ImageType,
)
from invokeai.app.services.models.image_record import ImageDTO, ImageUrlsDTO
from invokeai.app.services.models.image_record import (
ImageDTO,
ImageRecordChanges,
ImageUrlsDTO,
)
from invokeai.app.services.item_storage import PaginatedResults

from ..dependencies import ApiDependencies
Expand All @@ -27,10 +32,17 @@
)
async def upload_image(
file: UploadFile,
image_type: ImageType,
request: Request,
response: Response,
image_category: ImageCategory = ImageCategory.GENERAL,
image_category: ImageCategory = Query(
default=ImageCategory.GENERAL, description="The category of the image"
),
is_intermediate: bool = Query(
default=False, description="Whether this is an intermediate image"
),
session_id: Optional[str] = Query(
default=None, description="The session ID associated with this upload, if any"
),
) -> ImageDTO:
"""Uploads an image"""
if not file.content_type.startswith("image"):
Expand All @@ -46,9 +58,11 @@ async def upload_image(

try:
image_dto = ApiDependencies.invoker.services.images.create(
pil_image,
image_type,
image_category,
image=pil_image,
image_type=ImageType.UPLOAD,
image_category=image_category,
session_id=session_id,
is_intermediate=is_intermediate,
)

response.status_code = 201
Expand All @@ -61,7 +75,7 @@ async def upload_image(

@images_router.delete("/{image_type}/{image_name}", operation_id="delete_image")
async def delete_image(
image_type: ImageType = Query(description="The type of image to delete"),
image_type: ImageType = Path(description="The type of image to delete"),
image_name: str = Path(description="The name of the image to delete"),
) -> None:
"""Deletes an image"""
Expand All @@ -73,6 +87,28 @@ async def delete_image(
pass


@images_router.patch(
"/{image_type}/{image_name}",
operation_id="update_image",
response_model=ImageDTO,
)
async def update_image(
image_type: ImageType = Path(description="The type of image to update"),
image_name: str = Path(description="The name of the image to update"),
image_changes: ImageRecordChanges = Body(
description="The changes to apply to the image"
),
) -> ImageDTO:
"""Updates an image"""

try:
return ApiDependencies.invoker.services.images.update(
image_type, image_name, image_changes
)
except Exception as e:
raise HTTPException(status_code=400, detail="Failed to update image")


@images_router.get(
"/{image_type}/{image_name}/metadata",
operation_id="get_image_metadata",
Expand All @@ -85,9 +121,7 @@ async def get_image_metadata(
"""Gets an image's metadata"""

try:
return ApiDependencies.invoker.services.images.get_dto(
image_type, image_name
)
return ApiDependencies.invoker.services.images.get_dto(image_type, image_name)
except Exception as e:
raise HTTPException(status_code=404)

Expand All @@ -113,9 +147,7 @@ async def get_image_full(
"""Gets a full-resolution image file"""

try:
path = ApiDependencies.invoker.services.images.get_path(
image_type, image_name
)
path = ApiDependencies.invoker.services.images.get_path(image_type, image_name)

if not ApiDependencies.invoker.services.images.validate_path(path):
raise HTTPException(status_code=404)
Expand Down
1 change: 1 addition & 0 deletions invokeai/app/invocations/baseinvocation.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ def invoke(self, context: InvocationContext) -> BaseInvocationOutput:

#fmt: off
id: str = Field(description="The id of this node. Must be unique among all nodes.")
is_intermediate: bool = Field(default=False, description="Whether or not this node is an intermediate node.")
#fmt: on


Expand Down
3 changes: 2 additions & 1 deletion invokeai/app/invocations/cv.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,11 @@ def invoke(self, context: InvocationContext) -> ImageOutput:

image_dto = context.services.images.create(
image=image_inpainted,
image_type=ImageType.INTERMEDIATE,
image_type=ImageType.RESULT,
image_category=ImageCategory.GENERAL,
node_id=self.id,
session_id=context.graph_execution_state_id,
is_intermediate=self.is_intermediate,
)

return ImageOutput(
Expand Down
3 changes: 3 additions & 0 deletions invokeai/app/invocations/generate.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ def invoke(self, context: InvocationContext) -> ImageOutput:
image_category=ImageCategory.GENERAL,
session_id=context.graph_execution_state_id,
node_id=self.id,
is_intermediate=self.is_intermediate,
)

return ImageOutput(
Expand Down Expand Up @@ -181,6 +182,7 @@ def invoke(self, context: InvocationContext) -> ImageOutput:
image_category=ImageCategory.GENERAL,
session_id=context.graph_execution_state_id,
node_id=self.id,
is_intermediate=self.is_intermediate,
)

return ImageOutput(
Expand Down Expand Up @@ -296,6 +298,7 @@ def invoke(self, context: InvocationContext) -> ImageOutput:
image_category=ImageCategory.GENERAL,
session_id=context.graph_execution_state_id,
node_id=self.id,
is_intermediate=self.is_intermediate,
)

return ImageOutput(
Expand Down
9 changes: 9 additions & 0 deletions invokeai/app/invocations/image.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ def invoke(self, context: InvocationContext) -> ImageOutput:
image_category=ImageCategory.GENERAL,
node_id=self.id,
session_id=context.graph_execution_state_id,
is_intermediate=self.is_intermediate,
)

return ImageOutput(
Expand Down Expand Up @@ -204,6 +205,7 @@ def invoke(self, context: InvocationContext) -> ImageOutput:
image_category=ImageCategory.GENERAL,
node_id=self.id,
session_id=context.graph_execution_state_id,
is_intermediate=self.is_intermediate,
)

return ImageOutput(
Expand Down Expand Up @@ -242,6 +244,7 @@ def invoke(self, context: InvocationContext) -> MaskOutput:
image_category=ImageCategory.MASK,
node_id=self.id,
session_id=context.graph_execution_state_id,
is_intermediate=self.is_intermediate,
)

return MaskOutput(
Expand Down Expand Up @@ -280,6 +283,7 @@ def invoke(self, context: InvocationContext) -> ImageOutput:
image_category=ImageCategory.GENERAL,
node_id=self.id,
session_id=context.graph_execution_state_id,
is_intermediate=self.is_intermediate,
)

return ImageOutput(
Expand Down Expand Up @@ -318,6 +322,7 @@ def invoke(self, context: InvocationContext) -> ImageOutput:
image_category=ImageCategory.GENERAL,
node_id=self.id,
session_id=context.graph_execution_state_id,
is_intermediate=self.is_intermediate,
)

return ImageOutput(
Expand Down Expand Up @@ -356,6 +361,7 @@ def invoke(self, context: InvocationContext) -> ImageOutput:
image_category=ImageCategory.GENERAL,
node_id=self.id,
session_id=context.graph_execution_state_id,
is_intermediate=self.is_intermediate,
)

return ImageOutput(
Expand Down Expand Up @@ -397,6 +403,7 @@ def invoke(self, context: InvocationContext) -> ImageOutput:
image_category=ImageCategory.GENERAL,
node_id=self.id,
session_id=context.graph_execution_state_id,
is_intermediate=self.is_intermediate,
)

return ImageOutput(
Expand Down Expand Up @@ -437,6 +444,7 @@ def invoke(self, context: InvocationContext) -> ImageOutput:
image_category=ImageCategory.GENERAL,
node_id=self.id,
session_id=context.graph_execution_state_id,
is_intermediate=self.is_intermediate,
)

return ImageOutput(
Expand Down Expand Up @@ -482,6 +490,7 @@ def invoke(self, context: InvocationContext) -> ImageOutput:
image_category=ImageCategory.GENERAL,
node_id=self.id,
session_id=context.graph_execution_state_id,
is_intermediate=self.is_intermediate,
)

return ImageOutput(
Expand Down
3 changes: 3 additions & 0 deletions invokeai/app/invocations/infill.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ def invoke(self, context: InvocationContext) -> ImageOutput:
image_category=ImageCategory.GENERAL,
node_id=self.id,
session_id=context.graph_execution_state_id,
is_intermediate=self.is_intermediate,
)

return ImageOutput(
Expand Down Expand Up @@ -193,6 +194,7 @@ def invoke(self, context: InvocationContext) -> ImageOutput:
image_category=ImageCategory.GENERAL,
node_id=self.id,
session_id=context.graph_execution_state_id,
is_intermediate=self.is_intermediate,
)

return ImageOutput(
Expand Down Expand Up @@ -230,6 +232,7 @@ def invoke(self, context: InvocationContext) -> ImageOutput:
image_category=ImageCategory.GENERAL,
node_id=self.id,
session_id=context.graph_execution_state_id,
is_intermediate=self.is_intermediate,
)

return ImageOutput(
Expand Down
1 change: 1 addition & 0 deletions invokeai/app/invocations/latent.py
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,7 @@ def invoke(self, context: InvocationContext) -> ImageOutput:
image_category=ImageCategory.GENERAL,
session_id=context.graph_execution_state_id,
node_id=self.id,
is_intermediate=self.is_intermediate
)

return ImageOutput(
Expand Down
3 changes: 2 additions & 1 deletion invokeai/app/invocations/reconstruct.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,11 @@ def invoke(self, context: InvocationContext) -> ImageOutput:
# TODO: can this return multiple results?
image_dto = context.services.images.create(
image=results[0][0],
image_type=ImageType.INTERMEDIATE,
image_type=ImageType.RESULT,
image_category=ImageCategory.GENERAL,
node_id=self.id,
session_id=context.graph_execution_state_id,
is_intermediate=self.is_intermediate,
)

return ImageOutput(
Expand Down
1 change: 1 addition & 0 deletions invokeai/app/invocations/upscale.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ def invoke(self, context: InvocationContext) -> ImageOutput:
image_category=ImageCategory.GENERAL,
node_id=self.id,
session_id=context.graph_execution_state_id,
is_intermediate=self.is_intermediate,
)

return ImageOutput(
Expand Down
1 change: 0 additions & 1 deletion invokeai/app/models/image.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ class ImageType(str, Enum, metaclass=MetaEnum):

RESULT = "results"
UPLOAD = "uploads"
INTERMEDIATE = "intermediates"


class InvalidImageTypeException(ValueError):
Expand Down
Loading