From 82ec27944b7adb9dc48134f762a19b9d74953cd8 Mon Sep 17 00:00:00 2001 From: marshHawk4 Date: Fri, 14 Jul 2023 14:41:10 -0400 Subject: [PATCH 1/7] interventions --- api/models.py | 5 +++++ api/server.py | 18 ++++++++++++++++-- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/api/models.py b/api/models.py index dd5f6cc..7030705 100644 --- a/api/models.py +++ b/api/models.py @@ -91,11 +91,16 @@ class Dataset(BaseModel): example={'postive_tests': 'infected'}, ) +class InterventionObject(BaseModel): + timestep: float + name: str + value: float class SimulatePostRequest(BaseModel): engine: Engine = Field(..., example="ciemss") model_config_id: str = Field(..., example="ba8da8d4-047d-11ee-be56") timespan: Timespan + interventions: Optional[List[InterventionObject]] = Field(None, example=[{"timestep":1,"name":"beta","value":.4}]) extra: SimulateExtra = Field( None, description="optional extra system specific arguments for advanced use cases", diff --git a/api/server.py b/api/server.py index 928d49a..67fc6ec 100644 --- a/api/server.py +++ b/api/server.py @@ -71,6 +71,12 @@ def simulate_model(body: SimulatePostRequest) -> JobResponse: model_config_id = body.model_config_id start = body.timespan.start end = body.timespan.end + intervention_tuples=None + interventions_array = body.interventions + + if interventions_array is not None: + intervention_tuples= [(intervention.timestep +.001, intervention.name, intervention.value) for intervention in interventions_array ] + operation_name = "operations.simulate" options = { @@ -79,7 +85,8 @@ def simulate_model(body: SimulatePostRequest) -> JobResponse: "start": start, "end": end, "extra": body.extra.dict(), - "visual_options": True + "visual_options": True, + "interventions":intervention_tuples } resp = create_job(operation_name=operation_name, options=options) @@ -104,6 +111,12 @@ def calibrate_model(body: CalibratePostRequest) -> JobResponse: start = body.timespan.start end = body.timespan.end extra = body.extra.dict() + intervention_tuples=None + interventions_array = body.interventions + + if interventions_array is not None: + intervention_tuples= [(intervention.timestep +.001, intervention.name, intervention.value) for intervention in interventions_array ] + operation_name = "operations.calibrate_then_simulate" @@ -114,7 +127,8 @@ def calibrate_model(body: CalibratePostRequest) -> JobResponse: "end": end, "dataset": dataset.dict(), "extra": extra, - "visual_options": True + "visual_options": True, + "interventions":intervention_tuples } resp = create_job(operation_name=operation_name, options=options) From 2f362bba031f0b7894238a2570b6423847e25f5b Mon Sep 17 00:00:00 2001 From: Five Grant <5@fivegrant.com> Date: Mon, 17 Jul 2023 10:13:20 -0500 Subject: [PATCH 2/7] Create empty interventions by default --- api/models.py | 2 +- api/server.py | 10 ++++------ 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/api/models.py b/api/models.py index 7030705..38c71a9 100644 --- a/api/models.py +++ b/api/models.py @@ -100,7 +100,7 @@ class SimulatePostRequest(BaseModel): engine: Engine = Field(..., example="ciemss") model_config_id: str = Field(..., example="ba8da8d4-047d-11ee-be56") timespan: Timespan - interventions: Optional[List[InterventionObject]] = Field(None, example=[{"timestep":1,"name":"beta","value":.4}]) + interventions: List[InterventionObject] = Field(default_factory=list, example=[{"timestep":1,"name":"beta","value":.4}]) extra: SimulateExtra = Field( None, description="optional extra system specific arguments for advanced use cases", diff --git a/api/server.py b/api/server.py index 67fc6ec..303b1a5 100644 --- a/api/server.py +++ b/api/server.py @@ -71,11 +71,9 @@ def simulate_model(body: SimulatePostRequest) -> JobResponse: model_config_id = body.model_config_id start = body.timespan.start end = body.timespan.end - intervention_tuples=None - interventions_array = body.interventions - - if interventions_array is not None: - intervention_tuples= [(intervention.timestep +.001, intervention.name, intervention.value) for intervention in interventions_array ] + interventions = [ + (intervention.timestep, intervention.name, intervention.value) for intervention in body.interventions + ] operation_name = "operations.simulate" @@ -86,7 +84,7 @@ def simulate_model(body: SimulatePostRequest) -> JobResponse: "end": end, "extra": body.extra.dict(), "visual_options": True, - "interventions":intervention_tuples + "interventions": interventions } resp = create_job(operation_name=operation_name, options=options) From dc7af8bcca98bb9a1fcd925f42fb0c1f595f6cd6 Mon Sep 17 00:00:00 2001 From: Five Grant <5@fivegrant.com> Date: Mon, 17 Jul 2023 12:55:26 -0500 Subject: [PATCH 3/7] Add logging of interventions --- api/server.py | 21 +++++++++++---------- api/utils.py | 7 ++++--- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/api/server.py b/api/server.py index 303b1a5..e0ce66c 100644 --- a/api/server.py +++ b/api/server.py @@ -1,5 +1,6 @@ from __future__ import annotations +import logging from fastapi import FastAPI, Response, status from fastapi.middleware.cors import CORSMiddleware @@ -13,6 +14,9 @@ ) +logging.basicConfig() +logging.getLogger().setLevel(logging.DEBUG) + def build_api(*args) -> FastAPI: api = FastAPI( @@ -53,7 +57,7 @@ def get_status(simulation_id: str) -> StatusSimulationIdGetResponse: from utils import fetch_job_status status = fetch_job_status(simulation_id) - print(status) + logging.info(status) if not isinstance(status, str): return status @@ -102,20 +106,16 @@ def calibrate_model(body: CalibratePostRequest) -> JobResponse: from utils import create_job # Parse request body - print(body) + logging.info(body) engine = str(body.engine).lower() model_config_id = body.model_config_id dataset = body.dataset start = body.timespan.start end = body.timespan.end extra = body.extra.dict() - intervention_tuples=None - interventions_array = body.interventions - - if interventions_array is not None: - intervention_tuples= [(intervention.timestep +.001, intervention.name, intervention.value) for intervention in interventions_array ] - - + interventions = [ + (intervention.timestep, intervention.name, intervention.value) for intervention in body.interventions + ] operation_name = "operations.calibrate_then_simulate" options = { @@ -126,7 +126,7 @@ def calibrate_model(body: CalibratePostRequest) -> JobResponse: "dataset": dataset.dict(), "extra": extra, "visual_options": True, - "interventions":intervention_tuples + "interventions":interventions } resp = create_job(operation_name=operation_name, options=options) @@ -147,3 +147,4 @@ def create_ensemble(body: EnsemblePostRequest) -> JobResponse: ) + diff --git a/api/utils.py b/api/utils.py index 63cda45..6f2f2c5 100644 --- a/api/utils.py +++ b/api/utils.py @@ -53,7 +53,7 @@ def create_job(operation_name: str, options: Optional[Dict[Any, Any]] = None): job = q.fetch_job(job_id) if STANDALONE: - print(f"OPTIONS: {options}") + logging.info(f"OPTIONS: {options}") ex_payload = { "engine": "ciemss", "model_config_id": options.get("model_config_id"), @@ -73,9 +73,9 @@ def create_job(operation_name: str, options: Optional[Dict[Any, Any]] = None): "engine": "ciemss", "workflow_id": job_id, } - print(payload) + logging.info(payload) sys.stdout.flush() - print(requests.put(post_url, json=json.loads(json.dumps(payload))).content) + logging.info(requests.put(post_url, json=json.loads(json.dumps(payload))).content) if job and force_restart: job.cleanup(ttl=0) # Cleanup/remove data immediately @@ -110,6 +110,7 @@ def create_job(operation_name: str, options: Optional[Dict[Any, Any]] = None): "status": status, "simulation_error": job_error, "result": job_result, + "interventions": options["interventions"], } return response From 72fd50404d04a595e9f6239adc317ea3dbb269ff Mon Sep 17 00:00:00 2001 From: Five Grant <5@fivegrant.com> Date: Mon, 17 Jul 2023 13:05:35 -0500 Subject: [PATCH 4/7] Strip interventions from calibrate --- api/server.py | 6 ++---- api/utils.py | 1 - docker-compose.yaml | 5 ----- 3 files changed, 2 insertions(+), 10 deletions(-) diff --git a/api/server.py b/api/server.py index e0ce66c..0b880f9 100644 --- a/api/server.py +++ b/api/server.py @@ -93,6 +93,8 @@ def simulate_model(body: SimulatePostRequest) -> JobResponse: resp = create_job(operation_name=operation_name, options=options) + if len(interventions) > 0: + logging.info("{resp['id']} used interventions: {interventiosn}") response = {"simulation_id": resp["id"]} return response @@ -113,9 +115,6 @@ def calibrate_model(body: CalibratePostRequest) -> JobResponse: start = body.timespan.start end = body.timespan.end extra = body.extra.dict() - interventions = [ - (intervention.timestep, intervention.name, intervention.value) for intervention in body.interventions - ] operation_name = "operations.calibrate_then_simulate" options = { @@ -126,7 +125,6 @@ def calibrate_model(body: CalibratePostRequest) -> JobResponse: "dataset": dataset.dict(), "extra": extra, "visual_options": True, - "interventions":interventions } resp = create_job(operation_name=operation_name, options=options) diff --git a/api/utils.py b/api/utils.py index 6f2f2c5..f33131f 100644 --- a/api/utils.py +++ b/api/utils.py @@ -110,7 +110,6 @@ def create_job(operation_name: str, options: Optional[Dict[Any, Any]] = None): "status": status, "simulation_error": job_error, "result": job_result, - "interventions": options["interventions"], } return response diff --git a/docker-compose.yaml b/docker-compose.yaml index 02fee43..21b5b65 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -3,9 +3,6 @@ networks: pyciemss: driver: bridge name: pyciemss - data-api: - #TODO Remove in production - external: true services: api: container_name: pyciemss-api @@ -18,7 +15,6 @@ services: - api.env networks: - pyciemss - - data-api # TODO Remove in production depends_on: - redis volumes: @@ -43,4 +39,3 @@ services: - redis networks: - pyciemss - - data-api From dd09d5f64b4983bbac46d375bfc65af1d4d4e602 Mon Sep 17 00:00:00 2001 From: Five Grant <5@fivegrant.com> Date: Mon, 17 Jul 2023 13:08:14 -0500 Subject: [PATCH 5/7] Fix typo --- api/server.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/server.py b/api/server.py index 0b880f9..affedcd 100644 --- a/api/server.py +++ b/api/server.py @@ -94,7 +94,7 @@ def simulate_model(body: SimulatePostRequest) -> JobResponse: resp = create_job(operation_name=operation_name, options=options) if len(interventions) > 0: - logging.info("{resp['id']} used interventions: {interventiosn}") + logging.info("{resp['id']} used interventions: {interventions}") response = {"simulation_id": resp["id"]} return response From 9a9aac0ad42f3d7bc44b85f367fd63e24981d8c4 Mon Sep 17 00:00:00 2001 From: Five Grant <5@fivegrant.com> Date: Mon, 17 Jul 2023 13:15:17 -0500 Subject: [PATCH 6/7] Fix logging message --- api/server.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/server.py b/api/server.py index affedcd..8812a24 100644 --- a/api/server.py +++ b/api/server.py @@ -94,7 +94,7 @@ def simulate_model(body: SimulatePostRequest) -> JobResponse: resp = create_job(operation_name=operation_name, options=options) if len(interventions) > 0: - logging.info("{resp['id']} used interventions: {interventions}") + logging.info(f"{resp['id']} used interventions: {interventions}") response = {"simulation_id": resp["id"]} return response From 8552e42903711a2f119ed125238d5a38dbaac3a6 Mon Sep 17 00:00:00 2001 From: Five Grant <5@fivegrant.com> Date: Mon, 17 Jul 2023 13:16:47 -0500 Subject: [PATCH 7/7] Reinclude docker network --- docker-compose.yaml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docker-compose.yaml b/docker-compose.yaml index 21b5b65..02fee43 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -3,6 +3,9 @@ networks: pyciemss: driver: bridge name: pyciemss + data-api: + #TODO Remove in production + external: true services: api: container_name: pyciemss-api @@ -15,6 +18,7 @@ services: - api.env networks: - pyciemss + - data-api # TODO Remove in production depends_on: - redis volumes: @@ -39,3 +43,4 @@ services: - redis networks: - pyciemss + - data-api