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.