class_docstr: :obj:`Multipart` defines API specification for the inputs/outputs of a Service, where inputs/outputs
  of a Service can receive/send a **multipart** request/responses as specified in your API function signature.
  
  A sample service implementation:
  
  .. 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 NumpyNdarray
     from bentoml.io import Multipart
     from bentoml.io import JSON
  
     if TYPE_CHECKING:
         from numpy.typing import NDArray
  
     runner = bentoml.sklearn.get("sklearn_model_clf").to_runner()
  
     svc = bentoml.Service("iris-classifier", runners=[runner])
  
     input_spec = Multipart(arr=NumpyNdarray(), annotations=JSON())
     output_spec = Multipart(output=NumpyNdarray(), result=JSON())
  
     @svc.api(input=input_spec, output=output_spec)
     async def predict(
         arr: NDArray[Any], annotations: dict[str, Any]
     ) -> dict[str, NDArray[Any] | dict[str, Any]]:
         res = await runner.run(arr)
         return {"output": res, "result": annotations}
  
  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
  
             % curl -X POST -H "Content-Type: multipart/form-data" \
                    -F annotations=@test.json -F arr='[5,4,3,2]' \
                    http://0.0.0.0:3000/predict
  
             # --b1d72c201a064ecd92a17a412eb9208e
             # Content-Disposition: form-data; name="output"
             # content-length: 1
             # content-type: application/json
  
             # 1
             # --b1d72c201a064ecd92a17a412eb9208e
             # Content-Disposition: form-data; name="result"
             # content-length: 13
             # content-type: application/json
  
             # {"foo":"bar"}
             # --b1d72c201a064ecd92a17a412eb9208e--
  
      .. tab-item:: Python
  
         .. note::
  
            The following code snippet uses `requests_toolbelt <https://github.com/requests/toolbelt>`_.
            Install with ``pip install requests-toolbelt``.
  
         .. code-block:: python
            :caption: `request.py`
  
            import requests
  
            from requests_toolbelt.multipart.encoder import MultipartEncoder
  
            m = MultipartEncoder(
                fields={
                    "field0": "value",
                    "field1": "value",
                    "field2": ("filename", open("test.json", "rb"), "application/json"),
                }
            )
  
            requests.post(
                "http://0.0.0.0:3000/predict", data=m, headers={"Content-Type": m.content_type}
            )
  
  Args:
      inputs: Dictionary consisting keys as inputs definition for a Multipart
              request/response, values as IODescriptor supported by BentoML. Currently,
              :obj:`Multipart` supports :obj:`Image`, :obj:`NumpyNdarray`, :obj:`PandasDataFrame`, :obj:`PandasSeries`, :obj:`Text`,
              and :obj:`File`.
  
              Make sure to match the input parameters in function signatures in an API function to the keys defined
              under :obj:`Multipart`:
  
              .. code-block:: bash
  
                 +----------------------------------------------------------------+
                 |                                                                |
                 |   +--------------------------------------------------------+   |
                 |   |                                                        |   |
                 |   |    Multipart(arr=NumpyNdarray(), annotations=JSON())   |   |
                 |   |               |                       |                |   |
                 |   +---------------+-----------------------+----------------+   |
                 |                   |                       |                    |
                 |                   |                       |                    |
                 |                   |                       |                    |
                 |                   +-----+        +--------+                    |
                 |                         |        |                             |
                 |         +---------------v--------v---------+                   |
                 |         |  def predict(arr, annotations):  |                   |
                 |         +----------------------------------+                   |
                 |                                                                |
                 +----------------------------------------------------------------+
  
  Returns:
      :obj:`Multipart`: IO Descriptor that represents a Multipart request/response.
class_docstr_tok: [":","obj",":","`","Multipart","`","defines","API","specification","for","the","inputs\/outputs","of","a","Service",",","where","inputs\/outputs","of","a","Service","can","receive\/send","a","*","*","multipart","*","*","request\/responses","as","specified","in","your","API","function","signature",".","A","sample","service","implementation",":","..","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","NumpyNdarray","from","bentoml.io","import","Multipart","from","bentoml.io","import","JSON","if","TYPE_CHECKING",":","from","numpy.typing","import","NDArray","runner","=","bentoml.sklearn.get","(","``","sklearn_model_clf","''",")",".to_runner","(",")","svc","=","bentoml.Service","(","``","iris-classifier","''",",","runners=","[","runner","]",")","input_spec","=","Multipart","(","arr=NumpyNdarray","(",")",",","annotations=JSON","(",")",")","output_spec","=","Multipart","(","output=NumpyNdarray","(",")",",","result=JSON","(",")",")","@","svc.api","(","input=input_spec",",","output=output_spec",")","async","def","predict","(","arr",":","NDArray","[","Any","]",",","annotations",":","dict","[","str",",","Any","]",")","-",">","dict","[","str",",","NDArray","[","Any","]","|","dict","[","str",",","Any","]","]",":","res","=","await","runner.run","(","arr",")","return","{","``","output","''",":","res",",","``","result","''",":","annotations","}","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","%","curl","-X","POST","-H","``","Content-Type",":","multipart\/form-data","''","\\","-F","annotations=","@","test.json","-F","arr=","'","[","5,4,3,2","]","'","\\","http",":","\/\/0.0.0.0:3000\/predict","#","--","b1d72c201a064ecd92a17a412eb9208e","#","Content-Disposition",":","form-data",";","name=","''","output","''","#","content-length",":","1","#","content-type",":","application\/json","#","1","#","--","b1d72c201a064ecd92a17a412eb9208e","#","Content-Disposition",":","form-data",";","name=","''","result","''","#","content-length",":","13","#","content-type",":","application\/json","#","{","``","foo","''",":","''","bar","''","}","#","--","b1d72c201a064ecd92a17a412eb9208e","--","..","tab-item",":",":","Python","..","note",":",":","The","following","code","snippet","uses","`","requests_toolbelt","<","https",":","\/\/github.com\/requests\/toolbelt",">","`","_",".","Install","with","``","pip","install","requests-toolbelt","``",".","..","code-block",":",":","python",":","caption",":","`","request.py","`","import","requests","from","requests_toolbelt.multipart.encoder","import","MultipartEncoder","m","=","MultipartEncoder","(","fields=","{","``","field0","''",":","``","value","''",",","``","field1","''",":","``","value","''",",","``","field2","''",":","(","``","filename","''",",","open","(","``","test.json","''",",","``","rb","''",")",",","``","application\/json","''",")",",","}",")","requests.post","(","``","http",":","\/\/0.0.0.0:3000\/predict","''",",","data=m",",","headers=","{","``","Content-Type","''",":","m.content_type","}",")","Args",":","inputs",":","Dictionary","consisting","keys","as","inputs","definition","for","a","Multipart","request\/response",",","values","as","IODescriptor","supported","by","BentoML",".","Currently",",",":","obj",":","`","Multipart","`","supports",":","obj",":","`","Image","`",",",":","obj",":","`","NumpyNdarray","`",",",":","obj",":","`","PandasDataFrame","`",",",":","obj",":","`","PandasSeries","`",",",":","obj",":","`","Text","`",",","and",":","obj",":","`","File","`",".","Make","sure","to","match","the","input","parameters","in","function","signatures","in","an","API","function","to","the","keys","defined","under",":","obj",":","`","Multipart","`",":","..","code-block",":",":","bash","+","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","+","|","|","|","+","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","+","|","|","|","|","|","|","|","Multipart","(","arr=NumpyNdarray","(",")",",","annotations=JSON","(",")",")","|","|","|","|","|","|","|","|","|","+","--","--","--","--","--","--","--","-+","--","--","--","--","--","--","--","--","--","--","--","-+","--","--","--","--","--","--","--","--","+","|","|","|","|","|","|","|","|","|","|","|","|","|","|","+","--","--","-+","+","--","--","--","--","+","|","|","|","|","|","|","+","--","--","--","--","--","--","--","-v","--","--","--","--","v","--","--","--","--","-+","|","|","|","def","predict","(","arr",",","annotations",")",":","|","|","|","+","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","+","|","|","|","+","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","+","Returns",":",":","obj",":","`","Multipart","`",":","IO","Descriptor","that","represents","a","Multipart","request\/response","."]
code: def openapi_request_body(self) -> dict[str, t.Any]:
      return {
          "content": {
              self._mime_type: MediaType(
                  schema=self.openapi_schema(),
                  example=self.openapi_example(),
              )
          },
          "required": True,
          "x-bentoml-io-descriptor": self.to_spec(),
      }
  
imports: from __future__ import annotations
  import asyncio
  import typing
  from multipart.multipart import parse_options_header
  from starlette.requests import Request
  from starlette.responses import Response
  from ...exceptions import BentoMLException
  from ...exceptions import InvalidArgument
  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 ..utils.formparser import concat_to_multipart_response
  from ..utils.formparser import populate_multipart_requests
  from .None import from_spec
  from .base import IODescriptor
label_desc: Use image node_id 10 for calling the Multipart obj's underlying member method code with example usage: obj.openapi_request_body() and returns: dict