11import json
2- from collections .abc import Collection
32from dataclasses import field
43from datetime import datetime
54from enum import Enum
6- from typing import Any , Optional
5+ from typing import Any , Iterable , Optional
76
87from pydantic .dataclasses import dataclass
98from typing_extensions import Self
109
11- from orca .services .nextflowtower .utils import parse_datetime
10+ from orca .services .nextflowtower .utils import dedup , parse_datetime
1211
1312
1413class TaskStatus (Enum ):
@@ -91,9 +90,9 @@ def from_json(cls, response: dict[str, Any]) -> Self:
9190class LaunchInfo :
9291 """Nextflow Tower workflow launch specification."""
9392
94- compute_env_id : str
95- pipeline : str
96- work_dir : str
93+ pipeline : Optional [ str ] = None
94+ compute_env_id : Optional [ str ] = None
95+ work_dir : Optional [ str ] = None
9796 revision : Optional [str ] = None
9897 params : Optional [dict ] = None
9998 nextflow_config : Optional [str ] = None
@@ -104,18 +103,6 @@ class LaunchInfo:
104103 workspace_secrets : list [str ] = field (default_factory = list )
105104 label_ids : list [int ] = field (default_factory = list )
106105
107- @staticmethod
108- def dedup (items : Collection [str ]) -> list [str ]:
109- """Deduplicate items in a collection.
110-
111- Args:
112- items: Collection of items.
113-
114- Returns:
115- Deduplicated collection or None.
116- """
117- return list (set (items ))
118-
119106 def fill_in (self , attr : str , value : Any ):
120107 """Fill in any missing values.
121108
@@ -126,6 +113,35 @@ def fill_in(self, attr: str, value: Any):
126113 if not getattr (self , attr , None ):
127114 setattr (self , attr , value )
128115
116+ def add_in (self , attr : str , values : Iterable [Any ]):
117+ """Add values to a list attribute.
118+
119+ Args:
120+ attr: Attribute name.
121+ values: New attribute values.
122+ """
123+ current_values = getattr (self , attr )
124+ if not isinstance (current_values , list ):
125+ message = f"Attribute '{ attr } ' is not a list and cannot be extended."
126+ raise ValueError (message )
127+ updated_values = current_values + list (values )
128+ updated_values = dedup (updated_values )
129+ setattr (self , attr , updated_values )
130+
131+ def get (self , name : str ) -> Any :
132+ """Retrieve attribute value, which cannot be None.
133+
134+ Args:
135+ name: Atribute name.
136+
137+ Returns:
138+ Attribute value (not None).
139+ """
140+ if getattr (self , name , None ) is None :
141+ message = f"Attribute '{ name } ' must be set (not None) by this point."
142+ raise ValueError (message )
143+ return getattr (self , name )
144+
129145 def to_dict (self ) -> dict [str , Any ]:
130146 """Generate JSON representation of a launch specification.
131147
@@ -134,19 +150,19 @@ def to_dict(self) -> dict[str, Any]:
134150 """
135151 output = {
136152 "launch" : {
137- "computeEnvId" : self .compute_env_id ,
138- "configProfiles" : self . dedup (self .profiles ),
153+ "computeEnvId" : self .get ( " compute_env_id" ) ,
154+ "configProfiles" : dedup (self .profiles ),
139155 "configText" : self .nextflow_config ,
140156 "dateCreated" : None ,
141157 "entryName" : None ,
142158 "headJobCpus" : None ,
143159 "headJobMemoryMb" : None ,
144160 "id" : None ,
145- "labelIds" : self .label_ids ,
161+ "labelIds" : dedup ( self .label_ids ) ,
146162 "mainScript" : None ,
147163 "optimizationId" : None ,
148164 "paramsText" : json .dumps (self .params ),
149- "pipeline" : self .pipeline ,
165+ "pipeline" : self .get ( " pipeline" ) ,
150166 "postRunScript" : None ,
151167 "preRunScript" : self .pre_run_script ,
152168 "pullLatest" : False ,
@@ -156,9 +172,9 @@ def to_dict(self) -> dict[str, Any]:
156172 "schemaName" : None ,
157173 "stubRun" : False ,
158174 "towerConfig" : None ,
159- "userSecrets" : self . dedup (self .user_secrets ),
160- "workDir" : self .work_dir ,
161- "workspaceSecrets" : self . dedup (self .workspace_secrets ),
175+ "userSecrets" : dedup (self .user_secrets ),
176+ "workDir" : self .get ( " work_dir" ) ,
177+ "workspaceSecrets" : dedup (self .workspace_secrets ),
162178 }
163179 }
164180 return output
0 commit comments