mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
feat(nodes): consolidate image routers
This commit is contained in:
parent
11bd932cba
commit
b9375186a5
@ -1,47 +0,0 @@
|
||||
# Copyright (c) 2022 Kyle Schouviller (https://github.com/kyle0654) and the InvokeAI Team
|
||||
from fastapi import HTTPException, Path
|
||||
from fastapi.responses import FileResponse
|
||||
from fastapi.routing import APIRouter
|
||||
from invokeai.app.models.image import ImageType
|
||||
|
||||
from ..dependencies import ApiDependencies
|
||||
|
||||
image_files_router = APIRouter(prefix="/v1/files/images", tags=["images", "files"])
|
||||
|
||||
|
||||
@image_files_router.get("/{image_type}/{image_name}", operation_id="get_image")
|
||||
async def get_image(
|
||||
image_type: ImageType = Path(description="The type of the image to get"),
|
||||
image_name: str = Path(description="The id of the image to get"),
|
||||
) -> FileResponse:
|
||||
"""Gets an image"""
|
||||
|
||||
try:
|
||||
path = ApiDependencies.invoker.services.images_new.get_path(
|
||||
image_type=image_type, image_name=image_name
|
||||
)
|
||||
|
||||
return FileResponse(path)
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=404)
|
||||
|
||||
|
||||
@image_files_router.get(
|
||||
"/{image_type}/{image_name}/thumbnail", operation_id="get_thumbnail"
|
||||
)
|
||||
async def get_thumbnail(
|
||||
image_type: ImageType = Path(
|
||||
description="The type of the image whose thumbnail to get"
|
||||
),
|
||||
image_name: str = Path(description="The id of the image whose thumbnail to get"),
|
||||
) -> FileResponse:
|
||||
"""Gets a thumbnail"""
|
||||
|
||||
try:
|
||||
path = ApiDependencies.invoker.services.images_new.get_path(
|
||||
image_type=image_type, image_name=image_name, thumbnail=True
|
||||
)
|
||||
|
||||
return FileResponse(path)
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=404)
|
@ -1,71 +0,0 @@
|
||||
from fastapi import HTTPException, Path, Query
|
||||
from fastapi.routing import APIRouter
|
||||
from invokeai.app.models.image import (
|
||||
ImageCategory,
|
||||
ImageType,
|
||||
)
|
||||
from invokeai.app.services.item_storage import PaginatedResults
|
||||
from invokeai.app.services.models.image_record import ImageDTO
|
||||
|
||||
from ..dependencies import ApiDependencies
|
||||
|
||||
image_records_router = APIRouter(
|
||||
prefix="/v1/images/records", tags=["images", "records"]
|
||||
)
|
||||
|
||||
|
||||
@image_records_router.get("/{image_type}/{image_name}", operation_id="get_image_record")
|
||||
async def get_image_record(
|
||||
image_type: ImageType = Path(description="The type of the image record to get"),
|
||||
image_name: str = Path(description="The id of the image record to get"),
|
||||
) -> ImageDTO:
|
||||
"""Gets an image record by id"""
|
||||
|
||||
try:
|
||||
return ApiDependencies.invoker.services.images_new.get_dto(
|
||||
image_type=image_type, image_name=image_name
|
||||
)
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=404)
|
||||
|
||||
|
||||
@image_records_router.get(
|
||||
"/",
|
||||
operation_id="list_image_records",
|
||||
)
|
||||
async def list_image_records(
|
||||
image_type: ImageType = Query(description="The type of image records to get"),
|
||||
image_category: ImageCategory = Query(
|
||||
description="The kind of image records to get"
|
||||
),
|
||||
page: int = Query(default=0, description="The page of image records to get"),
|
||||
per_page: int = Query(
|
||||
default=10, description="The number of image records per page"
|
||||
),
|
||||
) -> PaginatedResults[ImageDTO]:
|
||||
"""Gets a list of image records by type and category"""
|
||||
|
||||
image_dtos = ApiDependencies.invoker.services.images_new.get_many(
|
||||
image_type=image_type,
|
||||
image_category=image_category,
|
||||
page=page,
|
||||
per_page=per_page,
|
||||
)
|
||||
|
||||
return image_dtos
|
||||
|
||||
|
||||
@image_records_router.delete("/{image_type}/{image_name}", operation_id="delete_image")
|
||||
async def delete_image_record(
|
||||
image_type: ImageType = Query(description="The type of image to delete"),
|
||||
image_name: str = Path(description="The name of the image to delete"),
|
||||
) -> None:
|
||||
"""Deletes an image record"""
|
||||
|
||||
try:
|
||||
ApiDependencies.invoker.services.images_new.delete(
|
||||
image_type=image_type, image_name=image_name
|
||||
)
|
||||
except Exception as e:
|
||||
# TODO: Does this need any exception handling at all?
|
||||
pass
|
@ -1,15 +1,13 @@
|
||||
import io
|
||||
import uuid
|
||||
from fastapi import 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.image_record_storage import ImageRecordStorageBase
|
||||
from invokeai.app.services.image_file_storage import ImageFileStorageBase
|
||||
from invokeai.app.services.models.image_record import ImageRecord
|
||||
from invokeai.app.services.models.image_record import ImageDTO, ImageUrlsDTO
|
||||
from invokeai.app.services.item_storage import PaginatedResults
|
||||
|
||||
from ..dependencies import ApiDependencies
|
||||
@ -32,7 +30,7 @@ async def upload_image(
|
||||
request: Request,
|
||||
response: Response,
|
||||
image_category: ImageCategory = ImageCategory.IMAGE,
|
||||
) -> ImageRecord:
|
||||
) -> ImageDTO:
|
||||
"""Uploads an image"""
|
||||
if not file.content_type.startswith("image"):
|
||||
raise HTTPException(status_code=415, detail="Not an image")
|
||||
@ -40,38 +38,145 @@ async def upload_image(
|
||||
contents = await file.read()
|
||||
|
||||
try:
|
||||
img = Image.open(io.BytesIO(contents))
|
||||
pil_image = Image.open(io.BytesIO(contents))
|
||||
except:
|
||||
# Error opening the image
|
||||
raise HTTPException(status_code=415, detail="Failed to read image")
|
||||
|
||||
try:
|
||||
image_record = ApiDependencies.invoker.services.images_new.create(
|
||||
image=img,
|
||||
image_type=image_type,
|
||||
image_category=image_category,
|
||||
image_dto = ApiDependencies.invoker.services.images_new.create(
|
||||
pil_image,
|
||||
image_type,
|
||||
image_category,
|
||||
)
|
||||
|
||||
response.status_code = 201
|
||||
response.headers["Location"] = image_record.image_url
|
||||
response.headers["Location"] = image_dto.image_url
|
||||
|
||||
return image_record
|
||||
return image_dto
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=500)
|
||||
|
||||
raise HTTPException(status_code=500, detail="Failed to create image")
|
||||
|
||||
|
||||
@images_router.delete("/{image_type}/{image_name}", operation_id="delete_image")
|
||||
async def delete_image_record(
|
||||
async def delete_image(
|
||||
image_type: ImageType = Query(description="The type of image to delete"),
|
||||
image_name: str = Path(description="The name of the image to delete"),
|
||||
) -> None:
|
||||
"""Deletes an image record"""
|
||||
"""Deletes an image"""
|
||||
|
||||
try:
|
||||
ApiDependencies.invoker.services.images_new.delete(
|
||||
image_type=image_type, image_name=image_name
|
||||
)
|
||||
ApiDependencies.invoker.services.images_new.delete(image_type, image_name)
|
||||
except Exception as e:
|
||||
# TODO: Does this need any exception handling at all?
|
||||
pass
|
||||
|
||||
|
||||
@images_router.get(
|
||||
"/{image_type}/{image_name}/record",
|
||||
operation_id="get_image_record",
|
||||
response_model=ImageDTO,
|
||||
)
|
||||
async def get_image_record(
|
||||
image_type: ImageType = Path(description="The type of the image record to get"),
|
||||
image_name: str = Path(description="The id of the image record to get"),
|
||||
) -> ImageDTO:
|
||||
"""Gets an image record by id"""
|
||||
|
||||
try:
|
||||
return ApiDependencies.invoker.services.images_new.get_dto(
|
||||
image_type, image_name
|
||||
)
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=404)
|
||||
|
||||
|
||||
@images_router.get("/{image_type}/{image_name}/image", operation_id="get_image")
|
||||
async def get_image(
|
||||
image_type: ImageType = Path(description="The type of the image to get"),
|
||||
image_name: str = Path(description="The id of the image to get"),
|
||||
) -> FileResponse:
|
||||
"""Gets an image"""
|
||||
|
||||
try:
|
||||
path = ApiDependencies.invoker.services.images_new.get_path(
|
||||
image_type, image_name
|
||||
)
|
||||
|
||||
return FileResponse(path)
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=404)
|
||||
|
||||
|
||||
@images_router.get("/{image_type}/{image_name}/thumbnail", operation_id="get_thumbnail")
|
||||
async def get_thumbnail(
|
||||
image_type: ImageType = Path(
|
||||
description="The type of the image whose thumbnail to get"
|
||||
),
|
||||
image_name: str = Path(description="The id of the image whose thumbnail to get"),
|
||||
) -> FileResponse:
|
||||
"""Gets a thumbnail"""
|
||||
|
||||
try:
|
||||
path = ApiDependencies.invoker.services.images_new.get_path(
|
||||
image_type, image_name, thumbnail=True
|
||||
)
|
||||
|
||||
return FileResponse(path)
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=404)
|
||||
|
||||
|
||||
@images_router.get(
|
||||
"/{image_type}/{image_name}/urls",
|
||||
operation_id="get_image_urls",
|
||||
response_model=ImageUrlsDTO,
|
||||
)
|
||||
async def get_image_urls(
|
||||
image_type: ImageType = Path(description="The type of the image whose URL to get"),
|
||||
image_name: str = Path(description="The id of the image whose URL to get"),
|
||||
) -> ImageUrlsDTO:
|
||||
"""Gets an image and thumbnail URL"""
|
||||
|
||||
try:
|
||||
image_url = ApiDependencies.invoker.services.images_new.get_url(
|
||||
image_type, image_name
|
||||
)
|
||||
thumbnail_url = ApiDependencies.invoker.services.images_new.get_url(
|
||||
image_type, image_name, thumbnail=True
|
||||
)
|
||||
return ImageUrlsDTO(
|
||||
image_type=image_type,
|
||||
image_name=image_name,
|
||||
image_url=image_url,
|
||||
thumbnail_url=thumbnail_url,
|
||||
)
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=404)
|
||||
|
||||
|
||||
@images_router.get(
|
||||
"/",
|
||||
operation_id="list_image_records",
|
||||
response_model=PaginatedResults[ImageDTO],
|
||||
)
|
||||
async def list_image_records(
|
||||
image_type: ImageType = Query(description="The type of image records to get"),
|
||||
image_category: ImageCategory = Query(
|
||||
description="The kind of image records to get"
|
||||
),
|
||||
page: int = Query(default=0, description="The page of image records to get"),
|
||||
per_page: int = Query(
|
||||
default=10, description="The number of image records per page"
|
||||
),
|
||||
) -> PaginatedResults[ImageDTO]:
|
||||
"""Gets a list of image records by type and category"""
|
||||
|
||||
image_dtos = ApiDependencies.invoker.services.images_new.get_many(
|
||||
image_type,
|
||||
image_category,
|
||||
page,
|
||||
per_page,
|
||||
)
|
||||
|
||||
return image_dtos
|
||||
|
@ -15,7 +15,7 @@ from fastapi_events.middleware import EventHandlerASGIMiddleware
|
||||
from pydantic.schema import schema
|
||||
|
||||
from .api.dependencies import ApiDependencies
|
||||
from .api.routers import image_files, image_records, sessions, models, images
|
||||
from .api.routers import sessions, models, images
|
||||
from .api.sockets import SocketIO
|
||||
from .invocations.baseinvocation import BaseInvocation
|
||||
from .services.config import InvokeAIAppConfig
|
||||
@ -73,10 +73,6 @@ app.include_router(sessions.session_router, prefix="/api")
|
||||
|
||||
app.include_router(models.models_router, prefix="/api")
|
||||
|
||||
app.include_router(image_files.image_files_router, prefix="/api")
|
||||
|
||||
app.include_router(image_records.image_records_router, prefix="/api")
|
||||
|
||||
app.include_router(images.images_router, prefix="/api")
|
||||
|
||||
# Build a custom OpenAPI to include all outputs
|
||||
|
@ -23,13 +23,21 @@ class ImageRecord(BaseModel):
|
||||
)
|
||||
|
||||
|
||||
class ImageDTO(ImageRecord):
|
||||
"""Deserialized image record with URLs."""
|
||||
class ImageUrlsDTO(BaseModel):
|
||||
"""The URLs for an image and its thumbnaill"""
|
||||
|
||||
image_name: str = Field(description="The name of the image.")
|
||||
image_type: ImageType = Field(description="The type of the image.")
|
||||
image_url: str = Field(description="The URL of the image.")
|
||||
thumbnail_url: str = Field(description="The thumbnail URL of the image.")
|
||||
|
||||
|
||||
class ImageDTO(ImageRecord, ImageUrlsDTO):
|
||||
"""Deserialized image record with URLs."""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
def image_record_to_dto(
|
||||
image_record: ImageRecord, image_url: str, thumbnail_url: str
|
||||
) -> ImageDTO:
|
||||
|
@ -25,6 +25,6 @@ class LocalUrlService(UrlServiceBase):
|
||||
) -> str:
|
||||
image_basename = os.path.basename(image_name)
|
||||
if thumbnail:
|
||||
return f"{self._base_url}/files/images/{image_type.value}/{image_basename}/thumbnail"
|
||||
return f"{self._base_url}/images/{image_type.value}/{image_basename}/thumbnail"
|
||||
|
||||
return f"{self._base_url}/files/images/{image_type.value}/{image_basename}"
|
||||
return f"{self._base_url}/images/{image_type.value}/{image_basename}/image"
|
||||
|
Loading…
Reference in New Issue
Block a user