Skip to content

Commit

Permalink
add endpoint to unlink runs from portfolio
Browse files Browse the repository at this point in the history
  • Loading branch information
rathod-b committed May 7, 2024
1 parent 3d5ac5f commit b353fbc
Show file tree
Hide file tree
Showing 5 changed files with 97 additions and 6 deletions.
4 changes: 2 additions & 2 deletions reo/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -159,11 +159,11 @@ class UnexpectedError(REoptError):

__name__ = 'UnexpectedError'

def __init__(self, exc_type, exc_value, exc_traceback, task='', run_uuid='', user_uuid='', message=None):
def __init__(self, exc_type, exc_value, exc_traceback, task='', run_uuid='', user_uuid='', portfolio_uuid='', message=None):
debug_msg = "exc_type: {}; exc_value: {}; exc_traceback: {}".format(exc_type, exc_value, exc_traceback)
if message is None:
message = "Unexpected Error."
super(UnexpectedError, self).__init__(task=task, name=self.__name__, run_uuid=run_uuid, user_uuid=user_uuid,
super(UnexpectedError, self).__init__(task=task, name=self.__name__, run_uuid=run_uuid, user_uuid=user_uuid, portfolio_uuid=portfolio_uuid,
message=message, traceback=debug_msg)


Expand Down
22 changes: 22 additions & 0 deletions reoptjl/migrations/0058_portfoliounlinkedruns.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Generated by Django 4.0.7 on 2024-05-07 15:47

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('reoptjl', '0057_apimeta_portfolio_uuid'),
]

operations = [
migrations.CreateModel(
name='PortfolioUnlinkedRuns',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('portfolio_uuid', models.UUIDField()),
('user_uuid', models.UUIDField()),
('run_uuid', models.UUIDField(unique=True)),
],
),
]
11 changes: 11 additions & 0 deletions reoptjl/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,17 @@ def create(cls, **kwargs):
obj.save()
return obj

class PortfolioUnlinkedRuns(models.Model):
portfolio_uuid = models.UUIDField(unique=False)
user_uuid = models.UUIDField(unique=False)
run_uuid = models.UUIDField(unique=True)

@classmethod
def create(cls, **kwargs):
obj = cls(**kwargs)
obj.save()
return obj

class UserProvidedMeta(BaseModel, models.Model):
"""
User provided values that are not necessary for running REopt
Expand Down
1 change: 1 addition & 0 deletions reoptjl/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
re_path(r'^user/(?P<user_uuid>[0-9a-f-]+)/summary/?$', views.summary),
re_path(r'^user/(?P<user_uuid>[0-9a-f-]+)/summary_by_chunk/(?P<chunk>[0-9]+)/?$', views.summary_by_chunk),
re_path(r'^user/(?P<user_uuid>[0-9a-f-]+)/unlink/(?P<run_uuid>[0-9a-f-]+)/?$', views.unlink),
re_path(r'^user/(?P<user_uuid>[0-9a-f-]+)/unlink_from_portfolio/(?P<portfolio_uuid>[0-9a-f-]+)/(?P<run_uuid>[0-9a-f-]+)/?$', views.unlink_from_portfolio),
re_path(r'^ghp_efficiency_thermal_factors/?$', views.ghp_efficiency_thermal_factors),
re_path(r'^peak_load_outage_times/?$', views.peak_load_outage_times),
re_path(r'^invalid_urdb/?$', reoviews.invalid_urdb),
Expand Down
65 changes: 61 additions & 4 deletions reoptjl/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
CoolingLoadOutputs, HeatingLoadOutputs, REoptjlMessageOutputs, HotThermalStorageInputs, HotThermalStorageOutputs,\
ColdThermalStorageInputs, ColdThermalStorageOutputs, AbsorptionChillerInputs, AbsorptionChillerOutputs,\
FinancialInputs, FinancialOutputs, UserUnlinkedRuns, BoilerInputs, BoilerOutputs, SteamTurbineInputs, \
SteamTurbineOutputs, GHPInputs, GHPOutputs
SteamTurbineOutputs, GHPInputs, GHPOutputs, PortfolioUnlinkedRuns
import os
import requests
import numpy as np
Expand Down Expand Up @@ -727,16 +727,24 @@ def summary(request, user_uuid):
# Create Querysets: Select all objects associate with a user_uuid, portfolio_uuid="", Order by `created` column
scenarios = APIMeta.objects.filter(
user_uuid=user_uuid
).filter(
portfolio_uuid=""
).only(
'run_uuid',
'portfolio_uuid',
'status',
'created'
).order_by("-created")

unlinked_run_uuids = [i.run_uuid for i in UserUnlinkedRuns.objects.filter(user_uuid=user_uuid)]
api_metas = [s for s in scenarios if s.run_uuid not in unlinked_run_uuids]
unlinked_por_uuids = [i.run_uuid for i in PortfolioUnlinkedRuns.objects.filter(user_uuid=user_uuid)]

api_metas = []
for s in scenarios:
if s.run_uuid not in unlinked_run_uuids:
api_metas.append(s)
elif s.portfolio_uuid != '' and s.run_uuid in (set(unlinked_por_uuids)-set(unlinked_run_uuids)):
api_metas.append(s)
else:
pass

if len(api_metas) > 0:
summary_dict = queryset_for_summary(api_metas, summary_dict)
Expand Down Expand Up @@ -1131,6 +1139,55 @@ def unlink(request, user_uuid, run_uuid):
err.save_to_db()
return JsonResponse({"Error": err.message}, status=404)

def unlink_from_portfolio(request, user_uuid, portfolio_uuid, run_uuid):

"""
add an entry to the PortfolioUnlinkedRuns for the given portfolio_uuid and run_uuid
"""
content = {'user_uuid': user_uuid, 'portfolio_uuid': portfolio_uuid, 'run_uuid': run_uuid}
for name, check_id in content.items():
try:
uuid.UUID(check_id) # raises ValueError if not valid uuid
except ValueError as e:
if e.args[0] == "badly formed hexadecimal UUID string":
return JsonResponse({"Error": "{} {}".format(name, e.args[0]) }, status=400)
else:
exc_type, exc_value, exc_traceback = sys.exc_info()
if name == 'user_uuid':
err = UnexpectedError(exc_type, exc_value, exc_traceback, task='unlink', user_uuid=check_id)
if name == 'portfolio_uuid':
err = UnexpectedError(exc_type, exc_value, exc_traceback, task='unlink', portfolio_uuid=check_id)
if name == 'run_uuid':
err = UnexpectedError(exc_type, exc_value, exc_traceback, task='unlink', run_uuid=check_id)
err.save_to_db()
return JsonResponse({"Error": str(err.message)}, status=400)

try:
if not APIMeta.objects.filter(portfolio_uuid=portfolio_uuid).exists():
return JsonResponse({"Error": "Portfolio {} does not exist".format(portfolio_uuid)}, status=400)


runs = APIMeta.objects.filter(run_uuid=run_uuid)
if len(runs) == 0:
return JsonResponse({"Error": "Run {} does not exist".format(run_uuid)}, status=400)
else:
if runs[0].portfolio_uuid != portfolio_uuid:
return JsonResponse({"Error": "Run {} is not associated with portfolio {}".format(run_uuid, portfolio_uuid)}, status=400)

# Run exists and is tied to porfolio provided in request, hence unlink now.
if not PortfolioUnlinkedRuns.objects.filter(run_uuid=run_uuid).exists():
PortfolioUnlinkedRuns.create(**content)
return JsonResponse({"Success": "run_uuid {} unlinked from portfolio_uuid {}".format(run_uuid, portfolio_uuid)},
status=201)
else:
return JsonResponse({"Nothing changed": "run_uuid {} is already unlinked from portfolio_uuid {}".format(run_uuid, portfolio_uuid)},
status=208)
except Exception as e:
exc_type, exc_value, exc_traceback = sys.exc_info()
err = UnexpectedError(exc_type, exc_value, exc_traceback, task='unlink', portfolio_uuid=portfolio_uuid)
err.save_to_db()
return JsonResponse({"Error": err.message}, status=404)

def avert_emissions_profile(request):
try:
inputs = {
Expand Down

0 comments on commit b353fbc

Please sign in to comment.