feat(api): add order_by and order_dir to list images for sorting

This commit is contained in:
maryhipp 2024-06-27 12:21:23 -04:00 committed by psychedelicious
parent 6109a06f04
commit f268fe126e
6 changed files with 47 additions and 5 deletions

View File

@ -9,9 +9,15 @@ from PIL import Image
from pydantic import BaseModel, Field, JsonValue from pydantic import BaseModel, Field, JsonValue
from invokeai.app.invocations.fields import MetadataField from invokeai.app.invocations.fields import MetadataField
from invokeai.app.services.image_records.image_records_common import ImageCategory, ImageRecordChanges, ResourceOrigin from invokeai.app.services.image_records.image_records_common import (
ImageCategory,
ImageRecordChanges,
OrderByOptions,
ResourceOrigin,
)
from invokeai.app.services.images.images_common import ImageDTO, ImageUrlsDTO from invokeai.app.services.images.images_common import ImageDTO, ImageUrlsDTO
from invokeai.app.services.shared.pagination import OffsetPaginatedResults from invokeai.app.services.shared.pagination import OffsetPaginatedResults
from invokeai.app.services.shared.sqlite.sqlite_common import SQLiteDirection
from ..dependencies import ApiDependencies from ..dependencies import ApiDependencies
@ -316,12 +322,16 @@ async def list_image_dtos(
), ),
offset: int = Query(default=0, description="The page offset"), offset: int = Query(default=0, description="The page offset"),
limit: int = Query(default=10, description="The number of images per page"), limit: int = Query(default=10, description="The number of images per page"),
order_by: OrderByOptions = Query(default=OrderByOptions.CREATED_AT, description="The way to sort the images"),
order_dir: SQLiteDirection = Query(default=SQLiteDirection.Descending, description="The order of sort"),
) -> OffsetPaginatedResults[ImageDTO]: ) -> OffsetPaginatedResults[ImageDTO]:
"""Gets a list of image DTOs""" """Gets a list of image DTOs"""
image_dtos = ApiDependencies.invoker.services.images.get_many( image_dtos = ApiDependencies.invoker.services.images.get_many(
offset, offset,
limit, limit,
order_by,
order_dir,
image_origin, image_origin,
categories, categories,
is_intermediate, is_intermediate,

View File

@ -4,8 +4,9 @@ from typing import Optional
from invokeai.app.invocations.fields import MetadataField from invokeai.app.invocations.fields import MetadataField
from invokeai.app.services.shared.pagination import OffsetPaginatedResults from invokeai.app.services.shared.pagination import OffsetPaginatedResults
from invokeai.app.services.shared.sqlite.sqlite_common import SQLiteDirection
from .image_records_common import ImageCategory, ImageRecord, ImageRecordChanges, ResourceOrigin from .image_records_common import ImageCategory, ImageRecord, ImageRecordChanges, OrderByOptions, ResourceOrigin
class ImageRecordStorageBase(ABC): class ImageRecordStorageBase(ABC):
@ -37,6 +38,8 @@ class ImageRecordStorageBase(ABC):
self, self,
offset: int = 0, offset: int = 0,
limit: int = 10, limit: int = 10,
order_by: OrderByOptions = OrderByOptions.CREATED_AT,
order_dir: SQLiteDirection = SQLiteDirection.Descending,
image_origin: Optional[ResourceOrigin] = None, image_origin: Optional[ResourceOrigin] = None,
categories: Optional[list[ImageCategory]] = None, categories: Optional[list[ImageCategory]] = None,
is_intermediate: Optional[bool] = None, is_intermediate: Optional[bool] = None,

View File

@ -207,3 +207,13 @@ def deserialize_image_record(image_dict: dict) -> ImageRecord:
starred=starred, starred=starred,
has_workflow=has_workflow, has_workflow=has_workflow,
) )
class OrderByOptions(str, Enum, metaclass=MetaEnum):
"""Options for image ordering
- `created_at`: order by created_at date
- `starred`: order by starred and then created_at
"""
CREATED_AT = "created_at"
STARRED = "starred"

View File

@ -5,6 +5,7 @@ from typing import Optional, Union, cast
from invokeai.app.invocations.fields import MetadataField, MetadataFieldValidator from invokeai.app.invocations.fields import MetadataField, MetadataFieldValidator
from invokeai.app.services.shared.pagination import OffsetPaginatedResults from invokeai.app.services.shared.pagination import OffsetPaginatedResults
from invokeai.app.services.shared.sqlite.sqlite_common import SQLiteDirection
from invokeai.app.services.shared.sqlite.sqlite_database import SqliteDatabase from invokeai.app.services.shared.sqlite.sqlite_database import SqliteDatabase
from .image_records_base import ImageRecordStorageBase from .image_records_base import ImageRecordStorageBase
@ -16,6 +17,7 @@ from .image_records_common import (
ImageRecordDeleteException, ImageRecordDeleteException,
ImageRecordNotFoundException, ImageRecordNotFoundException,
ImageRecordSaveException, ImageRecordSaveException,
OrderByOptions,
ResourceOrigin, ResourceOrigin,
deserialize_image_record, deserialize_image_record,
) )
@ -144,6 +146,8 @@ class SqliteImageRecordStorage(ImageRecordStorageBase):
self, self,
offset: int = 0, offset: int = 0,
limit: int = 10, limit: int = 10,
order_by: OrderByOptions = OrderByOptions.CREATED_AT,
order_dir: SQLiteDirection = SQLiteDirection.Descending,
image_origin: Optional[ResourceOrigin] = None, image_origin: Optional[ResourceOrigin] = None,
categories: Optional[list[ImageCategory]] = None, categories: Optional[list[ImageCategory]] = None,
is_intermediate: Optional[bool] = None, is_intermediate: Optional[bool] = None,
@ -208,9 +212,14 @@ class SqliteImageRecordStorage(ImageRecordStorageBase):
""" """
query_params.append(board_id) query_params.append(board_id)
query_pagination = """--sql if order_by == OrderByOptions.STARRED:
ORDER BY images.starred DESC, images.created_at DESC LIMIT ? OFFSET ? query_pagination = f"""--sql
""" ORDER BY images.starred {order_dir}, images.created_at {order_dir} LIMIT ? OFFSET ?
"""
else:
query_pagination = f"""--sql
ORDER BY images.created_at {order_dir} LIMIT ? OFFSET ?
"""
# Final images query with pagination # Final images query with pagination
images_query += query_conditions + query_pagination + ";" images_query += query_conditions + query_pagination + ";"

View File

@ -8,10 +8,12 @@ from invokeai.app.services.image_records.image_records_common import (
ImageCategory, ImageCategory,
ImageRecord, ImageRecord,
ImageRecordChanges, ImageRecordChanges,
OrderByOptions,
ResourceOrigin, ResourceOrigin,
) )
from invokeai.app.services.images.images_common import ImageDTO from invokeai.app.services.images.images_common import ImageDTO
from invokeai.app.services.shared.pagination import OffsetPaginatedResults from invokeai.app.services.shared.pagination import OffsetPaginatedResults
from invokeai.app.services.shared.sqlite.sqlite_common import SQLiteDirection
class ImageServiceABC(ABC): class ImageServiceABC(ABC):
@ -116,6 +118,8 @@ class ImageServiceABC(ABC):
self, self,
offset: int = 0, offset: int = 0,
limit: int = 10, limit: int = 10,
order_by: OrderByOptions = OrderByOptions.CREATED_AT,
order_dir: SQLiteDirection = SQLiteDirection.Descending,
image_origin: Optional[ResourceOrigin] = None, image_origin: Optional[ResourceOrigin] = None,
categories: Optional[list[ImageCategory]] = None, categories: Optional[list[ImageCategory]] = None,
is_intermediate: Optional[bool] = None, is_intermediate: Optional[bool] = None,

View File

@ -5,6 +5,7 @@ from PIL.Image import Image as PILImageType
from invokeai.app.invocations.fields import MetadataField from invokeai.app.invocations.fields import MetadataField
from invokeai.app.services.invoker import Invoker from invokeai.app.services.invoker import Invoker
from invokeai.app.services.shared.pagination import OffsetPaginatedResults from invokeai.app.services.shared.pagination import OffsetPaginatedResults
from invokeai.app.services.shared.sqlite.sqlite_common import SQLiteDirection
from ..image_files.image_files_common import ( from ..image_files.image_files_common import (
ImageFileDeleteException, ImageFileDeleteException,
@ -20,6 +21,7 @@ from ..image_records.image_records_common import (
ImageRecordSaveException, ImageRecordSaveException,
InvalidImageCategoryException, InvalidImageCategoryException,
InvalidOriginException, InvalidOriginException,
OrderByOptions,
ResourceOrigin, ResourceOrigin,
) )
from .images_base import ImageServiceABC from .images_base import ImageServiceABC
@ -207,6 +209,8 @@ class ImageService(ImageServiceABC):
self, self,
offset: int = 0, offset: int = 0,
limit: int = 10, limit: int = 10,
order_by: OrderByOptions = OrderByOptions.CREATED_AT,
order_dir: SQLiteDirection = SQLiteDirection.Descending,
image_origin: Optional[ResourceOrigin] = None, image_origin: Optional[ResourceOrigin] = None,
categories: Optional[list[ImageCategory]] = None, categories: Optional[list[ImageCategory]] = None,
is_intermediate: Optional[bool] = None, is_intermediate: Optional[bool] = None,
@ -216,6 +220,8 @@ class ImageService(ImageServiceABC):
results = self.__invoker.services.image_records.get_many( results = self.__invoker.services.image_records.get_many(
offset, offset,
limit, limit,
order_by,
order_dir,
image_origin, image_origin,
categories, categories,
is_intermediate, is_intermediate,