From 0e7549c5429b5aa3fd85409dd339eaf44dd92c42 Mon Sep 17 00:00:00 2001 From: Miles Granger Date: Tue, 18 Feb 2020 14:34:29 +0100 Subject: [PATCH] Support reporting expected models (#911) --- gordo/server/server.py | 6 ++++-- gordo/server/views/base.py | 7 +++++++ .../resources/argo-workflow.yml.template | 2 ++ tests/gordo/server/test_gordo_server.py | 17 ++++++++++++++++ .../test_workflow_generator.py | 20 +++++++++++++++++++ 5 files changed, 50 insertions(+), 2 deletions(-) diff --git a/gordo/server/server.py b/gordo/server/server.py index 19b5191fb..dfeec9d7a 100644 --- a/gordo/server/server.py +++ b/gordo/server/server.py @@ -14,7 +14,7 @@ import subprocess from functools import wraps - +import yaml from flask import Flask, g, request, current_app, make_response, jsonify from gordo.server import views from gordo import __version__ @@ -25,7 +25,9 @@ class Config: """Server config""" - MODEL_COLLECTION_DIR_ENV_VAR = "MODEL_COLLECTION_DIR" + def __init__(self): + self.MODEL_COLLECTION_DIR_ENV_VAR = "MODEL_COLLECTION_DIR" + self.EXPECTED_MODELS = yaml.safe_load(os.getenv("EXPECTED_MODELS", "[]")) def adapt_proxy_deployment(wsgi_app: typing.Callable) -> typing.Callable: diff --git a/gordo/server/views/base.py b/gordo/server/views/base.py index b4e132c9c..f99961d98 100644 --- a/gordo/server/views/base.py +++ b/gordo/server/views/base.py @@ -268,7 +268,14 @@ def get(self, gordo_project: str): ) +class ExpectedModels(Resource): + @api.doc(description="Models that the server expects to be able to serve.") + def get(self, gordo_project: str): + return jsonify({"expected-models": current_app.config["EXPECTED_MODELS"]}) + + api.add_resource(ModelListView, "/gordo/v0//models") +api.add_resource(ExpectedModels, "/gordo/v0//expected-models") api.add_resource(BaseModelView, "/gordo/v0///prediction") api.add_resource( MetaDataView, diff --git a/gordo/workflow/workflow_generator/resources/argo-workflow.yml.template b/gordo/workflow/workflow_generator/resources/argo-workflow.yml.template index 5e84d16fc..2780e86c9 100644 --- a/gordo/workflow/workflow_generator/resources/argo-workflow.yml.template +++ b/gordo/workflow/workflow_generator/resources/argo-workflow.yml.template @@ -876,6 +876,8 @@ spec: value: /gordo/models/{{project_name}}/{{project_revision}} - name: GORDO_LOG_LEVEL value: "{{log_level}}" + - name: EXPECTED_MODELS + value: [{% for machine in machines %}"{{ machine.name }}",{% endfor %}] resources: requests: diff --git a/tests/gordo/server/test_gordo_server.py b/tests/gordo/server/test_gordo_server.py index 41496a5cf..6283af0be 100644 --- a/tests/gordo/server/test_gordo_server.py +++ b/tests/gordo/server/test_gordo_server.py @@ -295,3 +295,20 @@ def test_non_existant_model_metadata(tmpdir, gordo_project, api_version): f"/gordo/{api_version}/{gordo_project}/model-does-not-exist/metadata" ) assert resp.status_code == 404 + + +def test_expected_models_route(tmpdir): + """ + Route that gives back the expected models names, which are just read from + the 'EXPECTED_MODELS' env var. + """ + with tu.temp_env_vars( + MODEL_COLLECTION_DIR=str(tmpdir), + EXPECTED_MODELS=json.dumps(["model-a", "model-b"]), + ): + app = server.build_app() + app.testing = True + client = app.test_client() + + resp = client.get("/gordo/v0/test-project/expected-models") + assert resp.json["expected-models"] == ["model-a", "model-b"] diff --git a/tests/gordo/workflow/test_workflow_generator/test_workflow_generator.py b/tests/gordo/workflow/test_workflow_generator/test_workflow_generator.py index 43ca2faa5..a66aabe99 100644 --- a/tests/gordo/workflow/test_workflow_generator/test_workflow_generator.py +++ b/tests/gordo/workflow/test_workflow_generator/test_workflow_generator.py @@ -480,3 +480,23 @@ def test_log_level_key(test_file: str, log_level: str, path_to_config_files: str # Assert all the values to the GORDO_LOG_LEVEL key contains the correct log-level assert all([log_level in value for value in gordo_log_levels]) + + +def test_expected_models_in_workflow(repo_dir): + """ + Server deployment depends on EXPECTED_MODELS env var being set, + which is a list of strings, indicating the expected model names to be served. + """ + workflow_str = _generate_test_workflow_str( + path_to_config_files=os.path.join(repo_dir, "examples"), + config_filename="config.yaml", + ) + assert "name: EXPECTED_MODELS" in workflow_str + + # Not the prettiest, but a whole lot prettier than digging down into the workflow yaml + # basically want to get to 'gordo-server-deployment' and ensure the EXPECTED_MODELS env var + # is set with a list (in string form) of model names which can be loaded. + expected_models_str = ( + workflow_str.split("EXPECTED_MODELS")[1].split("value:")[1].split("\n")[0] + ) + assert isinstance(yaml.safe_load(expected_models_str), list)