Skip to content

Commit

Permalink
upsert update works
Browse files Browse the repository at this point in the history
  • Loading branch information
AlbertSnows committed Sep 6, 2024
1 parent 7d5e5d7 commit 4ef2c92
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 60 deletions.
115 changes: 60 additions & 55 deletions gen3userdatalibrary/db.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,60 @@
async_sessionmaker = async_sessionmaker(engine, expire_on_commit=False)


async def create_user_list_instance(user_list: dict, user_id):
now = datetime.datetime.now(datetime.timezone.utc)
name = user_list.get("name", f"Saved List {now}")
user_list_items = user_list.get("items", {})

for _, item_contents in user_list_items.items():
# TODO THIS NEEDS TO BE CFG
if item_contents.get("type") == "GA4GH_DRS":
try:
validate(instance=item_contents, schema=ITEMS_JSON_SCHEMA_DRS)
except ValidationError as e:
logging.debug(f"User-provided JSON is invalid: {e.message}")
raise
elif item_contents.get("type") == "Gen3GraphQL":
try:
validate(
instance=item_contents,
schema=ITEMS_JSON_SCHEMA_GEN3_GRAPHQL,
)
except ValidationError as e:
logging.debug(f"User-provided JSON is invalid: {e.message}")
raise
else:
try:
validate(
instance=item_contents,
schema=ITEMS_JSON_SCHEMA_GENERIC,
)
except ValidationError as e:
logging.debug(f"User-provided JSON is invalid: {e.message}")
raise

logging.warning(
"User-provided JSON is an unknown type. Creating anyway..."
)

if user_id is None:
# TODO make this a reasonable error type
raise Exception()
new_list = UserList(
version=0,
creator=str(user_id),
# temporarily set authz without the list ID since we haven't created the list in the db yet
authz={
"version": 0,
"authz": [f"/users/{user_id}/user-data-library/lists"],
},
name=name,
created_time=now,
updated_time=now,
items=user_list_items)
return new_list


class DataAccessLayer():
"""
Defines an abstract interface to manipulate the database. Instances are given a session to
Expand All @@ -62,58 +116,8 @@ def __init__(self, db_session: AsyncSession):
self.db_session = db_session

async def create_user_list(self, user_list) -> UserList:
now = datetime.datetime.now(datetime.timezone.utc)
name = user_list.get("name", f"Saved List {now}")
user_list_items = user_list.get("items", {})

for _, item_contents in user_list_items.items():
# TODO THIS NEEDS TO BE CFG
if item_contents.get("type") == "GA4GH_DRS":
try:
validate(instance=item_contents, schema=ITEMS_JSON_SCHEMA_DRS)
except ValidationError as e:
logging.debug(f"User-provided JSON is invalid: {e.message}")
raise
elif item_contents.get("type") == "Gen3GraphQL":
try:
validate(
instance=item_contents,
schema=ITEMS_JSON_SCHEMA_GEN3_GRAPHQL,
)
except ValidationError as e:
logging.debug(f"User-provided JSON is invalid: {e.message}")
raise
else:
try:
validate(
instance=item_contents,
schema=ITEMS_JSON_SCHEMA_GENERIC,
)
except ValidationError as e:
logging.debug(f"User-provided JSON is invalid: {e.message}")
raise

logging.warning(
"User-provided JSON is an unknown type. Creating anyway..."
)

user_id = await get_user_id()

if user_id is None:
# TODO make this a reasonable error type
raise Exception()
new_list = UserList(
version=0,
creator=str(user_id),
# temporarily set authz without the list ID since we haven't created the list in the db yet
authz={
"version": 0,
"authz": [f"/users/{user_id}/user-data-library/lists"],
},
name=name,
created_time=now,
updated_time=now,
items=user_list_items)
new_list = await create_user_list_instance(user_list, user_id)
self.db_session.add(new_list)

# correct authz with id, but flush to get the autoincrement id
Expand Down Expand Up @@ -146,17 +150,18 @@ async def get_all_lists(self) -> List[UserList]:
async def update_list(
self,
list_id: int,
user_list: UserList) -> str:
user_list: UserList) -> UserList:
q = select(UserList).where(UserList.id == list_id)
existing_record = await self.db_session.execute(q)
result = await self.db_session.execute(q)
existing_record = result.scalar_one_or_none()
if existing_record is None:
raise ValueError(f"No UserList found with id {list_id}")
for attr in dir(user_list):
if not attr.startswith('_') and hasattr(existing_record, attr):
setattr(existing_record, attr, getattr(user_list, attr))
q.execution_options(synchronize_session="fetch")
existing_record.id = list_id
await self.db_session.commit()
return existing_record.scalar_one()
return existing_record

async def test_connection(self) -> None:
await self.db_session.execute(text("SELECT 1;"))
Expand Down
11 changes: 6 additions & 5 deletions gen3userdatalibrary/routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

from gen3userdatalibrary import config, logging
from gen3userdatalibrary.auth import authorize_request, get_user_id
from gen3userdatalibrary.db import DataAccessLayer, get_data_access_layer
from gen3userdatalibrary.db import DataAccessLayer, get_data_access_layer, create_user_list_instance
from gen3userdatalibrary.models import UserList
from gen3userdatalibrary.utils import add_user_list_metric
from fastapi.responses import RedirectResponse
Expand Down Expand Up @@ -391,17 +391,18 @@ async def upsert_list_by_id(
response = {"status": status_text, "timestamp": time.time(), "created_list": list_data[1].to_dict()}
return JSONResponse(status_code=return_status, content=response)
try:
list_as_orm = UserList(user_list)
except Exception:
user_id = await get_user_id()
list_as_orm = await create_user_list_instance(user_list, user_id)
except Exception as e:
return_status = status.HTTP_400_BAD_REQUEST
status_text = "UNHEALTHY"
response = {"status": status_text, "timestamp": time.time(), "error": "malformed list, could not update"}
return JSONResponse(status_code=return_status, content=response)

try:
outcome = await data_access_layer.update_list(ID, list_as_orm)
response = {"status": status_text, "timestamp": time.time(), "updated_name": outcome}
except Exception:
response = {"status": status_text, "timestamp": time.time(), "updated_list": outcome.to_dict()}
except Exception as e:
return_status = status.HTTP_500_INTERNAL_SERVER_ERROR
status_text = "UNHEALTHY"
response = {"status": status_text, "timestamp": time.time()}
Expand Down

0 comments on commit 4ef2c92

Please sign in to comment.