Has anyone had success getting `Shape` validation ...
# ask-for-help
a
Has anyone had success getting
Shape
validation to work with
numpy
? I’m trying this example, but with an
np.ndarray
instead of
torch.Tensor
, and I’m getting an error:
Copy code
IndexError: list assignment index out of range
Works fine if I remove the
Shape
restriction inside
Annotated
.
👀 1
🎉 1
@Sean Here is an example:
Copy code
from typing import Annotated
from pydantic import Field

import bentoml
from bentoml.validators import Shape, DType
import numpy as np


@bentoml.service
class ModelService:

    def __init__(self):
        self.model = ""

    @bentoml.api
    def predict(
            self,
            input_arr: Annotated[
                np.ndarray,
                # Shape((-1, 2)), # <-- this doesn't work
                DType("float32")
            ] = Field(description="A (-1, 2)-shaped np.ndarray")
    ) -> np.ndarray:
        return input_arr
👀 1
Also seems like it does not work with
torch.Tensor
? I’m using
bentoml==1.2.12
.
I believe this fixes the issue:
Copy code
diff --git a/src/_bentoml_sdk/_pydantic.py b/src/_bentoml_sdk/_pydantic.py
index ae4e49d5..987b0358 100644
--- a/src/_bentoml_sdk/_pydantic.py
+++ b/src/_bentoml_sdk/_pydantic.py
@@ -53,13 +53,13 @@ def numpy_prepare_pydantic_annotations(
     _, remaining_annotations = _known_annotated_metadata.collect_known_metadata(
         annotations
     )
-    for i, annotation in enumerate(remaining_annotations[:]):
+    for annotation in remaining_annotations[:]:
         if isinstance(annotation, Shape):
             shape = annotation.dimensions
-            del remaining_annotations[i]
+            remaining_annotations.remove(annotation)
         elif isinstance(annotation, DType):
             dtype = annotation.dtype
-            del remaining_annotations[i]
+            remaining_annotations.remove(annotation)
     return source, [TensorSchema("numpy-array", dtype, shape), *remaining_annotations]
 
 
@@ -80,13 +80,13 @@ def torch_prepare_pydantic_annotations(
     _, remaining_annotations = _known_annotated_metadata.collect_known_metadata(
         annotations
     )
-    for i, annotation in enumerate(remaining_annotations[:]):
+    for annotation in remaining_annotations[:]:
         if isinstance(annotation, Shape):
             shape = annotation.dimensions
-            del remaining_annotations[i]
+            remaining_annotations.remove(annotation)
         elif isinstance(annotation, DType):
             dtype = annotation.dtype
-            del remaining_annotations[i]
+            remaining_annotations.remove(annotation)
     return source, [TensorSchema("torch-tensor", dtype, shape), *remaining_annotations]
 
 
@@ -106,13 +106,13 @@ def tf_prepare_pydantic_annotations(
     _, remaining_annotations = _known_annotated_metadata.collect_known_metadata(
         annotations
     )
-    for i, annotation in enumerate(remaining_annotations[:]):
+    for annotation in remaining_annotations[:]:
         if isinstance(annotation, Shape):
             shape = annotation.dimensions
-            del remaining_annotations[i]
+            remaining_annotations.remove(annotation)
         elif isinstance(annotation, DType):
             dtype = annotation.dtype
-            del remaining_annotations[i]
+            remaining_annotations.remove(annotation)
     return source, [TensorSchema("tf-tensor", dtype, shape), *remaining_annotations]
 
 
@@ -169,10 +169,10 @@ def pathlib_prepare_pydantic_annotations(
         annotations
     )
     content_type: str | None = None
-    for i, annotation in enumerate(remaining_annotations[:]):
+    for annotation in remaining_annotations[:]:
         if isinstance(annotation, ContentType):
             content_type = annotation.content_type
-            del remaining_annotations[i]
+            remaining_annotations.annotation(remove)
     return source, [FileSchema(content_type=content_type), *remaining_annotations]
Opened a draft PR but need to step away for the rest of the day. Haven’t thoroughly tested it, and there might be better approaches. Feel free to build on top of the PR if you have time, otherwise I can pick it up again tomorrow or this weekend. The issue is deleting from a list with indices from a copy of that list.
s
Thanks for the PR, @Adam Liter. I will investigate the problem and review the PR today.
I was able to reproduce and looks like we have a bug in supporting multiple validators. We will work with you on the PR and publish a new version before earlier next week.
gratitude thank you 1
👍 1
a
Thanks Sean. I updated the PR with a fix that passes the lint checks from
ruff
and verified it’s working. Also fixed a related typo in the docs. Happy to update the PR further though with any additional feedback you might have.
s
This is great! Thanks, Adam. We’ll work with you on the PR and publish a new version early next week.
👍 1
Thanks for the PR, @Adam Liter. It has been merged and released in the latest version BentoML,
v1.2.13
. 🎉
gratitude thank you 1
a
Thanks for the quick turnaround on this!
👏 1