2626# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2727# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2828import logging
29- from typing import Optional , List , TypeVar , Any , Mapping , Union
29+ from typing import Optional , List , TypeVar , Any , Mapping , Union , cast
3030from pathlib import Path
3131
3232from servicex .configuration import Configuration
4343
4444from make_it_sync import make_sync
4545from servicex .databinder_models import ServiceXSpec , General , Sample
46+ from collections .abc import Sequence
4647
4748T = TypeVar ("T" )
4849logger = logging .getLogger (__name__ )
4950
5051
52+ class GuardList (Sequence ):
53+ def __init__ (self , data : Union [Sequence , Exception ]):
54+ import copy
55+ super ().__init__ ()
56+ self ._data = copy .copy (data )
57+
58+ def valid (self ) -> bool :
59+ return not isinstance (self ._data , Exception )
60+
61+ def __getitem__ (self , index ) -> Any :
62+ if not self .valid ():
63+ data = cast (Exception , self ._data )
64+ raise data
65+ else :
66+ data = cast (Sequence , self ._data )
67+ return data [index ]
68+
69+ def __len__ (self ) -> int :
70+ if not self .valid ():
71+ data = cast (Exception , self ._data )
72+ raise data
73+ else :
74+ data = cast (Sequence , self ._data )
75+ return len (data )
76+
77+ def __repr__ (self ):
78+ if self .valid ():
79+ return repr (self ._data )
80+ else :
81+ return f'Invalid GuardList: { repr (self ._data )} '
82+
83+
5184def _load_ServiceXSpec (
5285 config : Union [ServiceXSpec , Mapping [str , Any ], str , Path ]
5386) -> ServiceXSpec :
@@ -117,11 +150,19 @@ def get_codegen(_sample: Sample, _general: General):
117150 return datasets
118151
119152
120- def _output_handler (config : ServiceXSpec , results : List [TransformedResults ]):
153+ def _output_handler (config : ServiceXSpec , requests : List [Query ],
154+ results : List [Union [TransformedResults , Exception ]]):
155+ matched_results = zip (requests , results )
121156 if config .General .Delivery == General .DeliveryEnum .SignedURLs :
122- out_dict = {obj .title : obj .signed_url_list for obj in results }
157+ out_dict = {obj [0 ].title : GuardList (obj [1 ].signed_url_list
158+ if not isinstance (obj [1 ], Exception )
159+ else obj [1 ])
160+ for obj in matched_results }
123161 elif config .General .Delivery == General .DeliveryEnum .LocalCache :
124- out_dict = {obj .title : obj .file_list for obj in results }
162+ out_dict = {obj [0 ].title : GuardList (obj [1 ].file_list
163+ if not isinstance (obj [1 ], Exception )
164+ else obj [1 ])
165+ for obj in matched_results }
125166
126167 if config .General .OutputDirectory :
127168 import yaml as yl
@@ -139,7 +180,8 @@ def _output_handler(config: ServiceXSpec, results: List[TransformedResults]):
139180def deliver (
140181 config : Union [ServiceXSpec , Mapping [str , Any ], str , Path ],
141182 config_path : Optional [str ] = None ,
142- servicex_name : Optional [str ] = None
183+ servicex_name : Optional [str ] = None ,
184+ return_exceptions : bool = True
143185):
144186 config = _load_ServiceXSpec (config )
145187
@@ -148,12 +190,13 @@ def deliver(
148190 group = DatasetGroup (datasets )
149191
150192 if config .General .Delivery == General .DeliveryEnum .SignedURLs :
151- results = group .as_signed_urls ()
152- return _output_handler (config , results )
193+ results = group .as_signed_urls (return_exceptions = return_exceptions )
194+ return _output_handler (config , datasets , results )
153195
154196 elif config .General .Delivery == General .DeliveryEnum .LocalCache :
155- results = group .as_files ()
156- return _output_handler (config , results )
197+ results = group .as_files (return_exceptions = return_exceptions )
198+ print (results )
199+ return _output_handler (config , datasets , results )
157200
158201
159202class ServiceXClient :
0 commit comments