class_docstr: :obj:`PandasDataFrame` defines API specification for the inputs/outputs of a Service,
  where either inputs will be converted to or outputs will be converted from type
  :code:`pd.DataFrame` as specified in your API function signature.
  
  A sample service implementation:
  
  .. code-block:: python
     :caption: `service.py`
  
     from __future__ import annotations
  
     import bentoml
     import pandas as pd
     import numpy as np
     from bentoml.io import PandasDataFrame
  
     input_spec = PandasDataFrame.from_sample(pd.DataFrame(np.array([[5,4,3,2]])))
  
     runner = bentoml.sklearn.get("sklearn_model_clf").to_runner()
  
     svc = bentoml.Service("iris-classifier", runners=[runner])
  
     @svc.api(input=input_spec, output=PandasDataFrame())
     def predict(input_arr):
         res = runner.run(input_arr)
         return pd.DataFrame(res)
  
  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: application/json" \
                      --data '[{"0":5,"1":4,"2":3,"3":2}]' http://0.0.0.0:3000/predict
  
              # [{"0": 1}]%
  
      .. tab-item:: Python
  
          .. code-block:: python
             :caption: `request.py`
  
              import requests
  
              requests.post(
                  "http://0.0.0.0:3000/predict",
                  headers={"content-type": "application/json"},
                  data='[{"0":5,"1":4,"2":3,"3":2}]'
              ).text
  
  Args:
      orient: Indication of expected JSON string format. Compatible JSON strings can be
              produced by :func:`pandas.io.json.to_json()` with a corresponding orient value.
              Possible orients are:
  
              - :obj:`split` - :code:`dict[str, Any]` ↦ {``idx`` ↠ ``[idx]``, ``columns`` ↠ ``[columns]``, ``data`` ↠ ``[values]``}
              - :obj:`records` - :code:`list[Any]` ↦ [{``column`` ↠ ``value``}, ..., {``column`` ↠ ``value``}]
              - :obj:`index` - :code:`dict[str, Any]` ↦ {``idx`` ↠ {``column`` ↠ ``value``}}
              - :obj:`columns` - :code:`dict[str, Any]` ↦ {``column`` ↠ {``index`` ↠ ``value``}}
              - :obj:`values` - :code:`dict[str, Any]` ↦ Values arrays
      columns: List of columns name that users wish to update.
      apply_column_names: Whether to update incoming DataFrame columns. If :code:`apply_column_names=True`,
                          then ``columns`` must be specified.
      dtype: Data type users wish to convert their inputs/outputs to. If it is a boolean,
             then pandas will infer dtypes. Else if it is a dictionary of column to
             ``dtype``, then applies those to incoming dataframes. If ``False``, then don't
             infer dtypes at all (only applies to the data). This is not applicable for :code:`orient='table'`.
      enforce_dtype: Whether to enforce a certain data type. if :code:`enforce_dtype=True` then :code:`dtype` must be specified.
      shape: Optional shape check that users can specify for their incoming HTTP
             requests. We will only check the number of columns you specified for your
             given shape:
  
             .. code-block:: python
                :caption: `service.py`
  
  
                import pandas as pd
                from bentoml.io import PandasDataFrame
  
                df = pd.DataFrame([[1, 2, 3]])  # shape (1,3)
                inp = PandasDataFrame.from_sample(df)
  
                @svc.api(
                    input=PandasDataFrame(shape=(51, 10),
                          enforce_shape=True),
                    output=PandasDataFrame()
                )
                def predict(input_df: pd.DataFrame) -> pd.DataFrame:
                    # if input_df have shape (40,9),
                    # it will throw out errors
                    ...
      enforce_shape: Whether to enforce a certain shape. If ``enforce_shape=True`` then ``shape`` must be specified.
      default_format: The default serialization format to use if the request does not specify a ``Content-Type`` Headers.
                      It is also the serialization format used for the response. Possible values are:
  
                      - :obj:`json` - JSON text format (inferred from content-type ``"application/json"``)
                      - :obj:`parquet` - Parquet binary format (inferred from content-type ``"application/octet-stream"``)
                      - :obj:`csv` - CSV text format (inferred from content-type ``"text/csv"``)
  
  Returns:
      :obj:`PandasDataFrame`: IO Descriptor that represents a :code:`pd.DataFrame`.
class_docstr_tok: [":","obj",":","`","PandasDataFrame","`","defines","API","specification","for","the","inputs\/outputs","of","a","Service",",","where","either","inputs","will","be","converted","to","or","outputs","will","be","converted","from","type",":","code",":","`","pd.DataFrame","`","as","specified","in","your","API","function","signature",".","A","sample","service","implementation",":","..","code-block",":",":","python",":","caption",":","`","service.py","`","from","__future__","import","annotations","import","bentoml","import","pandas","as","pd","import","numpy","as","np","from","bentoml.io","import","PandasDataFrame","input_spec","=","PandasDataFrame.from_sample","(","pd.DataFrame","(","np.array","(","[","[","5,4,3,2","]","]",")",")",")","runner","=","bentoml.sklearn.get","(","``","sklearn_model_clf","''",")",".to_runner","(",")","svc","=","bentoml.Service","(","``","iris-classifier","''",",","runners=","[","runner","]",")","@","svc.api","(","input=input_spec",",","output=PandasDataFrame","(",")",")","def","predict","(","input_arr",")",":","res","=","runner.run","(","input_arr",")","return","pd.DataFrame","(","res",")","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",":","application\/json","''","\\","--","data","'","[","{","``","0","''",":5",",","''","1","''",":4",",","''","2","''",":3",",","''","3","''",":2","}","]","'","http",":","\/\/0.0.0.0:3000\/predict","#","[","{","``","0","''",":","1","}","]","%","..","tab-item",":",":","Python","..","code-block",":",":","python",":","caption",":","`","request.py","`","import","requests","requests.post","(","``","http",":","\/\/0.0.0.0:3000\/predict","''",",","headers=","{","``","content-type","''",":","``","application\/json","''","}",",","data=","'","[","{","``","0","''",":5",",","''","1","''",":4",",","''","2","''",":3",",","''","3","''",":2","}","]","'",")",".text","Args",":","orient",":","Indication","of","expected","JSON","string","format",".","Compatible","JSON","strings","can","be","produced","by",":","func",":","`","pandas.io.json.to_json","(",")","`","with","a","corresponding","orient","value",".","Possible","orients","are",":","-",":","obj",":","`","split","`","-",":","code",":","`","dict","[","str",",","Any","]","`","\u21a6","{","``","idx","``","\u21a0","``","[","idx","]","``",",","``","columns","``","\u21a0","``","[","columns","]","``",",","``","data","``","\u21a0","``","[","values","]","``","}","-",":","obj",":","`","records","`","-",":","code",":","`","list","[","Any","]","`","\u21a6","[","{","``","column","``","\u21a0","``","value","``","}",",","...",",","{","``","column","``","\u21a0","``","value","``","}","]","-",":","obj",":","`","index","`","-",":","code",":","`","dict","[","str",",","Any","]","`","\u21a6","{","``","idx","``","\u21a0","{","``","column","``","\u21a0","``","value","``","}","}","-",":","obj",":","`","columns","`","-",":","code",":","`","dict","[","str",",","Any","]","`","\u21a6","{","``","column","``","\u21a0","{","``","index","``","\u21a0","``","value","``","}","}","-",":","obj",":","`","values","`","-",":","code",":","`","dict","[","str",",","Any","]","`","\u21a6","Values","arrays","columns",":","List","of","columns","name","that","users","wish","to","update",".","apply_column_names",":","Whether","to","update","incoming","DataFrame","columns",".","If",":","code",":","`","apply_column_names=True","`",",","then","``","columns","``","must","be","specified",".","dtype",":","Data","type","users","wish","to","convert","their","inputs\/outputs","to",".","If","it","is","a","boolean",",","then","pandas","will","infer","dtypes",".","Else","if","it","is","a","dictionary","of","column","to","``","dtype","``",",","then","applies","those","to","incoming","dataframes",".","If","``","False","``",",","then","don't","infer","dtypes","at","all","(","only","applies","to","the","data",")",".","This","is","not","applicable","for",":","code",":","`","orient='table","'","`",".","enforce_dtype",":","Whether","to","enforce","a","certain","data","type",".","if",":","code",":","`","enforce_dtype=True","`","then",":","code",":","`","dtype","`","must","be","specified",".","shape",":","Optional","shape","check","that","users","can","specify","for","their","incoming","HTTP","requests",".","We","will","only","check","the","number","of","columns","you","specified","for","your","given","shape",":","..","code-block",":",":","python",":","caption",":","`","service.py","`","import","pandas","as","pd","from","bentoml.io","import","PandasDataFrame","df","=","pd.DataFrame","(","[","[","1",",","2",",","3","]","]",")","#","shape","(","1,3",")","inp","=","PandasDataFrame.from_sample","(","df",")","@","svc.api","(","input=PandasDataFrame","(","shape=","(","51",",","10",")",",","enforce_shape=True",")",",","output=PandasDataFrame","(",")",")","def","predict","(","input_df",":","pd.DataFrame",")","-",">","pd.DataFrame",":","#","if","input_df","have","shape","(","40,9",")",",","#","it","will","throw","out","errors","...","enforce_shape",":","Whether","to","enforce","a","certain","shape",".","If","``","enforce_shape=True","``","then","``","shape","``","must","be","specified",".","default_format",":","The","default","serialization","format","to","use","if","the","request","does","not","specify","a","``","Content-Type","``","Headers",".","It","is","also","the","serialization","format","used","for","the","response",".","Possible","values","are",":","-",":","obj",":","`","json","`","-","JSON","text","format","(","inferred","from","content-type","``","``","application\/json","''","``",")","-",":","obj",":","`","parquet","`","-","Parquet","binary","format","(","inferred","from","content-type","``","``","application\/octet-stream","''","``",")","-",":","obj",":","`","csv","`","-","CSV","text","format","(","inferred","from","content-type","``","``","text\/csv","''","``",")","Returns",":",":","obj",":","`","PandasDataFrame","`",":","IO","Descriptor","that","represents","a",":","code",":","`","pd.DataFrame","`","."]
code: def validate_dataframe(
      self,
      dataframe: ext.PdDataFrame,
      exception_cls: t.Type[Exception] = BadInput,
  ) -> ext.PdDataFrame:
      if not LazyType["ext.PdDataFrame"](
          "pandas.core.frame.DataFrame"
      ).isinstance(dataframe):
          raise InvalidArgument(
              f"return object is not of type 'pd.DataFrame', got type '{type(dataframe)}' instead"
          ) from None
  
      # TODO: dtype check
      # if self._dtype is not None and self._dtype != dataframe.dtypes:
      #     msg = f'{self.__class__.__name__}: Expecting DataFrame of dtype "{self._dtype}", but "{dataframe.dtypes}" was received.'
      #     if self._enforce_dtype:
      #         raise exception_cls(msg) from None
  
      if self._apply_column_names:
          if not self._columns:
              raise BadInput(
                  "When apply_column_names is set, you must provide columns."
              )
  
          if len(self._columns) != dataframe.shape[1]:
              raise BadInput(
                  f"length of 'columns' ({len(self._columns)}) does not match the # of columns of incoming data ({dataframe.shape[1]})."
              ) from None
  
          dataframe.columns = pd.Index(self._columns)
  
      # TODO: convert from wide to long format (melt())
      if self._shape is not None and self._shape != dataframe.shape:
          msg = f'{self.__class__.__name__}: Expecting DataFrame of shape "{self._shape}", but "{dataframe.shape}" was received.'
          if self._enforce_shape and not all(
              left == right
              for left, right in zip(self._shape, dataframe.shape)
              if left != -1 and right != -1
          ):
              raise exception_cls(msg) from None
  
      return dataframe
  
imports: from __future__ import annotations
  import functools
  import io
  import logging
  import os
  import typing
  from concurrent.futures import ThreadPoolExecutor
  from enum import Enum
  from starlette.requests import Request
  from starlette.responses import Response
  from ...exceptions import BadInput
  from ...exceptions import InvalidArgument
  from ...exceptions import MissingDependencyException
  from ...exceptions import UnprocessableEntity
  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.http import set_cookies
  from ..utils.lazy_loader import LazyLoader
  from ..utils.pkg import find_spec
  from .base import IODescriptor
label_desc: Use image node_id 12 for calling the PandasDataFrame obj's underlying member method code with example usage: obj.validate_dataframe(dataframe, exception_cls) and returns: dataframe