kind: job
verbose: false
metadata:
  name: batch-inference
  tag: ''
  categories:
  - model-serving
spec:
  image: mlrun/ml-models
  entry_points:
    infer:
      name: infer
      doc: 'Perform a prediction on a given dataset with the given model. Can perform
        drift analysis between the sample set

        statistics stored in the model to the current input data. The drift rule is
        the value per-feature mean of the TVD

        and Hellinger scores according to the thresholds configures here.'
      parameters:
      - name: context
        type: MLClientCtx
        doc: MLRun context.
      - name: model
        type: str
        doc: The model Store path.
      - name: dataset
        type: DatasetType
        doc: The dataset to infer through the model. Can be passed in `inputs` as
          either a Dataset artifact / Feature vector URI. Or, in `parameters` as a
          list, dictionary or numpy array.
      - name: drop_columns
        type: Union[str, List[str], int, List[int]]
        doc: A string / integer or a list of strings / integers that represent the
          column names / indices to drop. When the dataset is a list or a numpy array
          this parameter must be represented by integers.
        default: null
      - name: label_columns
        type: Union[str, List[str]]
        doc: The target label(s) of the column(s) in the dataset for Regression or
          Classification tasks. The label column can be accessed from the model object,
          or the feature vector provided if available.
        default: null
      - name: feature_columns
        type: Union[str, List[str]]
        doc: List of feature columns that will be used to build the dataframe when
          dataset is from type list or numpy array.
        default: null
      - name: log_result_set
        type: bool
        doc: Whether to log the result set - a DataFrame of the given inputs concatenated
          with the predictions. Defaulted to True.
        default: true
      - name: result_set_name
        type: str
        doc: The db key to set name of the prediction result and the filename. Defaulted
          to 'prediction'.
        default: prediction
      - name: batch_id
        type: str
        doc: The ID of the given batch (inference dataset). If `None`, it will be
          generated. Will be logged as a result of the run.
        default: null
      - name: perform_drift_analysis
        type: bool
        doc: Whether to perform drift analysis between the sample set of the model
          object to the dataset given. By default, None, which means it will perform
          drift analysis if the model has a sample set statistics. Perform drift analysis
          will produce a data drift table artifact.
        default: null
      - name: sample_set
        type: DatasetType
        doc: A sample dataset to give to compare the inputs in the drift analysis.
          The default chosen sample set will always be the one who is set in the model
          artifact itself.
        default: null
      - name: drift_threshold
        type: float
        doc: The threshold of which to mark drifts. Defaulted to 0.7.
        default: 0.7
      - name: possible_drift_threshold
        type: float
        doc: The threshold of which to mark possible drifts. Defaulted to 0.5.
        default: 0.5
      - name: inf_capping
        type: float
        doc: The value to set for when it reached infinity. Defaulted to 10.0.
        default: 10.0
      - name: artifacts_tag
        type: str
        doc: Tag to use for all the artifacts resulted from the function.
        default: ''
      lineno: 317
      has_kwargs: true
      has_varargs: false
  allow_empty_resources: true
  default_handler: infer
  command: ''
  build:
    functionSourceCode: IyBDb3B5cmlnaHQgMjAxOSBJZ3VhemlvCiMKIyBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKIyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiMgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiMKIyAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiMKIyBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKIyBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KIyBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiMgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiMKaW1wb3J0IGhhc2hsaWIKaW1wb3J0IGpzb24KZnJvbSBkYXRldGltZSBpbXBvcnQgZGF0ZXRpbWUKZnJvbSB0eXBpbmcgaW1wb3J0IEFueSwgRGljdCwgTGlzdCwgVHVwbGUsIFVuaW9uCmltcG9ydCBzZW12ZXIKCmltcG9ydCBtbHJ1bgppZiBzZW12ZXIuY29tcGFyZShtbHJ1bi5fX3ZlcnNpb25fXywgIjEuNS4wIikgPj0gMDoKICAgIHJhaXNlIG1scnVuLmVycm9ycy5NTFJ1bk5vdEZvdW5kRXJyb3IoCiAgICAgICAgZiJXaGVuIHVzaW5nIGBtbHJ1bmAgdmVyc2lvbiA+PTEuNS4wLCBwbGVhc2UgdXNlICIKICAgICAgICBmImJhdGNoIGluZmVyZW5jZSBgdjJgIGZ1bmN0aW9uICgnaHViOi8vYmF0Y2hfaW5mZXJlbmNlX3YyJykuIgogICAgKQoKaW1wb3J0IG1scnVuLmRhdGFzdG9yZQppbXBvcnQgbWxydW4udXRpbHMKaW1wb3J0IG51bXB5IGFzIG5wCmltcG9ydCBwYW5kYXMgYXMgcGQKZnJvbSBtbHJ1biBpbXBvcnQgZmVhdHVyZV9zdG9yZSBhcyBmcwpmcm9tIG1scnVuLmFydGlmYWN0cyBpbXBvcnQgQXJ0aWZhY3QKZnJvbSBtbHJ1bi5kYXRhX3R5cGVzLmluZmVyIGltcG9ydCBJbmZlck9wdGlvbnMsIGdldF9kZl9zdGF0cwpmcm9tIG1scnVuLmZyYW1ld29ya3MuYXV0b19tbHJ1biBpbXBvcnQgQXV0b01MUnVuCmZyb20gbWxydW4ubW9kZWxfbW9uaXRvcmluZy5mZWF0dXJlc19kcmlmdF90YWJsZSBpbXBvcnQgRmVhdHVyZXNEcmlmdFRhYmxlUGxvdApmcm9tIG1scnVuLm1vZGVsX21vbml0b3JpbmcubW9kZWxfbW9uaXRvcmluZ19iYXRjaCBpbXBvcnQgKAogICAgVmlydHVhbERyaWZ0LAogICAgY2FsY3VsYXRlX2lucHV0c19zdGF0aXN0aWNzLAopCgojIEEgdW5pb24gb2YgYWxsIHN1cHBvcnRlZCBkYXRhc2V0IHR5cGVzOgpEYXRhc2V0VHlwZSA9IFVuaW9uW21scnVuLkRhdGFJdGVtLCBsaXN0LCBkaWN0LCBwZC5EYXRhRnJhbWUsIHBkLlNlcmllcywgbnAubmRhcnJheV0KCgpkZWYgX3JlYWRfZGF0YXNldF9hc19kYXRhZnJhbWUoCiAgICBkYXRhc2V0OiBEYXRhc2V0VHlwZSwKICAgIGZlYXR1cmVfY29sdW1uczogVW5pb25bc3RyLCBMaXN0W3N0cl1dID0gTm9uZSwKICAgIGxhYmVsX2NvbHVtbnM6IFVuaW9uW3N0ciwgTGlzdFtzdHJdXSA9IE5vbmUsCiAgICBkcm9wX2NvbHVtbnM6IFVuaW9uW3N0ciwgTGlzdFtzdHJdLCBpbnQsIExpc3RbaW50XV0gPSBOb25lLAopIC0+IFR1cGxlW3BkLkRhdGFGcmFtZSwgTGlzdFtzdHJdXToKICAgICIiIgogICAgUGFyc2UgdGhlIGdpdmVuIGRhdGFzZXQgaW50byBhIERhdGFGcmFtZSBhbmQgZHJvcCB0aGUgY29sdW1ucyBhY2NvcmRpbmdseS4gSW4gYWRkaXRpb24sIHRoZSBsYWJlbCBjb2x1bW5zIHdpbGwgYmUKICAgIHBhcnNlZCBhbmQgdmFsaWRhdGVkIGFzIHdlbGwuCgogICAgOnBhcmFtIGRhdGFzZXQ6ICAgICAgICAgQSBkYXRhc2V0IHRoYXQgd2lsbCBiZSBjb252ZXJ0ZWQgaW50byBhIERhdGFGcmFtZS4KICAgICAgICAgICAgICAgICAgICAgICAgICAgIENhbiBiZSBlaXRoZXIgYSBsaXN0IG9mIGxpc3RzLCBkaWN0LCBVUkkgb3IgYSBGZWF0dXJlVmVjdG9yLgogICAgOnBhcmFtIGZlYXR1cmVfY29sdW1uczogTGlzdCBvZiBmZWF0dXJlIGNvbHVtbnMgdGhhdCB3aWxsIGJlIHVzZWQgdG8gYnVpbGQgdGhlIGRhdGFmcmFtZSB3aGVuIGRhdGFzZXQgaXMgZnJvbQogICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZSBsaXN0IG9yIG51bXB5IGFycmF5LgogICAgOnBhcmFtIGxhYmVsX2NvbHVtbnM6ICAgVGhlIHRhcmdldCBsYWJlbChzKSBvZiB0aGUgY29sdW1uKHMpIGluIHRoZSBkYXRhc2V0LiBmb3IgUmVncmVzc2lvbiBvcgogICAgICAgICAgICAgICAgICAgICAgICAgICAgQ2xhc3NpZmljYXRpb24gdGFza3MuCiAgICA6cGFyYW0gZHJvcF9jb2x1bW5zOiAgICBgYHN0cmBgIC8gYGBpbnRgYCBvciBhIGxpc3Qgb2YgYGBzdHJgYCAvIGBgaW50YGAgdGhhdCByZXByZXNlbnQgdGhlIGNvbHVtbiBuYW1lcyAvIGluZGljZXMKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvIGRyb3AuCgogICAgOnJldHVybnM6IEEgdHVwbGUgb2Y6CiAgICAgICAgICAgICAgWzBdID0gVGhlIHBhcnNlZCBkYXRhc2V0IGFzIGEgRGF0YUZyYW1lCiAgICAgICAgICAgICAgWzFdID0gTGFiZWwgY29sdW1ucy4KCiAgICByYWlzZXMgTUxSdW5JbnZhbGlkQXJndW1lbnRFcnJvcjogSWYgdGhlIGBkcm9wX2NvbHVtbnNgIGFyZSBub3QgbWF0Y2hpbmcgdGhlIGRhdGFzZXQgb3IgdW5zdXBwb3J0ZWQgZGF0YXNldCB0eXBlLgogICAgIiIiCiAgICAjIFR1cm4gdGhlIGBkcm9wIGxhYmVsc2AgaW50byBhIGxpc3QgaWYgZ2l2ZW46CiAgICBpZiBkcm9wX2NvbHVtbnMgaXMgbm90IE5vbmU6CiAgICAgICAgaWYgbm90IGlzaW5zdGFuY2UoZHJvcF9jb2x1bW5zLCBsaXN0KToKICAgICAgICAgICAgZHJvcF9jb2x1bW5zID0gW2Ryb3BfY29sdW1uc10KCiAgICAjIENoZWNrIGlmIHRoZSBkYXRhc2V0IGlzIGluIGZhY3QgYSBGZWF0dXJlIFZlY3RvcjoKICAgIGlmIGlzaW5zdGFuY2UoZGF0YXNldCwgZnMuRmVhdHVyZVZlY3Rvcik6CiAgICAgICAgIyBUcnkgdG8gZ2V0IHRoZSBsYWJlbCBjb2x1bW5zIGlmIG5vdCBwcm92aWRlZDoKICAgICAgICBpZiBsYWJlbF9jb2x1bW5zIGlzIE5vbmU6CiAgICAgICAgICAgIGxhYmVsX2NvbHVtbnMgPSBkYXRhc2V0LnN0YXR1cy5sYWJlbF9jb2x1bW4KICAgICAgICAjIEdldCB0aGUgZmVhdHVyZXMgYW5kIHBhcnNlIHRvIERhdGFGcmFtZToKICAgICAgICBkYXRhc2V0ID0gZnMuZ2V0X29mZmxpbmVfZmVhdHVyZXMoCiAgICAgICAgICAgIGRhdGFzZXQudXJpLCBkcm9wX2NvbHVtbnM9ZHJvcF9jb2x1bW5zCiAgICAgICAgKS50b19kYXRhZnJhbWUoKQoKICAgIGVsaWYgaXNpbnN0YW5jZShkYXRhc2V0LCAobGlzdCwgbnAubmRhcnJheSkpOgogICAgICAgIGlmIG5vdCBmZWF0dXJlX2NvbHVtbnM6CiAgICAgICAgICAgIHJhaXNlIG1scnVuLmVycm9ycy5NTFJ1bkludmFsaWRBcmd1bWVudEVycm9yKAogICAgICAgICAgICAgICAgIkZlYXR1cmUgY29sdW1ucyBsaXN0IG11c3QgYmUgcHJvdmlkZWQgd2hlbiBkYXRhc2V0IGlucHV0IGFzIGZyb20gdHlwZSBsaXN0IG9yIG51bXB5IGFycmF5IgogICAgICAgICAgICApCiAgICAgICAgIyBQYXJzZSB0aGUgbGlzdCAvIG51bXB5IGFycmF5IGludG8gYSBEYXRhRnJhbWU6CiAgICAgICAgZGF0YXNldCA9IHBkLkRhdGFGcmFtZShkYXRhc2V0LCBjb2x1bW5zPWZlYXR1cmVfY29sdW1ucykKICAgICAgICAjIFZhbGlkYXRlIHRoZSBgZHJvcF9jb2x1bW5zYCBpcyBnaXZlbiBhcyBpbnRlZ2VyczoKICAgICAgICBpZiBkcm9wX2NvbHVtbnMgYW5kIG5vdCBhbGwoaXNpbnN0YW5jZShjb2wsIGludCkgZm9yIGNvbCBpbiBkcm9wX2NvbHVtbnMpOgogICAgICAgICAgICByYWlzZSBtbHJ1bi5lcnJvcnMuTUxSdW5JbnZhbGlkQXJndW1lbnRFcnJvcigKICAgICAgICAgICAgICAgICJgZHJvcF9jb2x1bW5zYCBtdXN0IGJlIGFuIGludGVnZXIgLyBsaXN0IG9mIGludGVnZXJzIGlmIHByb3ZpZGVkIGFzIGEgbGlzdC4iCiAgICAgICAgICAgICkKICAgIGVsaWYgaXNpbnN0YW5jZShkYXRhc2V0LCBtbHJ1bi5EYXRhSXRlbSk6CiAgICAgICAgIyBUdXJuIHRoZSBEYXRhSVRlbSB0byBEYXRhRnJhbWU6CiAgICAgICAgZGF0YXNldCA9IGRhdGFzZXQuYXNfZGYoKQogICAgZWxzZToKICAgICAgICAjIFBhcnNlIHRoZSBvYmplY3QgKHNob3VsZCBiZSBhIHBkLkRhdGFGcmFtZSAvIHBkLlNlcmllcywgZGljdGlvbmFyeSkgaW50byBhIERhdGFGcmFtZToKICAgICAgICB0cnk6CiAgICAgICAgICAgIGRhdGFzZXQgPSBwZC5EYXRhRnJhbWUoZGF0YXNldCkKICAgICAgICBleGNlcHQgVmFsdWVFcnJvciBhcyBlOgogICAgICAgICAgICByYWlzZSBtbHJ1bi5lcnJvcnMuTUxSdW5JbnZhbGlkQXJndW1lbnRFcnJvcigKICAgICAgICAgICAgICAgIGYiQ291bGQgbm90IHBhcnNlIHRoZSBnaXZlbiBkYXRhc2V0IG9mIHR5cGUge3R5cGUoZGF0YXNldCl9IGludG8gYSBwYW5kYXMgRGF0YUZyYW1lLiAiCiAgICAgICAgICAgICAgICBmIlJlY2VpdmVkIHRoZSBmb2xsb3dpbmcgZXJyb3I6IHtlfSIKICAgICAgICAgICAgKQogICAgIyBEcm9wIGNvbHVtbnMgaWYgbmVlZGVkOgogICAgaWYgZHJvcF9jb2x1bW5zOgogICAgICAgIGRhdGFzZXQuZHJvcChkcm9wX2NvbHVtbnMsIGF4aXM9MSwgaW5wbGFjZT1UcnVlKQoKICAgICMgVHVybiB0aGUgYGxhYmVsX2NvbHVtbnNgIGludG8gYSBsaXN0IGJ5IGRlZmF1bHQ6CiAgICBpZiBsYWJlbF9jb2x1bW5zIGlzIE5vbmU6CiAgICAgICAgbGFiZWxfY29sdW1ucyA9IFtdCiAgICBlbGlmIGlzaW5zdGFuY2UobGFiZWxfY29sdW1ucywgKHN0ciwgaW50KSk6CiAgICAgICAgbGFiZWxfY29sdW1ucyA9IFtsYWJlbF9jb2x1bW5zXQogICAgcmV0dXJuIGRhdGFzZXQsIGxhYmVsX2NvbHVtbnMKCgpkZWYgX3ByZXBhcmVfcmVzdWx0X3NldCgKICAgIHg6IHBkLkRhdGFGcmFtZSwgbGFiZWxfY29sdW1uczogTGlzdFtzdHJdLCB5X3ByZWQ6IG5wLm5kYXJyYXkKKSAtPiBwZC5EYXRhRnJhbWU6CiAgICAiIiIKICAgIFNldCBkZWZhdWx0IGxhYmVsIGNvbHVtbiBuYW1lcyBhbmQgdmFsaWRhdGUgZ2l2ZW4gbmFtZXMgdG8gcHJlcGFyZSB0aGUgcmVzdWx0IHNldCAtIGEgY29uY2F0ZW5hdGlvbiBvZiB0aGUgaW5wdXRzCiAgICAoeCkgYW5kIHRoZSBtb2RlbCBwcmVkaWN0aW9ucyAoeV9wcmVkKS4KCiAgICA6cGFyYW0geDogICAgICAgICAgICAgVGhlIGlucHV0cy4KICAgIDpwYXJhbSBsYWJlbF9jb2x1bW5zOiBBIGxpc3Qgb2Ygc3RyaW5ncyByZXByZXNlbnRpbmcgdGhlIHRhcmdldCBjb2x1bW4gbmFtZXMgdG8gYWRkIHRvIHRoZSBwcmVkaWN0aW9ucy4gRGVmYXVsdCBuYW1lCiAgICAgICAgICAgICAgICAgICAgICAgICAgd2lsbCBiZSB1c2VkIGluIGNhc2UgdGhlIGxpc3QgaXMgZW1wdHkgKHByZWRpY3RlZF9sYWJlbF97aX0pLgogICAgOnBhcmFtIHlfcHJlZDogICAgICAgIFRoZSBtb2RlbCBwcmVkaWN0aW9ucyBvbiB0aGUgaW5wdXRzLgoKICAgIDpyZXR1cm5zOiBUaGUgcmVzdWx0IHNldC4KCiAgICByYWlzZXMgTUxSdW5JbnZhbGlkQXJndW1lbnRFcnJvcjogSWYgdGhlIGxhYmVscyBjb2x1bW5zIGFtb3VudCBkbyBub3QgbWF0Y2ggdGhlIG91dHB1dHMgb3IgaWYgb25lIG9mIHRoZSBsYWJlbAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2x1bW4gYWxyZWFkeSBleGlzdHMgaW4gdGhlIGRhdGFzZXQuCiAgICAiIiIKICAgICMgUHJlcGFyZSBkZWZhdWx0IHRhcmdldCBjb2x1bW5zIG5hbWVzIGlmIG5vdCBwcm92aWRlZDoKICAgIHByZWRpY3Rpb25fY29sdW1uc19hbW91bnQgPSAxIGlmIGxlbih5X3ByZWQuc2hhcGUpID09IDEgZWxzZSB5X3ByZWQuc2hhcGVbMV0KICAgIGlmIGxlbihsYWJlbF9jb2x1bW5zKSA9PSAwOgogICAgICAgICMgQWRkIGRlZmF1bHQgbGFiZWwgY29sdW1uIG5hbWVzOgogICAgICAgIGlmIHByZWRpY3Rpb25fY29sdW1uc19hbW91bnQgPT0gMToKICAgICAgICAgICAgbGFiZWxfY29sdW1ucyA9IFsicHJlZGljdGVkX2xhYmVsIl0KICAgICAgICBlbHNlOgogICAgICAgICAgICBsYWJlbF9jb2x1bW5zID0gWwogICAgICAgICAgICAgICAgZiJwcmVkaWN0ZWRfbGFiZWxfe2l9IiBmb3IgaSBpbiByYW5nZShwcmVkaWN0aW9uX2NvbHVtbnNfYW1vdW50KQogICAgICAgICAgICBdCgogICAgIyBWYWxpZGF0ZSB0aGUgbGFiZWwgY29sdW1uczoKICAgIGlmIHByZWRpY3Rpb25fY29sdW1uc19hbW91bnQgIT0gbGVuKGxhYmVsX2NvbHVtbnMpOgogICAgICAgICMgTm8gZXF1YWxpdHkgYmV0d2VlbiBwcm92aWRlZCBsYWJlbCBjb2x1bW4gbmFtZXMgYW5kIG91dHB1dHMgYW1vdW50OgogICAgICAgIHJhaXNlIG1scnVuLmVycm9ycy5NTFJ1bkludmFsaWRBcmd1bWVudEVycm9yKAogICAgICAgICAgICBmIlRoZSBudW1iZXIgb2YgcHJlZGljdGVkIGxhYmVsczoge3ByZWRpY3Rpb25fY29sdW1uc19hbW91bnR9ICIKICAgICAgICAgICAgZiJpcyBub3QgZXF1YWwgdG8gdGhlIGdpdmVuIGxhYmVsIGNvbHVtbnM6IHtsZW4obGFiZWxfY29sdW1ucyl9IgogICAgICAgICkKICAgIGNvbW1vbl9sYWJlbHMgPSBzZXQobGFiZWxfY29sdW1ucykgJiBzZXQoeC5jb2x1bW5zLnRvbGlzdCgpKQogICAgaWYgY29tbW9uX2xhYmVsczoKICAgICAgICAjIExhYmVsIGNvbHVtbiBleGlzdCBpbiB0aGUgb3JpZ2luYWwgaW5wdXRzOgogICAgICAgIHJhaXNlIG1scnVuLmVycm9ycy5NTFJ1bkludmFsaWRBcmd1bWVudEVycm9yKAogICAgICAgICAgICBmIlRoZSBsYWJlbHM6IHtjb21tb25fbGFiZWxzfSBhcmUgYWxyZWFkeSBleGlzdGVkIGluIHRoZSBnaXZlbiBkYXRhc2V0LiIKICAgICAgICApCgogICAgcmV0dXJuIHBkLmNvbmNhdCgKICAgICAgICBbeCwgcGQuRGF0YUZyYW1lKHlfcHJlZCwgY29sdW1ucz1sYWJlbF9jb2x1bW5zLCBpbmRleD14LmluZGV4KV0sIGF4aXM9MQogICAgKQoKCmRlZiBfZ2V0X3NhbXBsZV9zZXRfc3RhdGlzdGljcygKICAgIHNhbXBsZV9zZXQ6IERhdGFzZXRUeXBlID0gTm9uZSwgbW9kZWxfYXJ0aWZhY3RfZmVhdHVyZV9zdGF0czogZGljdCA9IE5vbmUKKSAtPiBkaWN0OgogICAgIiIiCiAgICBHZXQgdGhlIHNhbXBsZSBzZXQgc3RhdGlzdGljcyBlaXRoZXIgZnJvbSB0aGUgZ2l2ZW4gc2FtcGxlIHNldCBvciB0aGUgc3RhdGlzdGljcyBsb2dnZWQgd2l0aCB0aGUgbW9kZWwgd2hpbGUKICAgIGZhdm9yaW5nIHRoZSBnaXZlbiBzYW1wbGUgc2V0LgoKICAgIDpwYXJhbSBzYW1wbGVfc2V0OiAgICAgICAgICAgICAgICAgICBBIHNhbXBsZSBkYXRhc2V0IHRvIGdpdmUgdG8gY29tcGFyZSB0aGUgaW5wdXRzIGluIHRoZSBkcmlmdCBhbmFseXNpcy4KICAgIDpwYXJhbSBtb2RlbF9hcnRpZmFjdF9mZWF0dXJlX3N0YXRzOiBUaGUgYGZlYXR1cmVfc3RhdHNgIGF0dHJpYnV0ZSBpbiB0aGUgc3BlYyBvZiB0aGUgbW9kZWwgYXJ0aWZhY3QsIHdoZXJlIHRoZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9yaWdpbmFsIHNhbXBsZSBzZXQgc3RhdGlzdGljcyBvZiB0aGUgbW9kZWwgd2FzIHVzZWQuCgogICAgOnJldHVybnM6IFRoZSBzYW1wbGUgc2V0IHN0YXRpc3RpY3MuCgogICAgcmFpc2VzIE1MUnVuSW52YWxpZEFyZ3VtZW50RXJyb3I6IElmIG5vIHNhbXBsZSBzZXQgb3Igc3RhdGlzdGljcyB3ZXJlIGdpdmVuLgogICAgIiIiCiAgICAjIENoZWNrIGlmIGEgc2FtcGxlIHNldCB3YXMgcHJvdmlkZWQ6CiAgICBpZiBzYW1wbGVfc2V0IGlzIE5vbmU6CiAgICAgICAgIyBDaGVjayBpZiB0aGUgbW9kZWwgd2FzIGxvZ2dlZCB3aXRoIGEgc2FtcGxlIHNldDoKICAgICAgICBpZiBtb2RlbF9hcnRpZmFjdF9mZWF0dXJlX3N0YXRzIGlzIE5vbmU6CiAgICAgICAgICAgIHJhaXNlIG1scnVuLmVycm9ycy5NTFJ1bkludmFsaWRBcmd1bWVudEVycm9yKAogICAgICAgICAgICAgICAgIkNhbm5vdCBwZXJmb3JtIGRyaWZ0IGFuYWx5c2lzIGFzIHRoZXJlIGlzIG5vIHNhbXBsZSBzZXQgdG8gY29tcGFyZSB0by4gVGhlIG1vZGVsIGFydGlmYWN0IHdhcyBub3QgIgogICAgICAgICAgICAgICAgImxvZ2dlZCB3aXRoIGEgc2FtcGxlIHNldCBhbmQgYHNhbXBsZV9zZXRgIHdhcyBub3QgcHJvdmlkZWQgdG8gdGhlIGZ1bmN0aW9uLiIKICAgICAgICAgICAgKQogICAgICAgICMgUmV0dXJuIHRoZSBzdGF0aXN0aWNzIGxvZ2dlZCB3aXRoIHRoZSBtb2RlbDoKICAgICAgICByZXR1cm4gbW9kZWxfYXJ0aWZhY3RfZmVhdHVyZV9zdGF0cwoKICAgICMgVHVybiB0aGUgRGF0YUl0ZW0gdG8gRGF0YUZyYW1lOgogICAgaWYgaXNpbnN0YW5jZShzYW1wbGVfc2V0LCBtbHJ1bi5EYXRhSXRlbSk6CiAgICAgICAgc2FtcGxlX3NldCwgXyA9IF9yZWFkX2RhdGFzZXRfYXNfZGF0YWZyYW1lKGRhdGFzZXQ9c2FtcGxlX3NldCkKCiAgICAjIFJldHVybiB0aGUgc2FtcGxlIHNldCBzdGF0aXN0aWNzOgogICAgcmV0dXJuIGdldF9kZl9zdGF0cyhkZj1zYW1wbGVfc2V0LCBvcHRpb25zPUluZmVyT3B0aW9ucy5IaXN0b2dyYW0pCgoKZGVmIF9nZXRfZHJpZnRfcmVzdWx0KAogICAgdHZkOiBmbG9hdCwKICAgIGhlbGxpbmdlcjogZmxvYXQsCiAgICB0aHJlc2hvbGQ6IGZsb2F0LAopIC0+IFR1cGxlW2Jvb2wsIGZsb2F0XToKICAgICIiIgogICAgQ2FsY3VsYXRlIHRoZSBkcmlmdCByZXN1bHQgYnkgdGhlIGZvbGxvd2luZyBlcXVhdGlvbjogKHR2ZCArIGhlbGxpbmdlcikgLyAyCgogICAgOnBhcmFtIHR2ZDogICAgICAgVGhlIGZlYXR1cmUncyBUVkQgdmFsdWUuCiAgICA6cGFyYW0gaGVsbGluZ2VyOiBUaGUgZmVhdHVyZSdzIEhlbGxpbmdlciB2YWx1ZS4KICAgIDpwYXJhbSB0aHJlc2hvbGQ6IFRoZSB0aHJlc2hvbGQgZnJvbSB3aGljaCB0aGUgdmFsdWUgaXMgY29uc2lkZXJlZCBhIGRyaWZ0LgoKICAgIDpyZXR1cm5zOiBBIHR1cGxlIG9mOgogICAgICAgICAgICAgIFswXSA9IEJvb2xlYW4gdmFsdWUgYXMgdGhlIGRyaWZ0IHN0YXR1cy4KICAgICAgICAgICAgICBbMV0gPSBUaGUgcmVzdWx0LgogICAgIiIiCiAgICByZXN1bHQgPSAodHZkICsgaGVsbGluZ2VyKSAvIDIKICAgIGlmIHJlc3VsdCA+PSB0aHJlc2hvbGQ6CiAgICAgICAgcmV0dXJuIFRydWUsIHJlc3VsdAogICAgcmV0dXJuIEZhbHNlLCByZXN1bHQKCgpkZWYgX3BlcmZvcm1fZHJpZnRfYW5hbHlzaXMoCiAgICBzYW1wbGVfc2V0X3N0YXRpc3RpY3M6IGRpY3QsCiAgICBpbnB1dHM6IHBkLkRhdGFGcmFtZSwKICAgIGRyaWZ0X3RocmVzaG9sZDogZmxvYXQsCiAgICBwb3NzaWJsZV9kcmlmdF90aHJlc2hvbGQ6IGZsb2F0LAogICAgaW5mX2NhcHBpbmc6IGZsb2F0LAopIC0+IFR1cGxlW0FydGlmYWN0LCBBcnRpZmFjdCwgZGljdF06CiAgICAiIiIKICAgIFBlcmZvcm0gZHJpZnQgYW5hbHlzaXMsIHByb2R1Y2luZyB0aGUgZHJpZnQgdGFibGUgYXJ0aWZhY3QgZm9yIGxvZ2dpbmcgcG9zdCBwcmVkaWN0aW9uLgoKICAgIDpwYXJhbSBzYW1wbGVfc2V0X3N0YXRpc3RpY3M6ICAgIFRoZSBzdGF0aXN0aWNzIG9mIHRoZSBzYW1wbGUgc2V0IGxvZ2dlZCBhbG9uZyBhIG1vZGVsLgogICAgOnBhcmFtIGlucHV0czogICAgICAgICAgICAgICAgICAgSW5wdXQgZGF0YXNldCB0byBwZXJmb3JtIHRoZSBkcmlmdCBjYWxjdWxhdGlvbiBvbi4KICAgIDpwYXJhbSBkcmlmdF90aHJlc2hvbGQ6ICAgICAgICAgIFRoZSB0aHJlc2hvbGQgb2Ygd2hpY2ggdG8gbWFyayBkcmlmdHMuCiAgICA6cGFyYW0gcG9zc2libGVfZHJpZnRfdGhyZXNob2xkOiBUaGUgdGhyZXNob2xkIG9mIHdoaWNoIHRvIG1hcmsgcG9zc2libGUgZHJpZnRzLgogICAgOnBhcmFtIGluZl9jYXBwaW5nOiAgICAgICAgICAgICAgVGhlIHZhbHVlIHRvIHNldCBmb3Igd2hlbiBpdCByZWFjaGVkIGluZmluaXR5LgoKICAgIDpyZXR1cm5zOiBBIHR1cGxlIG9mCiAgICAgICAgICAgICAgWzBdID0gQW4gTUxSdW4gYXJ0aWZhY3QgaG9sZGluZyB0aGUgSFRNTCBjb2RlIG9mIHRoZSBkcmlmdCB0YWJsZSBwbG90LgogICAgICAgICAgICAgIFsxXSA9IEFuIE1MUnVuIGFydGlmYWN0IGhvbGRpbmcgdGhlIG1ldHJpYyBwZXIgZmVhdHVyZSBkaWN0aW9uYXJ5LgogICAgICAgICAgICAgIFsyXSA9IFJlc3VsdHMgdG8gbG9nIHRoZSBmaW5hbCBhbmFseXNpcyBvdXRjb21lLgogICAgIiIiCiAgICAjIENhbGN1bGF0ZSB0aGUgaW5wdXQncyBzdGF0aXN0aWNzOgogICAgaW5wdXRzX3N0YXRpc3RpY3MgPSBjYWxjdWxhdGVfaW5wdXRzX3N0YXRpc3RpY3MoCiAgICAgICAgc2FtcGxlX3NldF9zdGF0aXN0aWNzPXNhbXBsZV9zZXRfc3RhdGlzdGljcywKICAgICAgICBpbnB1dHM9aW5wdXRzLAogICAgKQoKICAgICMgQ2FsY3VsYXRlIGRyaWZ0OgogICAgdmlydHVhbF9kcmlmdCA9IFZpcnR1YWxEcmlmdChpbmZfY2FwcGluZz1pbmZfY2FwcGluZykKICAgIG1ldHJpY3MgPSB2aXJ0dWFsX2RyaWZ0LmNvbXB1dGVfZHJpZnRfZnJvbV9oaXN0b2dyYW1zKAogICAgICAgIGZlYXR1cmVfc3RhdHM9c2FtcGxlX3NldF9zdGF0aXN0aWNzLAogICAgICAgIGN1cnJlbnRfc3RhdHM9aW5wdXRzX3N0YXRpc3RpY3MsCiAgICApCiAgICBkcmlmdF9yZXN1bHRzID0gdmlydHVhbF9kcmlmdC5jaGVja19mb3JfZHJpZnRfcGVyX2ZlYXR1cmUoCiAgICAgICAgbWV0cmljc19yZXN1bHRzX2RpY3Rpb25hcnk9bWV0cmljcywKICAgICAgICBwb3NzaWJsZV9kcmlmdF90aHJlc2hvbGQ9cG9zc2libGVfZHJpZnRfdGhyZXNob2xkLAogICAgICAgIGRyaWZ0X2RldGVjdGVkX3RocmVzaG9sZD1kcmlmdF90aHJlc2hvbGQsCiAgICApCgogICAgIyBWYWxpZGF0ZSBhbGwgZmVhdHVyZSBjb2x1bW5zIG5hbWVkIHRoZSBzYW1lIGJldHdlZW4gdGhlIGlucHV0cyBhbmQgc2FtcGxlIHNldHM6CiAgICBzYW1wbGVfZmVhdHVyZXMgPSBzZXQoCiAgICAgICAgWwogICAgICAgICAgICBmZWF0dXJlX25hbWUKICAgICAgICAgICAgZm9yIGZlYXR1cmVfbmFtZSwgZmVhdHVyZV9zdGF0aXN0aWNzIGluIHNhbXBsZV9zZXRfc3RhdGlzdGljcy5pdGVtcygpCiAgICAgICAgICAgIGlmIGlzaW5zdGFuY2UoZmVhdHVyZV9zdGF0aXN0aWNzLCBkaWN0KQogICAgICAgIF0KICAgICkKICAgIGlucHV0X2ZlYXR1cmVzID0gc2V0KGlucHV0cy5jb2x1bW5zKQogICAgaWYgbGVuKHNhbXBsZV9mZWF0dXJlcyAmIGlucHV0X2ZlYXR1cmVzKSAhPSBsZW4oaW5wdXRfZmVhdHVyZXMpOgogICAgICAgIHJhaXNlIG1scnVuLmVycm9ycy5NTFJ1bkludmFsaWRBcmd1bWVudEVycm9yKAogICAgICAgICAgICBmIk5vdCBhbGwgZmVhdHVyZSBuYW1lcyB3ZXJlIG1hdGNoaW5nIGJldHdlZW4gdGhlIGlucHV0cyBhbmQgdGhlIHNhbXBsZSBzZXQgcHJvdmlkZWQ6ICIKICAgICAgICAgICAgZiJ7aW5wdXRfZmVhdHVyZXMgLSBzYW1wbGVfZmVhdHVyZXMgfCBzYW1wbGVfZmVhdHVyZXMgLSBpbnB1dF9mZWF0dXJlc30iCiAgICAgICAgKQoKICAgICMgUGxvdDoKICAgIGh0bWxfcGxvdCA9IEZlYXR1cmVzRHJpZnRUYWJsZVBsb3QoKS5wcm9kdWNlKAogICAgICAgIGZlYXR1cmVzPWxpc3QoaW5wdXRfZmVhdHVyZXMpLAogICAgICAgIHNhbXBsZV9zZXRfc3RhdGlzdGljcz1zYW1wbGVfc2V0X3N0YXRpc3RpY3MsCiAgICAgICAgaW5wdXRzX3N0YXRpc3RpY3M9aW5wdXRzX3N0YXRpc3RpY3MsCiAgICAgICAgbWV0cmljcz1tZXRyaWNzLAogICAgICAgIGRyaWZ0X3Jlc3VsdHM9ZHJpZnRfcmVzdWx0cywKICAgICkKCiAgICAjIFByZXBhcmUgbWV0cmljcyBwZXIgZmVhdHVyZSBkaWN0aW9uYXJ5OgogICAgbWV0cmljc19wZXJfZmVhdHVyZSA9IHsKICAgICAgICBmZWF0dXJlOiBfZ2V0X2RyaWZ0X3Jlc3VsdCgKICAgICAgICAgICAgdHZkPW1ldHJpY19kaWN0aW9uYXJ5WyJ0dmQiXSwKICAgICAgICAgICAgaGVsbGluZ2VyPW1ldHJpY19kaWN0aW9uYXJ5WyJoZWxsaW5nZXIiXSwKICAgICAgICAgICAgdGhyZXNob2xkPWRyaWZ0X3RocmVzaG9sZCwKICAgICAgICApWzFdCiAgICAgICAgZm9yIGZlYXR1cmUsIG1ldHJpY19kaWN0aW9uYXJ5IGluIG1ldHJpY3MuaXRlbXMoKQogICAgICAgIGlmIGlzaW5zdGFuY2UobWV0cmljX2RpY3Rpb25hcnksIGRpY3QpCiAgICB9CgogICAgIyBDYWxjdWxhdGUgdGhlIGZpbmFsIGFuYWx5c2lzIHJlc3VsdDoKICAgIGRyaWZ0X3N0YXR1cywgZHJpZnRfbWV0cmljID0gX2dldF9kcmlmdF9yZXN1bHQoCiAgICAgICAgdHZkPW1ldHJpY3NbInR2ZF9tZWFuIl0sCiAgICAgICAgaGVsbGluZ2VyPW1ldHJpY3NbImhlbGxpbmdlcl9tZWFuIl0sCiAgICAgICAgdGhyZXNob2xkPWRyaWZ0X3RocmVzaG9sZCwKICAgICkKCiAgICByZXR1cm4gKAogICAgICAgIEFydGlmYWN0KGJvZHk9aHRtbF9wbG90LCBmb3JtYXQ9Imh0bWwiLCBrZXk9ImRyaWZ0X3RhYmxlX3Bsb3QiKSwKICAgICAgICBBcnRpZmFjdCgKICAgICAgICAgICAgYm9keT1qc29uLmR1bXBzKG1ldHJpY3NfcGVyX2ZlYXR1cmUpLAogICAgICAgICAgICBmb3JtYXQ9Impzb24iLAogICAgICAgICAgICBrZXk9ImZlYXR1cmVzX2RyaWZ0X3Jlc3VsdHMiLAogICAgICAgICksCiAgICAgICAgeyJkcmlmdF9zdGF0dXMiOiBkcmlmdF9zdGF0dXMsICJkcmlmdF9tZXRyaWMiOiBkcmlmdF9tZXRyaWN9LAogICAgKQoKCmRlZiBpbmZlcigKICAgIGNvbnRleHQ6IG1scnVuLk1MQ2xpZW50Q3R4LAogICAgbW9kZWw6IHN0ciwKICAgIGRhdGFzZXQ6IERhdGFzZXRUeXBlLAogICAgZHJvcF9jb2x1bW5zOiBVbmlvbltzdHIsIExpc3Rbc3RyXSwgaW50LCBMaXN0W2ludF1dID0gTm9uZSwKICAgIGxhYmVsX2NvbHVtbnM6IFVuaW9uW3N0ciwgTGlzdFtzdHJdXSA9IE5vbmUsCiAgICBmZWF0dXJlX2NvbHVtbnM6IFVuaW9uW3N0ciwgTGlzdFtzdHJdXSA9IE5vbmUsCiAgICBsb2dfcmVzdWx0X3NldDogYm9vbCA9IFRydWUsCiAgICByZXN1bHRfc2V0X25hbWU6IHN0ciA9ICJwcmVkaWN0aW9uIiwKICAgIGJhdGNoX2lkOiBzdHIgPSBOb25lLAogICAgcGVyZm9ybV9kcmlmdF9hbmFseXNpczogYm9vbCA9IE5vbmUsCiAgICBzYW1wbGVfc2V0OiBEYXRhc2V0VHlwZSA9IE5vbmUsCiAgICBkcmlmdF90aHJlc2hvbGQ6IGZsb2F0ID0gMC43LAogICAgcG9zc2libGVfZHJpZnRfdGhyZXNob2xkOiBmbG9hdCA9IDAuNSwKICAgIGluZl9jYXBwaW5nOiBmbG9hdCA9IDEwLjAsCiAgICBhcnRpZmFjdHNfdGFnOiBzdHIgPSAiIiwKICAgICoqcHJlZGljdF9rd2FyZ3M6IERpY3Rbc3RyLCBBbnldLAopOgogICAgIiIiCiAgICBQZXJmb3JtIGEgcHJlZGljdGlvbiBvbiBhIGdpdmVuIGRhdGFzZXQgd2l0aCB0aGUgZ2l2ZW4gbW9kZWwuIENhbiBwZXJmb3JtIGRyaWZ0IGFuYWx5c2lzIGJldHdlZW4gdGhlIHNhbXBsZSBzZXQKICAgIHN0YXRpc3RpY3Mgc3RvcmVkIGluIHRoZSBtb2RlbCB0byB0aGUgY3VycmVudCBpbnB1dCBkYXRhLiBUaGUgZHJpZnQgcnVsZSBpcyB0aGUgdmFsdWUgcGVyLWZlYXR1cmUgbWVhbiBvZiB0aGUgVFZECiAgICBhbmQgSGVsbGluZ2VyIHNjb3JlcyBhY2NvcmRpbmcgdG8gdGhlIHRocmVzaG9sZHMgY29uZmlndXJlcyBoZXJlLgoKICAgIDpwYXJhbSBjb250ZXh0OiAgICAgICAgICAgICAgICAgIE1MUnVuIGNvbnRleHQuCiAgICA6cGFyYW0gbW9kZWw6ICAgICAgICAgICAgICAgICAgICBUaGUgbW9kZWwgU3RvcmUgcGF0aC4KICAgIDpwYXJhbSBkYXRhc2V0OiAgICAgICAgICAgICAgICAgIFRoZSBkYXRhc2V0IHRvIGluZmVyIHRocm91Z2ggdGhlIG1vZGVsLiBDYW4gYmUgcGFzc2VkIGluIGBpbnB1dHNgIGFzIGVpdGhlciBhCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEYXRhc2V0IGFydGlmYWN0IC8gRmVhdHVyZSB2ZWN0b3IgVVJJLiBPciwgaW4gYHBhcmFtZXRlcnNgIGFzIGEgbGlzdCwgZGljdGlvbmFyeSBvcgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVtcHkgYXJyYXkuCiAgICA6cGFyYW0gZHJvcF9jb2x1bW5zOiAgICAgICAgICAgICBBIHN0cmluZyAvIGludGVnZXIgb3IgYSBsaXN0IG9mIHN0cmluZ3MgLyBpbnRlZ2VycyB0aGF0IHJlcHJlc2VudCB0aGUgY29sdW1uIG5hbWVzCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvIGluZGljZXMgdG8gZHJvcC4gV2hlbiB0aGUgZGF0YXNldCBpcyBhIGxpc3Qgb3IgYSBudW1weSBhcnJheSB0aGlzIHBhcmFtZXRlciBtdXN0CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiZSByZXByZXNlbnRlZCBieSBpbnRlZ2Vycy4KICAgIDpwYXJhbSBsYWJlbF9jb2x1bW5zOiAgICAgICAgICAgIFRoZSB0YXJnZXQgbGFiZWwocykgb2YgdGhlIGNvbHVtbihzKSBpbiB0aGUgZGF0YXNldCBmb3IgUmVncmVzc2lvbiBvcgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ2xhc3NpZmljYXRpb24gdGFza3MuIFRoZSBsYWJlbCBjb2x1bW4gY2FuIGJlIGFjY2Vzc2VkIGZyb20gdGhlIG1vZGVsIG9iamVjdCwgb3IKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZSBmZWF0dXJlIHZlY3RvciBwcm92aWRlZCBpZiBhdmFpbGFibGUuCiAgICA6cGFyYW0gZmVhdHVyZV9jb2x1bW5zOiAgICAgICAgICBMaXN0IG9mIGZlYXR1cmUgY29sdW1ucyB0aGF0IHdpbGwgYmUgdXNlZCB0byBidWlsZCB0aGUgZGF0YWZyYW1lIHdoZW4gZGF0YXNldCBpcwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZnJvbSB0eXBlIGxpc3Qgb3IgbnVtcHkgYXJyYXkuCiAgICA6cGFyYW0gbG9nX3Jlc3VsdF9zZXQ6ICAgICAgICAgICBXaGV0aGVyIHRvIGxvZyB0aGUgcmVzdWx0IHNldCAtIGEgRGF0YUZyYW1lIG9mIHRoZSBnaXZlbiBpbnB1dHMgY29uY2F0ZW5hdGVkIHdpdGgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZSBwcmVkaWN0aW9ucy4gRGVmYXVsdGVkIHRvIFRydWUuCiAgICA6cGFyYW0gcmVzdWx0X3NldF9uYW1lOiAgICAgICAgICBUaGUgZGIga2V5IHRvIHNldCBuYW1lIG9mIHRoZSBwcmVkaWN0aW9uIHJlc3VsdCBhbmQgdGhlIGZpbGVuYW1lLiBEZWZhdWx0ZWQgdG8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdwcmVkaWN0aW9uJy4KICAgIDpwYXJhbSBiYXRjaF9pZDogICAgICAgICAgICAgICAgIFRoZSBJRCBvZiB0aGUgZ2l2ZW4gYmF0Y2ggKGluZmVyZW5jZSBkYXRhc2V0KS4gSWYgYE5vbmVgLCBpdCB3aWxsIGJlIGdlbmVyYXRlZC4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdpbGwgYmUgbG9nZ2VkIGFzIGEgcmVzdWx0IG9mIHRoZSBydW4uCiAgICA6cGFyYW0gcGVyZm9ybV9kcmlmdF9hbmFseXNpczogICBXaGV0aGVyIHRvIHBlcmZvcm0gZHJpZnQgYW5hbHlzaXMgYmV0d2VlbiB0aGUgc2FtcGxlIHNldCBvZiB0aGUgbW9kZWwgb2JqZWN0IHRvIHRoZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YXNldCBnaXZlbi4gQnkgZGVmYXVsdCwgTm9uZSwgd2hpY2ggbWVhbnMgaXQgd2lsbCBwZXJmb3JtIGRyaWZ0IGFuYWx5c2lzIGlmIHRoZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbW9kZWwgaGFzIGEgc2FtcGxlIHNldCBzdGF0aXN0aWNzLiBQZXJmb3JtIGRyaWZ0IGFuYWx5c2lzIHdpbGwgcHJvZHVjZSBhIGRhdGEgZHJpZnQKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhYmxlIGFydGlmYWN0LgogICAgOnBhcmFtIHNhbXBsZV9zZXQ6ICAgICAgICAgICAgICAgQSBzYW1wbGUgZGF0YXNldCB0byBnaXZlIHRvIGNvbXBhcmUgdGhlIGlucHV0cyBpbiB0aGUgZHJpZnQgYW5hbHlzaXMuIFRoZSBkZWZhdWx0CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaG9zZW4gc2FtcGxlIHNldCB3aWxsIGFsd2F5cyBiZSB0aGUgb25lIHdobyBpcyBzZXQgaW4gdGhlIG1vZGVsIGFydGlmYWN0IGl0c2VsZi4KICAgIDpwYXJhbSBkcmlmdF90aHJlc2hvbGQ6ICAgICAgICAgIFRoZSB0aHJlc2hvbGQgb2Ygd2hpY2ggdG8gbWFyayBkcmlmdHMuIERlZmF1bHRlZCB0byAwLjcuCiAgICA6cGFyYW0gcG9zc2libGVfZHJpZnRfdGhyZXNob2xkOiBUaGUgdGhyZXNob2xkIG9mIHdoaWNoIHRvIG1hcmsgcG9zc2libGUgZHJpZnRzLiBEZWZhdWx0ZWQgdG8gMC41LgogICAgOnBhcmFtIGluZl9jYXBwaW5nOiAgICAgICAgICAgICAgVGhlIHZhbHVlIHRvIHNldCBmb3Igd2hlbiBpdCByZWFjaGVkIGluZmluaXR5LiBEZWZhdWx0ZWQgdG8gMTAuMC4KICAgIDpwYXJhbSBhcnRpZmFjdHNfdGFnOiAgICAgICAgICAgIFRhZyB0byB1c2UgZm9yIGFsbCB0aGUgYXJ0aWZhY3RzIHJlc3VsdGVkIGZyb20gdGhlIGZ1bmN0aW9uLgogICAgIiIiCiAgICAjIExvYWRpbmcgdGhlIG1vZGVsOgogICAgY29udGV4dC5sb2dnZXIuaW5mbyhmIkxvYWRpbmcgbW9kZWwuLi4iKQogICAgbW9kZWxfaGFuZGxlciA9IEF1dG9NTFJ1bi5sb2FkX21vZGVsKG1vZGVsX3BhdGg9bW9kZWwsIGNvbnRleHQ9Y29udGV4dCkKICAgIGlmIGxhYmVsX2NvbHVtbnMgaXMgTm9uZToKICAgICAgICBsYWJlbF9jb2x1bW5zID0gWwogICAgICAgICAgICBvdXRwdXQubmFtZSBmb3Igb3V0cHV0IGluIG1vZGVsX2hhbmRsZXIuX21vZGVsX2FydGlmYWN0LnNwZWMub3V0cHV0cwogICAgICAgIF0KCiAgICBpZiBmZWF0dXJlX2NvbHVtbnMgaXMgTm9uZToKICAgICAgICBmZWF0dXJlX2NvbHVtbnMgPSBbCiAgICAgICAgICAgIGlucHV0Lm5hbWUgZm9yIGlucHV0IGluIG1vZGVsX2hhbmRsZXIuX21vZGVsX2FydGlmYWN0LnNwZWMuaW5wdXRzCiAgICAgICAgXQoKICAgICMgR2V0IGRhdGFzZXQgYnkgb2JqZWN0LCBVUkwgb3IgYnkgRmVhdHVyZVZlY3RvcjoKICAgIGNvbnRleHQubG9nZ2VyLmluZm8oZiJMb2FkaW5nIGRhdGEuLi4iKQogICAgeCwgbGFiZWxfY29sdW1ucyA9IF9yZWFkX2RhdGFzZXRfYXNfZGF0YWZyYW1lKAogICAgICAgIGRhdGFzZXQ9ZGF0YXNldCwKICAgICAgICBmZWF0dXJlX2NvbHVtbnM9ZmVhdHVyZV9jb2x1bW5zLAogICAgICAgIGxhYmVsX2NvbHVtbnM9bGFiZWxfY29sdW1ucywKICAgICAgICBkcm9wX2NvbHVtbnM9ZHJvcF9jb2x1bW5zLAogICAgKQoKICAgICMgUHJlZGljdDoKICAgIGNvbnRleHQubG9nZ2VyLmluZm8oZiJDYWxjdWxhdGluZyBwcmVkaWN0aW9uLi4uIikKICAgIHlfcHJlZCA9IG1vZGVsX2hhbmRsZXIubW9kZWwucHJlZGljdCh4LCAqKnByZWRpY3Rfa3dhcmdzKQoKICAgICMgUHJlcGFyZSB0aGUgcmVzdWx0IHNldDoKICAgIHJlc3VsdF9zZXQgPSBfcHJlcGFyZV9yZXN1bHRfc2V0KHg9eCwgbGFiZWxfY29sdW1ucz1sYWJlbF9jb2x1bW5zLCB5X3ByZWQ9eV9wcmVkKQoKICAgICMgQ2hlY2sgZm9yIGxvZ2dpbmcgdGhlIHJlc3VsdCBzZXQ6CiAgICBpZiBsb2dfcmVzdWx0X3NldDoKICAgICAgICAjIExvZyB0aGUgcmVzdWx0IHNldDoKICAgICAgICBjb250ZXh0LmxvZ2dlci5pbmZvKGYiTG9nZ2luZyByZXN1bHQgc2V0ICh4IHwgcHJlZGljdGlvbikuLi4iKQogICAgICAgIGNvbnRleHQubG9nX2RhdGFzZXQoCiAgICAgICAgICAgIGtleT1yZXN1bHRfc2V0X25hbWUsCiAgICAgICAgICAgIGRmPXJlc3VsdF9zZXQsCiAgICAgICAgICAgIGRiX2tleT1yZXN1bHRfc2V0X25hbWUsCiAgICAgICAgICAgIHRhZz1hcnRpZmFjdHNfdGFnLAogICAgICAgICkKICAgICAgICAjIExvZyB0aGUgYmF0Y2ggSUQ6CiAgICAgICAgaWYgYmF0Y2hfaWQgaXMgTm9uZToKICAgICAgICAgICAgYmF0Y2hfaWQgPSBoYXNobGliLnNoYTIyNChzdHIoZGF0ZXRpbWUubm93KCkpLmVuY29kZSgpKS5oZXhkaWdlc3QoKQogICAgICAgIGNvbnRleHQubG9nX3Jlc3VsdCgKICAgICAgICAgICAga2V5PSJiYXRjaF9pZCIsCiAgICAgICAgICAgIHZhbHVlPWJhdGNoX2lkLAogICAgICAgICkKCiAgICAjIENoZWNrIGZvciBwZXJmb3JtaW5nIGRyaWZ0IGFuYWx5c2lzOgogICAgaWYgKAogICAgICAgIHBlcmZvcm1fZHJpZnRfYW5hbHlzaXMgaXMgTm9uZQogICAgICAgIGFuZCBtb2RlbF9oYW5kbGVyLl9tb2RlbF9hcnRpZmFjdC5zcGVjLmZlYXR1cmVfc3RhdHMgaXMgbm90IE5vbmUKICAgICk6CiAgICAgICAgcGVyZm9ybV9kcmlmdF9hbmFseXNpcyA9IFRydWUKICAgIGlmIHBlcmZvcm1fZHJpZnRfYW5hbHlzaXM6CiAgICAgICAgY29udGV4dC5sb2dnZXIuaW5mbygiUGVyZm9ybWluZyBkcmlmdCBhbmFseXNpcy4uLiIpCiAgICAgICAgIyBHZXQgdGhlIHNhbXBsZSBzZXQgc3RhdGlzdGljcyAoZWl0aGVyIGZyb20gdGhlIHNhbXBsZSBzZXQgb3IgZnJvbSB0aGUgc3RhdGlzdGljcyBsb2dnZWQgd2l0aCB0aGUgbW9kZWwpOgogICAgICAgIHNhbXBsZV9zZXRfc3RhdGlzdGljcyA9IF9nZXRfc2FtcGxlX3NldF9zdGF0aXN0aWNzKAogICAgICAgICAgICBzYW1wbGVfc2V0PXNhbXBsZV9zZXQsCiAgICAgICAgICAgIG1vZGVsX2FydGlmYWN0X2ZlYXR1cmVfc3RhdHM9bW9kZWxfaGFuZGxlci5fbW9kZWxfYXJ0aWZhY3Quc3BlYy5mZWF0dXJlX3N0YXRzLAogICAgICAgICkKICAgICAgICAjIFByb2R1Y2UgdGhlIGFydGlmYWN0OgogICAgICAgICgKICAgICAgICAgICAgZHJpZnRfdGFibGVfcGxvdCwKICAgICAgICAgICAgbWV0cmljX3Blcl9mZWF0dXJlX2RpY3QsCiAgICAgICAgICAgIGFuYWx5c2lzX3Jlc3VsdHMsCiAgICAgICAgKSA9IF9wZXJmb3JtX2RyaWZ0X2FuYWx5c2lzKAogICAgICAgICAgICBzYW1wbGVfc2V0X3N0YXRpc3RpY3M9c2FtcGxlX3NldF9zdGF0aXN0aWNzLAogICAgICAgICAgICBpbnB1dHM9cmVzdWx0X3NldCwKICAgICAgICAgICAgZHJpZnRfdGhyZXNob2xkPWRyaWZ0X3RocmVzaG9sZCwKICAgICAgICAgICAgcG9zc2libGVfZHJpZnRfdGhyZXNob2xkPXBvc3NpYmxlX2RyaWZ0X3RocmVzaG9sZCwKICAgICAgICAgICAgaW5mX2NhcHBpbmc9aW5mX2NhcHBpbmcsCiAgICAgICAgKQogICAgICAgICMgTG9nIHRoZSBhcnRpZmFjdCBhbmQgcmVzdWx0czoKICAgICAgICBjb250ZXh0LmxvZ19hcnRpZmFjdChkcmlmdF90YWJsZV9wbG90LCB0YWc9YXJ0aWZhY3RzX3RhZykKICAgICAgICBjb250ZXh0LmxvZ19hcnRpZmFjdChtZXRyaWNfcGVyX2ZlYXR1cmVfZGljdCwgdGFnPWFydGlmYWN0c190YWcpCiAgICAgICAgY29udGV4dC5sb2dfcmVzdWx0cyhyZXN1bHRzPWFuYWx5c2lzX3Jlc3VsdHMpCg==
    origin_filename: ''
    auto_build: false
    code_origin: ''
    with_mlrun: false
  disable_auto_mount: false
  description: Batch inference (also knows as prediction) for the common ML frameworks
    (SciKit-Learn, XGBoost and LightGBM) while performing data drift analysis.