From a49313bf6c73cf8ea299db4a5edf59c4d4b24f3a Mon Sep 17 00:00:00 2001 From: Peter Prettenhofer Date: Mon, 7 Jan 2019 21:55:10 +0100 Subject: [PATCH 1/5] PRED-2194 use old reasonCodesPredictions route to support 4.3.x installs --- CHANGES.rst | 9 ++++++++- datarobot_batch_scoring/__init__.py | 2 +- .../api_response_handlers/pred_api_v10.py | 13 ++++++++++--- datarobot_batch_scoring/batch_scoring.py | 2 +- 4 files changed, 20 insertions(+), 6 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 4b11149e..b9bbe580 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,3 +1,10 @@ +1.15.3 (2019 Jan 7) +=================== + +Bugfixes +-------- +* Added support for ``--max_prediction_explanations`` on DataRobot 4.3.x . + 1.15.2 (2018 Dec 17) ===================== @@ -17,7 +24,7 @@ Enhancements Enhancements ------------ -* Added new argument ``-max_prediction_explanations`` that allows batch scoring with predictions explanations and adds ``explanation_N_feature`` and ``explanation_N_strength`` to each row in output document (where ``N ∈ (1, max_prediction_explanations)`` ) +* Added new argument ``--max_prediction_explanations`` that allows batch scoring with predictions explanations and adds ``explanation_N_feature`` and ``explanation_N_strength`` to each row in output document (where ``N ∈ (1, max_prediction_explanations)`` ) 1.14.2 (2018 Nov 14) ==================== diff --git a/datarobot_batch_scoring/__init__.py b/datarobot_batch_scoring/__init__.py index 18ddad07..0f5df046 100644 --- a/datarobot_batch_scoring/__init__.py +++ b/datarobot_batch_scoring/__init__.py @@ -1 +1 @@ -__version__ = '1.15.2' +__version__ = '1.15.3.dev0' diff --git a/datarobot_batch_scoring/api_response_handlers/pred_api_v10.py b/datarobot_batch_scoring/api_response_handlers/pred_api_v10.py index 79b95d72..f8234e66 100644 --- a/datarobot_batch_scoring/api_response_handlers/pred_api_v10.py +++ b/datarobot_batch_scoring/api_response_handlers/pred_api_v10.py @@ -71,8 +71,15 @@ def format_data(result, batch, **opts): written_fields = out_fields[1:] comb = [row[1:] for row in pred] - if 'predictionExplanations' in single_row: - num_reason_codes = len(single_row['predictionExplanations']) + prediction_explanations_keys = ('predictionExplanations', 'reasonCodes', None) + + def _find_prediction_explanations_key(): + return [key for key in prediction_explanations_keys + if key in single_row or key is None][0] + + prediction_explanations_key = _find_prediction_explanations_key() + if prediction_explanations_key: + num_reason_codes = len(single_row[prediction_explanations_key]) for num in range(1, num_reason_codes + 1): written_fields += [ 'explanation_{0}_feature'.format(num), @@ -80,7 +87,7 @@ def format_data(result, batch, **opts): ] for in_row, out_row in zip(result, comb): reason_codes = [] - for raw_reason_code in in_row['predictionExplanations']: + for raw_reason_code in in_row[prediction_explanations_key]: reason_codes += [ raw_reason_code['feature'], raw_reason_code['strength'] diff --git a/datarobot_batch_scoring/batch_scoring.py b/datarobot_batch_scoring/batch_scoring.py index b8e629b7..bc771f5c 100644 --- a/datarobot_batch_scoring/batch_scoring.py +++ b/datarobot_batch_scoring/batch_scoring.py @@ -133,7 +133,7 @@ def run_batch_predictions(base_url, base_headers, user, pwd, endpoint = base_url + '/'.join((pid, lid)) if max_prediction_explanations: - endpoint += '/predictionExplanations?maxCodes=' + \ + endpoint += '/reasonCodesPredictions?maxCodes=' + \ str(max_prediction_explanations) else: if deployment_id is not None: From b002c9dc42f07a8286ccfacee079b29e497a2a7b Mon Sep 17 00:00:00 2001 From: Peter Prettenhofer Date: Mon, 7 Jan 2019 22:10:07 +0100 Subject: [PATCH 2/5] ensure that deployment aware routes use predictionExplanations --- datarobot_batch_scoring/batch_scoring.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/datarobot_batch_scoring/batch_scoring.py b/datarobot_batch_scoring/batch_scoring.py index bc771f5c..4eb7d54b 100644 --- a/datarobot_batch_scoring/batch_scoring.py +++ b/datarobot_batch_scoring/batch_scoring.py @@ -133,8 +133,15 @@ def run_batch_predictions(base_url, base_headers, user, pwd, endpoint = base_url + '/'.join((pid, lid)) if max_prediction_explanations: - endpoint += '/reasonCodesPredictions?maxCodes=' + \ - str(max_prediction_explanations) + if deployment_id is not None: + # Deployment routes only support predictionExplanations. + endpoint += '/predictionExplanations?maxCodes=' + else: + # For non-deployment routes we use the old reasonCodesRoutes + # to support 4.3.x releases. + endpoint += '/reasonCodesPredictions?maxCodes=' + + endpoint += str(max_prediction_explanations) else: if deployment_id is not None: endpoint += '/predictions' From ed1657405c0b4f0dcee1f5302f7ca8e6ad9039ee Mon Sep 17 00:00:00 2001 From: Peter Prettenhofer Date: Mon, 7 Jan 2019 22:17:43 +0100 Subject: [PATCH 3/5] cosmit: pep8 --- datarobot_batch_scoring/api_response_handlers/pred_api_v10.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/datarobot_batch_scoring/api_response_handlers/pred_api_v10.py b/datarobot_batch_scoring/api_response_handlers/pred_api_v10.py index f8234e66..fc643476 100644 --- a/datarobot_batch_scoring/api_response_handlers/pred_api_v10.py +++ b/datarobot_batch_scoring/api_response_handlers/pred_api_v10.py @@ -71,7 +71,8 @@ def format_data(result, batch, **opts): written_fields = out_fields[1:] comb = [row[1:] for row in pred] - prediction_explanations_keys = ('predictionExplanations', 'reasonCodes', None) + prediction_explanations_keys = ('predictionExplanations', 'reasonCodes', + None) def _find_prediction_explanations_key(): return [key for key in prediction_explanations_keys From d741bb9affd7566f90db10ec9b830a13107bf907 Mon Sep 17 00:00:00 2001 From: Peter Prettenhofer Date: Wed, 9 Jan 2019 14:28:58 +0100 Subject: [PATCH 4/5] update liveserver for reasonCodesPredictions routes --- tests/liveserver_fixtures.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/liveserver_fixtures.py b/tests/liveserver_fixtures.py index 587a3488..db0b1943 100644 --- a/tests/liveserver_fixtures.py +++ b/tests/liveserver_fixtures.py @@ -190,6 +190,8 @@ def post_auth(): @app.route('/predApi/v1.0///predict', methods=["POST"]) @app.route('/predApi/v1.0///predictionExplanations', methods=["POST"]) + @app.route('/predApi/v1.0///reasonCodesPredictions', + methods=["POST"]) @app.route('/api/v1///predict', methods=["POST"]) def predict_sinc(pid, lid): return _predict(lid) @@ -205,6 +207,8 @@ def predict_deployment_aware(deployment_id): @app.route('/predApi/v1.0//predict', methods=["POST"]) @app.route('/predApi/v1.0//predictionExplanations', methods=["POST"]) + @app.route('/predApi/v1.0//reasonCodesPredictions', + methods=["POST"]) @app.route('/api/v1//predict', methods=["POST"]) def predict_transferable(import_id): return _predict(import_id) From 64e7f1c3af7ea86eaf578c270f8ff216b5c71c15 Mon Sep 17 00:00:00 2001 From: Peter Prettenhofer Date: Wed, 9 Jan 2019 14:54:25 +0100 Subject: [PATCH 5/5] cut official 1.15.3 --- datarobot_batch_scoring/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/datarobot_batch_scoring/__init__.py b/datarobot_batch_scoring/__init__.py index 0f5df046..5fdff846 100644 --- a/datarobot_batch_scoring/__init__.py +++ b/datarobot_batch_scoring/__init__.py @@ -1 +1 @@ -__version__ = '1.15.3.dev0' +__version__ = '1.15.3'