Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/couchdb #39

Merged
merged 2 commits into from
Jan 24, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions lib/couchdb/document.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ def from_dict(cls, data: Dict[str, Any]) -> "YggdrasilDocument":
# Samples
instance.samples = data.get("samples", [])

# User info
instance.user_info = data.get("user_info", {})

# Delivery info
instance.delivery_info = data.get("delivery_info", {})
if "delivery_results" not in instance.delivery_info:
Expand Down Expand Up @@ -78,6 +81,7 @@ def __init__(self, project_id: str, projects_reference: str, method: str) -> Non
self.samples: List[Dict[str, Any]] = []
self.delivery_info: Dict[str, Any] = {"delivery_results": []}
self.ngi_report: List[Dict[str, Any]] = []
self.user_info: Dict[str, Dict[str, Optional[str]]] = {}

def to_dict(self) -> Dict[str, Any]:
"""Converts the YggdrasilDocument to a dictionary.
Expand All @@ -96,8 +100,37 @@ def to_dict(self) -> Dict[str, Any]:
"samples": self.samples,
"delivery_info": self.delivery_info,
"ngi_report": self.ngi_report,
"user_info": self.user_info,
}

# ---------------------------
# USER INFO
# ---------------------------

def set_user_info(self, updated_info: Dict[str, Dict[str, Optional[str]]]) -> None:
"""
Updates self.user_info with the nested dictionary provided.

Example updated_info:
{
"owner": {
"email": "[email protected]",
"name": "Owner Name"
},
"pi": {
"email": "[email protected]",
"name": "PI Name"
}
}
"""
for role, sub_dict in updated_info.items():
if role not in self.user_info:
# If the doc didn't have that role yet, create a blank dict
self.user_info[role] = {}
# Copy keys like "email", "name"
for key, val in sub_dict.items():
self.user_info[role][key] = val or ""

# ------------------------------------------------------------------------
# SAMPLES
# ------------------------------------------------------------------------
Expand Down
48 changes: 47 additions & 1 deletion lib/couchdb/manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -203,25 +203,71 @@ def __init__(self) -> None:
super().__init__("yggdrasil")

def create_project(
self, project_id: str, projects_reference: str, method: str
self,
project_id: str,
projects_reference: str,
method: str,
user_info: Optional[Dict[str, Dict[str, Optional[str]]]] = None,
sensitive: Optional[bool] = True,
) -> YggdrasilDocument:
"""Creates a new project document in the database.

Args:
project_id (str): The project ID.
projects_reference (str): Reference to the original project document.
method (str): The library construction method.
user_info (Optional[Dict[str, Dict[str, str]]]): Nested dict of user info,
e.g. {"owner": {"email": "...", "name": "..."}, ...}.
sensitive (bool): True if data is sensitive. Defaults to True.

Returns:
YggdrasilDocument: The newly created project document.
"""
new_document = YggdrasilDocument(
project_id=project_id, projects_reference=projects_reference, method=method
)

# If we have user info, populate it into new_document.user_info
# TODO: Make sure the PI and the owner are always set | Either here or upon delivery
if user_info:
new_document.user_info = user_info

# Set sensitive flag to True by default (better safe than sorry)
new_document.delivery_info["sensitive"] = sensitive

self.save_document(new_document)
logging.info(f"New project with ID '{project_id}' created successfully.")
return new_document

def sync_project_metadata(
self,
project_id: str,
user_info: Dict[str, Dict[str, Optional[str]]],
is_sensitive: bool,
) -> None:
"""
Fetches the project doc from YggdrasilDB, updates user_info & sensitive,
then saves it back.
"""
doc_dict = self.get_document_by_project_id(project_id)
if not doc_dict:
logging.warning(f"No project '{project_id}' found to update.")
return

ygg_doc = YggdrasilDocument.from_dict(doc_dict)

# Update user_info
ygg_doc.set_user_info(user_info)

# Update sensitive
ygg_doc.delivery_info["sensitive"] = is_sensitive

# Save
self.save_document(ygg_doc)
logging.info(
f"Synced project '{project_id}' with necessary metadata from projectsDB."
)

def save_document(self, document: YggdrasilDocument) -> None:
try:
existing_doc = self.db.get(document._id)
Expand Down
Loading