From 60c3c8802adddd46b84351ab75ac0d2f495140ff Mon Sep 17 00:00:00 2001 From: wbecker Date: Fri, 19 Dec 2025 10:08:37 -0700 Subject: [PATCH 1/9] Make load_type optional (default=electric) for GET request --- reoptjl/views.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/reoptjl/views.py b/reoptjl/views.py index e4984a43e..b4340462e 100644 --- a/reoptjl/views.py +++ b/reoptjl/views.py @@ -597,12 +597,13 @@ def simulated_load(request): inputs["latitude"] = float(request.GET['latitude']) # need float to convert unicode inputs["longitude"] = float(request.GET['longitude']) # Optional load_type - will default to "electric" - inputs["load_type"] = request.GET.get('load_type') + if 'load_type' in request.GET: + inputs["load_type"] = request.GET["load_type"] # Optional year parameter to shift the CRB profile from 2017 (also 2023) to the input year if 'year' in request.GET: inputs["year"] = int(request.GET['year']) - if inputs["load_type"] == 'process_heat': + if inputs.get("load_type") == 'process_heat': expected_reference_name = 'industrial_reference_name' else: expected_reference_name = 'doe_reference_name' From 4aec4b14edcad61c5d32ed5990505c945886c072 Mon Sep 17 00:00:00 2001 From: wbecker Date: Fri, 19 Dec 2025 10:16:53 -0700 Subject: [PATCH 2/9] Refactor POST requests to /simulated_load for improved I/O and validation Optional load_type (default=electric) Optional year with doe_reference_name --- reoptjl/views.py | 54 +++++++++++++++++++++++++++++++----------------- 1 file changed, 35 insertions(+), 19 deletions(-) diff --git a/reoptjl/views.py b/reoptjl/views.py index b4340462e..cdde1041f 100644 --- a/reoptjl/views.py +++ b/reoptjl/views.py @@ -655,25 +655,22 @@ def simulated_load(request): if request.method == "POST": data = json.loads(request.body) - required_post_fields = ["load_type", "year"] either_required = ["normalize_and_scale_load_profile_input", "doe_reference_name"] - optional = ["percent_share"] either_check = 0 for either in either_required: - if data.get(either) is not None: + if either in data: inputs[either] = data[either] either_check += 1 if either_check == 0: return JsonResponse({"Error": "Missing either of normalize_and_scale_load_profile_input or doe_reference_name."}, status=400) elif either_check == 2: return JsonResponse({"Error": "Both normalize_and_scale_load_profile_input and doe_reference_name were input; only input one of these."}, status=400) - for field in required_post_fields: - # TODO make year optional for doe_reference_name input - inputs[field] = data[field] - for opt in optional: - if data.get(opt) is not None: - inputs[opt] = data[opt] - if data.get("normalize_and_scale_load_profile_input") is not None: + + # If normalize_and_scale_load_profile_input is true, year and load_profile are required + if data.get("normalize_and_scale_load_profile_input") is True: + if "year" not in data: + return JsonResponse({"Error": "year is required when normalize_and_scale_load_profile_input is true."}, status=400) + inputs["year"] = data["year"] if "load_profile" not in data: return JsonResponse({"Error": "load_profile is required when normalize_and_scale_load_profile_input is provided."}, status=400) inputs["load_profile"] = data["load_profile"] @@ -681,18 +678,37 @@ def simulated_load(request): if "time_steps_per_hour" not in data: return JsonResponse({"Error": "time_steps_per_hour is required when load_profile length is not 8760."}, status=400) inputs["time_steps_per_hour"] = data["time_steps_per_hour"] - if inputs["load_type"] == "electric": + + # If doe_reference_name is provided, latitude and longitude are required, year is optional + if "doe_reference_name" in data: + if "latitude" not in data or "longitude" not in data: + return JsonResponse({"Error": "latitude and longitude are required when doe_reference_name is provided."}, status=400) + inputs["latitude"] = float(data["latitude"]) + inputs["longitude"] = float(data["longitude"]) + # year is optional for doe_reference_name, as it will default to 2017 + if "year" in data: + inputs["year"] = data["year"] + if "percent_share" in data: + inputs["percent_share"] = data["percent_share"] + + # Optional load_type determines required energy input options (default is "electric") + load_type = data.get("load_type") + if load_type is None: + load_type = "electric" # default load_type for simulate_load() + else: + inputs["load_type"] = data["load_type"] + if load_type == "electric": for energy in ["annual_kwh", "monthly_totals_kwh", "monthly_peaks_kw"]: - if data.get(energy) is not None: - inputs[energy] = data.get(energy) - elif inputs["load_type"] in ["space_heating", "domestic_hot_water", "process_heat"]: + if energy in data: + inputs[energy] = data[energy] + elif load_type in ["space_heating", "domestic_hot_water", "process_heat"]: for energy in ["annual_mmbtu", "monthly_mmbtu"]: - if data.get(energy) is not None: - inputs[energy] = data.get(energy) - elif inputs["load_type"] == "cooling": + if energy in data: + inputs[energy] = data[energy] + elif load_type == "cooling": for energy in ["annual_tonhour", "monthly_tonhour"]: - if data.get(energy) is not None: - inputs[energy] = data.get(energy) + if energy in data: + inputs[energy] = data[energy] # json.dump(inputs, open("sim_load_post.json", "w")) julia_host = os.environ.get('JULIA_HOST', "julia") From b910a3d5f60e1730a67dd166f0d88a0c848f462e Mon Sep 17 00:00:00 2001 From: wbecker Date: Fri, 19 Dec 2025 10:17:26 -0700 Subject: [PATCH 3/9] Add tests for POST requests to /simulated_load --- reoptjl/test/test_http_endpoints.py | 122 ++++++++++++++++++++++++++++ 1 file changed, 122 insertions(+) diff --git a/reoptjl/test/test_http_endpoints.py b/reoptjl/test/test_http_endpoints.py index 7848e8839..165cb23a6 100644 --- a/reoptjl/test/test_http_endpoints.py +++ b/reoptjl/test/test_http_endpoints.py @@ -149,6 +149,128 @@ def test_simulated_load(self): v2_response = json.loads(resp.content) assert("Error" in v2_response.keys()) + def test_simulated_load_post(self): + + # Test 1: POST with normalize_and_scale_load_profile_input and load_profile + load_profile = [100.0] * 8760 # Simple 8760 hourly load profile + monthly_totals = [450000.0, 420000.0, 480000.0, 510000.0, 550000.0, 600000.0, + 620000.0, 610000.0, 570000.0, 520000.0, 470000.0, 440000.0] # 12 monthly totals in kWh to scale to + inputs = { + "normalize_and_scale_load_profile_input": True, + "load_profile": load_profile, + "year": 2021, + "monthly_totals_kwh": monthly_totals + } + resp = self.api_client.post(f'/stable/simulated_load', format='json', data=inputs) + self.assertHttpOK(resp) + post_response = json.loads(resp.content) + self.assertAlmostEqual(post_response["annual_kwh"], sum(monthly_totals), delta=10.0) + + # Test 2: POST with doe_reference_name and monthly_totals_kwh, monthly_peaks_kw + monthly_peaks = [900.0, 850.0, 950.0, 1000.0, 1100.0, 1200.0, + 1300.0, 1250.0, 1150.0, 1050.0, 950.0, 900.0] # 12 monthly peaks in kW (+/- 30%) + inputs = { + "doe_reference_name": "Hospital", + "latitude": 36.12, + "longitude": -115.5, + "load_type": "electric", + "monthly_totals_kwh": monthly_totals, + "monthly_peaks_kw": monthly_peaks, + "year": 2021 + } + resp = self.api_client.post(f'/stable/simulated_load', format='json', data=inputs) + self.assertHttpOK(resp) + post_response = json.loads(resp.content) + self.assertIn("loads_kw", post_response.keys()) + self.assertEqual(len(post_response["loads_kw"]), 8760) + self.assertIn("annual_kwh", post_response.keys()) + + # Test 3: POST with doe_reference_name only (no monthly data and no load_type, defaults to electric) + # and check consistency with GET request + inputs = { + "doe_reference_name": "LargeOffice", + "latitude": 40.7128, + "longitude": -74.0060, + "annual_kwh": 1000000.0 + } + resp = self.api_client.post(f'/stable/simulated_load', format='json', data=inputs) + self.assertHttpOK(resp) + post_response = json.loads(resp.content) + self.assertAlmostEqual(post_response["annual_kwh"], 1000000.0, delta=1.0) + + get_resp = self.api_client.get(f'/stable/simulated_load', data=inputs) + self.assertHttpOK(get_resp) + get_response = json.loads(get_resp.content) + self.assertEqual(post_response["loads_kw"][:3], get_response["loads_kw"][:3]) + + # Test 4: POST with blended/hybrid buildings using arrays for doe_reference_name and percent_share + inputs = { + "doe_reference_name": ["LargeOffice", "FlatLoad"], + "percent_share": [0.60, 0.40], + "latitude": 36.12, + "longitude": -115.5, + "load_type": "electric", + "annual_kwh": 1.5e7, + "year": 2021 + } + resp = self.api_client.post(f'/stable/simulated_load', format='json', data=inputs) + self.assertHttpOK(resp) + post_response = json.loads(resp.content) + self.assertIn("loads_kw", post_response.keys()) + self.assertEqual(len(post_response["loads_kw"]), 8760) + self.assertAlmostEqual(post_response["annual_kwh"], 1.5e7, delta=1.0) + + # Test 5: Validation - Missing both normalize_and_scale_load_profile_input and doe_reference_name + inputs = { + "latitude": 36.12, + "longitude": -115.5, + "year": 2021, + "monthly_totals_kwh": monthly_totals + } + resp = self.api_client.post(f'/stable/simulated_load', format='json', data=inputs) + self.assertHttpBadRequest(resp) + post_response = json.loads(resp.content) + self.assertIn("Error", post_response.keys()) + self.assertIn("Missing either of", post_response["Error"]) + + # Test 6: Validation - normalize_and_scale_load_profile_input without year + inputs = { + "normalize_and_scale_load_profile_input": True, + "load_profile": load_profile + } + resp = self.api_client.post(f'/stable/simulated_load', format='json', data=inputs) + self.assertHttpBadRequest(resp) + post_response = json.loads(resp.content) + self.assertIn("Error", post_response.keys()) + self.assertIn("year is required", post_response["Error"]) + + # Test 7: Validation - doe_reference_name without latitude + inputs = { + "doe_reference_name": "Hospital", + "longitude": -115.5, + "year": 2021 + } + resp = self.api_client.post(f'/stable/simulated_load', format='json', data=inputs) + self.assertHttpBadRequest(resp) + post_response = json.loads(resp.content) + self.assertIn("Error", post_response.keys()) + self.assertIn("latitude and longitude are required", post_response["Error"]) + + # Test 8: POST with non-8760 load_profile and time_steps_per_hour + load_profile_15min = [100.0] * 35040 # 8760 * 4 for 15-minute intervals + inputs = { + "normalize_and_scale_load_profile_input": True, + "load_profile": load_profile_15min, + "monthly_totals_kwh": monthly_totals, + "year": 2021, + "time_steps_per_hour": 4 + } + resp = self.api_client.post(f'/stable/simulated_load', format='json', data=inputs) + self.assertHttpOK(resp) + post_response = json.loads(resp.content) + self.assertAlmostEqual(post_response["annual_kwh"], sum(monthly_totals), delta=10.0) + + def test_avert_emissions_profile_endpoint(self): # Call to the django view endpoint dev/avert_emissions_profile which calls the http.jl endpoint #case 1: location in CONUS (Seattle, WA) From 12530c53ac5986fa58876949a44332720a8214fb Mon Sep 17 00:00:00 2001 From: wbecker Date: Fri, 19 Dec 2025 10:28:11 -0700 Subject: [PATCH 4/9] Update CHANGELOG.md with updates to /simulated_load --- CHANGELOG.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index af7c02ee0..3b357f9bc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,17 @@ Classify the change according to the following categories: ##### Removed ### Patches +## v3.17.5 +### Minor Updates +##### Added +- Tests in `test_http_endpoints.py` to test expected `/simulated_load` POST request functionality +##### Changed +- Makes `load_type` optional for both GET and POST requests to `/simulated_load`, with a default `load_type=electric`, consistent with the `simulated_load()` function in REopt.jl +- Makes the `year` input not required for inputs with `doe_reference_name` for POST request to `/simulated_load`, consistent with GET request and `simulated_load()` function in REopt.jl +##### Fixed +- POST requests to `/simulated_load` with `doe_reference_name` input to pass along the lat/long inputs (was not passing those inputs through) + + ## v3.17.4 ### Minor Updates ##### Fixed From 6c2c58be95fea8de02d755e9e77fb9687fed745f Mon Sep 17 00:00:00 2001 From: wbecker Date: Wed, 24 Dec 2025 10:00:38 -0700 Subject: [PATCH 5/9] Add industrial_reference_name as valid input option for POST --- reoptjl/views.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/reoptjl/views.py b/reoptjl/views.py index cdde1041f..8255ece1b 100644 --- a/reoptjl/views.py +++ b/reoptjl/views.py @@ -655,16 +655,16 @@ def simulated_load(request): if request.method == "POST": data = json.loads(request.body) - either_required = ["normalize_and_scale_load_profile_input", "doe_reference_name"] + either_required = ["normalize_and_scale_load_profile_input", "doe_reference_name", "industrial_reference_name"] either_check = 0 for either in either_required: if either in data: inputs[either] = data[either] either_check += 1 if either_check == 0: - return JsonResponse({"Error": "Missing either of normalize_and_scale_load_profile_input or doe_reference_name."}, status=400) + return JsonResponse({"Error": "Missing either of normalize_and_scale_load_profile_input or [doe or industrial]_reference_name."}, status=400) elif either_check == 2: - return JsonResponse({"Error": "Both normalize_and_scale_load_profile_input and doe_reference_name were input; only input one of these."}, status=400) + return JsonResponse({"Error": "Both normalize_and_scale_load_profile_input and [doe or industrial]_reference_name were input; only input one of these."}, status=400) # If normalize_and_scale_load_profile_input is true, year and load_profile are required if data.get("normalize_and_scale_load_profile_input") is True: @@ -680,7 +680,7 @@ def simulated_load(request): inputs["time_steps_per_hour"] = data["time_steps_per_hour"] # If doe_reference_name is provided, latitude and longitude are required, year is optional - if "doe_reference_name" in data: + if "doe_reference_name" in data or "industrial_reference_name" in data: if "latitude" not in data or "longitude" not in data: return JsonResponse({"Error": "latitude and longitude are required when doe_reference_name is provided."}, status=400) inputs["latitude"] = float(data["latitude"]) From ed1dd84701321f77a90966c2226028247f464b70 Mon Sep 17 00:00:00 2001 From: wbecker Date: Wed, 24 Dec 2025 11:11:03 -0700 Subject: [PATCH 6/9] Fixes to heating and cooling input handling for POST Also some type ensurances --- reoptjl/views.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/reoptjl/views.py b/reoptjl/views.py index 8255ece1b..ca24a5ff2 100644 --- a/reoptjl/views.py +++ b/reoptjl/views.py @@ -677,17 +677,17 @@ def simulated_load(request): if len(inputs["load_profile"]) != 8760: if "time_steps_per_hour" not in data: return JsonResponse({"Error": "time_steps_per_hour is required when load_profile length is not 8760."}, status=400) - inputs["time_steps_per_hour"] = data["time_steps_per_hour"] + inputs["time_steps_per_hour"] = int(data["time_steps_per_hour"]) # If doe_reference_name is provided, latitude and longitude are required, year is optional if "doe_reference_name" in data or "industrial_reference_name" in data: if "latitude" not in data or "longitude" not in data: - return JsonResponse({"Error": "latitude and longitude are required when doe_reference_name is provided."}, status=400) + return JsonResponse({"Error": "latitude and longitude are required when [doe or industrial]_reference_name is provided."}, status=400) inputs["latitude"] = float(data["latitude"]) inputs["longitude"] = float(data["longitude"]) # year is optional for doe_reference_name, as it will default to 2017 if "year" in data: - inputs["year"] = data["year"] + inputs["year"] = int(data["year"]) if "percent_share" in data: inputs["percent_share"] = data["percent_share"] @@ -701,7 +701,11 @@ def simulated_load(request): for energy in ["annual_kwh", "monthly_totals_kwh", "monthly_peaks_kw"]: if energy in data: inputs[energy] = data[energy] - elif load_type in ["space_heating", "domestic_hot_water", "process_heat"]: + if "cooling_doe_ref_name" in data: + inputs["cooling_doe_ref_name"] = data["cooling_doe_ref_name"] + if "cooling_pct_share" in data: + inputs["cooling_pct_share"] = data["cooling_pct_share"] + elif load_type in ["heating", "space_heating", "domestic_hot_water", "process_heat"]: for energy in ["annual_mmbtu", "monthly_mmbtu"]: if energy in data: inputs[energy] = data[energy] From 0ad9f649df5318b2ff488188fcf552fea5bb4460 Mon Sep 17 00:00:00 2001 From: wbecker Date: Wed, 7 Jan 2026 21:10:09 -0700 Subject: [PATCH 7/9] Remove unnecessary mapping from POST request body to inputs dict The beauty of the POST is that we can effectively pass the .json straight to the function as a dictionary with minimal data processing. This preserves all intentionally inputs validation/checking that was there before. --- reoptjl/views.py | 52 +++++++++--------------------------------------- 1 file changed, 9 insertions(+), 43 deletions(-) diff --git a/reoptjl/views.py b/reoptjl/views.py index ca24a5ff2..99b620547 100644 --- a/reoptjl/views.py +++ b/reoptjl/views.py @@ -654,12 +654,11 @@ def simulated_load(request): inputs[key] = float(request.GET.get(key)) if request.method == "POST": - data = json.loads(request.body) + inputs = json.loads(request.body) either_required = ["normalize_and_scale_load_profile_input", "doe_reference_name", "industrial_reference_name"] either_check = 0 for either in either_required: - if either in data: - inputs[either] = data[either] + if either in inputs: either_check += 1 if either_check == 0: return JsonResponse({"Error": "Missing either of normalize_and_scale_load_profile_input or [doe or industrial]_reference_name."}, status=400) @@ -667,52 +666,19 @@ def simulated_load(request): return JsonResponse({"Error": "Both normalize_and_scale_load_profile_input and [doe or industrial]_reference_name were input; only input one of these."}, status=400) # If normalize_and_scale_load_profile_input is true, year and load_profile are required - if data.get("normalize_and_scale_load_profile_input") is True: - if "year" not in data: + if inputs.get("normalize_and_scale_load_profile_input") is True: + if "year" not in inputs: return JsonResponse({"Error": "year is required when normalize_and_scale_load_profile_input is true."}, status=400) - inputs["year"] = data["year"] - if "load_profile" not in data: + if "load_profile" not in inputs: return JsonResponse({"Error": "load_profile is required when normalize_and_scale_load_profile_input is provided."}, status=400) - inputs["load_profile"] = data["load_profile"] if len(inputs["load_profile"]) != 8760: - if "time_steps_per_hour" not in data: - return JsonResponse({"Error": "time_steps_per_hour is required when load_profile length is not 8760."}, status=400) - inputs["time_steps_per_hour"] = int(data["time_steps_per_hour"]) + if "time_steps_per_hour" not in inputs: + return JsonResponse({"Error": "time_steps_per_hour is required when load_profile length is not 8760 (hourly)."}, status=400) # If doe_reference_name is provided, latitude and longitude are required, year is optional - if "doe_reference_name" in data or "industrial_reference_name" in data: - if "latitude" not in data or "longitude" not in data: + if "doe_reference_name" in inputs or "industrial_reference_name" in inputs: + if "latitude" not in inputs or "longitude" not in inputs: return JsonResponse({"Error": "latitude and longitude are required when [doe or industrial]_reference_name is provided."}, status=400) - inputs["latitude"] = float(data["latitude"]) - inputs["longitude"] = float(data["longitude"]) - # year is optional for doe_reference_name, as it will default to 2017 - if "year" in data: - inputs["year"] = int(data["year"]) - if "percent_share" in data: - inputs["percent_share"] = data["percent_share"] - - # Optional load_type determines required energy input options (default is "electric") - load_type = data.get("load_type") - if load_type is None: - load_type = "electric" # default load_type for simulate_load() - else: - inputs["load_type"] = data["load_type"] - if load_type == "electric": - for energy in ["annual_kwh", "monthly_totals_kwh", "monthly_peaks_kw"]: - if energy in data: - inputs[energy] = data[energy] - if "cooling_doe_ref_name" in data: - inputs["cooling_doe_ref_name"] = data["cooling_doe_ref_name"] - if "cooling_pct_share" in data: - inputs["cooling_pct_share"] = data["cooling_pct_share"] - elif load_type in ["heating", "space_heating", "domestic_hot_water", "process_heat"]: - for energy in ["annual_mmbtu", "monthly_mmbtu"]: - if energy in data: - inputs[energy] = data[energy] - elif load_type == "cooling": - for energy in ["annual_tonhour", "monthly_tonhour"]: - if energy in data: - inputs[energy] = data[energy] # json.dump(inputs, open("sim_load_post.json", "w")) julia_host = os.environ.get('JULIA_HOST', "julia") From 3eb7364d7c6691580e90176b3d5a0f17be1499fd Mon Sep 17 00:00:00 2001 From: wbecker Date: Fri, 9 Jan 2026 15:34:18 -0700 Subject: [PATCH 8/9] Change the python views -> http method type for /simulated_load from GET to POST due to potential payload size Even though the GET method works, for large payloads in particular, this should be a POST. --- julia_src/http.jl | 2 +- reoptjl/views.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/julia_src/http.jl b/julia_src/http.jl index bb59014e1..10228ea09 100644 --- a/julia_src/http.jl +++ b/julia_src/http.jl @@ -821,7 +821,7 @@ HTTP.register!(ROUTER, "GET", "/avert_emissions_profile", avert_emissions_profil HTTP.register!(ROUTER, "GET", "/cambium_profile", cambium_profile) HTTP.register!(ROUTER, "GET", "/easiur_costs", easiur_costs) HTTP.register!(ROUTER, "GET", "/sector_defaults", sector_defaults) -HTTP.register!(ROUTER, "GET", "/simulated_load", simulated_load) +HTTP.register!(ROUTER, "POST", "/simulated_load", simulated_load) HTTP.register!(ROUTER, "GET", "/absorption_chiller_defaults", absorption_chiller_defaults) HTTP.register!(ROUTER, "GET", "/ghp_efficiency_thermal_factors", ghp_efficiency_thermal_factors) HTTP.register!(ROUTER, "GET", "/ground_conductivity", ground_conductivity) diff --git a/reoptjl/views.py b/reoptjl/views.py index 99b620547..315a5a2dc 100644 --- a/reoptjl/views.py +++ b/reoptjl/views.py @@ -682,7 +682,7 @@ def simulated_load(request): # json.dump(inputs, open("sim_load_post.json", "w")) julia_host = os.environ.get('JULIA_HOST', "julia") - http_jl_response = requests.get("http://" + julia_host + ":8081/simulated_load/", json=inputs) + http_jl_response = requests.post("http://" + julia_host + ":8081/simulated_load/", json=inputs) response_data = http_jl_response.json() # Round all scalar/monthly outputs to 2 decimal places load_profile_key = next((k for k in response_data if "loads_" in k), None) From e819d274479cc5f365c997a2c32916c05015e3d6 Mon Sep 17 00:00:00 2001 From: wbecker Date: Mon, 12 Jan 2026 15:06:44 -0700 Subject: [PATCH 9/9] Handle error if not GET or POST methods --- reoptjl/views.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/reoptjl/views.py b/reoptjl/views.py index 315a5a2dc..71fc0ac28 100644 --- a/reoptjl/views.py +++ b/reoptjl/views.py @@ -652,8 +652,7 @@ def simulated_load(request): return JsonResponse({"Error. Monthly data does not contain 12 valid entries"}) elif request.GET.get(key) is not None: inputs[key] = float(request.GET.get(key)) - - if request.method == "POST": + elif request.method == "POST": inputs = json.loads(request.body) either_required = ["normalize_and_scale_load_profile_input", "doe_reference_name", "industrial_reference_name"] either_check = 0 @@ -679,6 +678,8 @@ def simulated_load(request): if "doe_reference_name" in inputs or "industrial_reference_name" in inputs: if "latitude" not in inputs or "longitude" not in inputs: return JsonResponse({"Error": "latitude and longitude are required when [doe or industrial]_reference_name is provided."}, status=400) + else: + return JsonResponse({"Error": "Only GET and POST methods are supported for this endpoint"}, status=405) # json.dump(inputs, open("sim_load_post.json", "w")) julia_host = os.environ.get('JULIA_HOST', "julia")