class_docstr: :obj:`Image` defines API specification for the inputs/outputs of a Service, where either
  inputs will be converted to or outputs will be converted from images as specified
  in your API function signature.
  
  A sample object detection service:
  
  .. code-block:: python
     :caption: `service.py`
  
     from __future__ import annotations
  
     from typing import TYPE_CHECKING
     from typing import Any
  
     import bentoml
     from bentoml.io import Image
     from bentoml.io import NumpyNdarray
  
     if TYPE_CHECKING:
         from PIL.Image import Image
         from numpy.typing import NDArray
  
     runner = bentoml.tensorflow.get('image-classification:latest').to_runner()
  
     svc = bentoml.Service("vit-object-detection", runners=[runner])
  
     @svc.api(input=Image(), output=NumpyNdarray(dtype="float32"))
     async def predict_image(f: Image) -> NDArray[Any]:
         assert isinstance(f, Image)
         arr = np.array(f) / 255.0
         assert arr.shape == (28, 28)
  
         # We are using greyscale image and our PyTorch model expect one
         # extra channel dimension
         arr = np.expand_dims(arr, (0, 3)).astype("float32")  # reshape to [1, 28, 28, 1]
         return await runner.async_run(arr)
  
  Users then can then serve this service with :code:`bentoml serve`:
  
  .. code-block:: bash
  
      % bentoml serve ./service.py:svc --reload
  
  Users can then send requests to the newly started services with any client:
  
  .. tab-set::
  
      .. tab-item:: Bash
  
          .. code-block:: bash
  
             # we will run on our input image test.png
             # image can get from http://images.cocodataset.org/val2017/000000039769.jpg
             % curl -H "Content-Type: multipart/form-data" \
                    -F 'fileobj=@test.jpg;type=image/jpeg' \
                    http://0.0.0.0:3000/predict_image
  
             # [{"score":0.8610631227493286,"label":"Egyptian cat"},
             # {"score":0.08770329505205154,"label":"tabby, tabby cat"},
             # {"score":0.03540956228971481,"label":"tiger cat"},
             # {"score":0.004140055272728205,"label":"lynx, catamount"},
             # {"score":0.0009498853469267488,"label":"Siamese cat, Siamese"}]%
  
      .. tab-item:: Python
  
         .. code-block:: python
            :caption: `request.py`
  
            import requests
  
            requests.post(
                "http://0.0.0.0:3000/predict_image",
                files = {"upload_file": open('test.jpg', 'rb')},
                headers = {"content-type": "multipart/form-data"}
            ).text
  
  Args:
      pilmode: Color mode for PIL. Default to ``RGB``.
      mime_type: The MIME type of the file type that this descriptor should return. Only relevant when used as an output descriptor.
      allowed_mime_types: A list of MIME types to restrict input to.
  
  Returns:
      :obj:`Image`: IO Descriptor that either a :code:`PIL.Image.Image` or a :code:`np.ndarray` representing an image.
class_docstr_tok: [":","obj",":","`","Image","`","defines","API","specification","for","the","inputs\/outputs","of","a","Service",",","where","either","inputs","will","be","converted","to","or","outputs","will","be","converted","from","images","as","specified","in","your","API","function","signature",".","A","sample","object","detection","service",":","..","code-block",":",":","python",":","caption",":","`","service.py","`","from","__future__","import","annotations","from","typing","import","TYPE_CHECKING","from","typing","import","Any","import","bentoml","from","bentoml.io","import","Image","from","bentoml.io","import","NumpyNdarray","if","TYPE_CHECKING",":","from","PIL.Image","import","Image","from","numpy.typing","import","NDArray","runner","=","bentoml.tensorflow.get","(","'image-classification",":","latest","'",")",".to_runner","(",")","svc","=","bentoml.Service","(","``","vit-object-detection","''",",","runners=","[","runner","]",")","@","svc.api","(","input=Image","(",")",",","output=NumpyNdarray","(","dtype=","''","float32","''",")",")","async","def","predict_image","(","f",":","Image",")","-",">","NDArray","[","Any","]",":","assert","isinstance","(","f",",","Image",")","arr","=","np.array","(","f",")","\/","255.0","assert","arr.shape","==","(","28",",","28",")","#","We","are","using","greyscale","image","and","our","PyTorch","model","expect","one","#","extra","channel","dimension","arr","=","np.expand_dims","(","arr",",","(","0",",","3",")",")",".astype","(","``","float32","''",")","#","reshape","to","[","1",",","28",",","28",",","1","]","return","await","runner.async_run","(","arr",")","Users","then","can","then","serve","this","service","with",":","code",":","`","bentoml","serve","`",":","..","code-block",":",":","bash","%","bentoml","serve",".\/service.py",":","svc","--","reload","Users","can","then","send","requests","to","the","newly","started","services","with","any","client",":","..","tab-set",":",":","..","tab-item",":",":","Bash","..","code-block",":",":","bash","#","we","will","run","on","our","input","image","test.png","#","image","can","get","from","http",":","\/\/images.cocodataset.org\/val2017\/000000039769.jpg","%","curl","-H","``","Content-Type",":","multipart\/form-data","''","\\","-F","'fileobj=","@","test.jpg",";","type=image\/jpeg","'","\\","http",":","\/\/0.0.0.0:3000\/predict_image","#","[","{","``","score","''",":0.8610631227493286",",","''","label","''",":","''","Egyptian","cat","''","}",",","#","{","``","score","''",":0.08770329505205154",",","''","label","''",":","''","tabby",",","tabby","cat","''","}",",","#","{","``","score","''",":0.03540956228971481",",","''","label","''",":","''","tiger","cat","''","}",",","#","{","``","score","''",":0.004140055272728205",",","''","label","''",":","''","lynx",",","catamount","''","}",",","#","{","``","score","''",":0.0009498853469267488",",","''","label","''",":","''","Siamese","cat",",","Siamese","''","}","]","%","..","tab-item",":",":","Python","..","code-block",":",":","python",":","caption",":","`","request.py","`","import","requests","requests.post","(","``","http",":","\/\/0.0.0.0:3000\/predict_image","''",",","files","=","{","``","upload_file","''",":","open","(","'test.jpg","'",",","'rb","'",")","}",",","headers","=","{","``","content-type","''",":","``","multipart\/form-data","''","}",")",".text","Args",":","pilmode",":","Color","mode","for","PIL",".","Default","to","``","RGB","``",".","mime_type",":","The","MIME","type","of","the","file","type","that","this","descriptor","should","return",".","Only","relevant","when","used","as","an","output","descriptor",".","allowed_mime_types",":","A","list","of","MIME","types","to","restrict","input","to",".","Returns",":",":","obj",":","`","Image","`",":","IO","Descriptor","that","either","a",":","code",":","`","PIL.Image.Image","`","or","a",":","code",":","`","np.ndarray","`","representing","an","image","."]
code: def from_spec(cls, spec: dict[str, t.Any]) -> t.Self:
      if "args" not in spec:
          raise InvalidArgument(
              f"Missing args key in Image spec: {spec}"
          )
  
      return cls(**spec["args"])
  
imports: from __future__ import annotations
  import functools
  import io
  import typing
  from urllib.parse import quote
  from multipart.multipart import parse_options_header
  from starlette.datastructures import UploadFile
  from starlette.requests import Request
  from starlette.responses import Response
  from ...exceptions import BadInput
  from ...exceptions import InternalServerError
  from ...exceptions import InvalidArgument
  from ...exceptions import MissingDependencyException
  from ...grpc.utils import import_generated_stubs
  from ..service.openapi import SUCCESS_DESCRIPTION
  from ..service.openapi.specification import MediaType
  from ..service.openapi.specification import Schema
  from ..types import LazyType
  from ..utils import LazyLoader
  from ..utils import resolve_user_filepath
  from ..utils.http import set_cookies
  from .base import IODescriptor
label_desc: Use image node_id 4 for calling the Image obj's underlying member method code with example usage: obj.from_spec(cls, spec) and returns: cls