11"""PEtab Problem class"""
22
33import os
4- from pathlib import Path
54import tempfile
5+ from pathlib import Path , PurePosixPath
66from typing import Dict , Iterable , List , Optional , Union
7+ from urllib .parse import unquote , urlparse , urlunparse
78from warnings import warn
89
9- import pandas as pd
1010import libsbml
11- from . import (parameter_mapping , measurements , conditions , parameters ,
12- sampling , sbml , yaml , core , observables , format_version )
11+ import pandas as pd
12+
13+ from . import (conditions , core , format_version , measurements , observables ,
14+ parameter_mapping , parameters , sampling , sbml , yaml )
1315from .C import * # noqa: F403
1416
1517__all__ = ['Problem' , 'get_default_condition_file_name' ,
@@ -88,13 +90,18 @@ def __setstate__(self, state):
8890 self .__dict__ .update (state )
8991
9092 @staticmethod
91- def from_files (sbml_file : str = None ,
92- condition_file : str = None ,
93- measurement_file : Union [str , Iterable [str ]] = None ,
94- parameter_file : Union [str , List [str ]] = None ,
95- visualization_files : Union [str , Iterable [str ]] = None ,
96- observable_files : Union [str , Iterable [str ]] = None
97- ) -> 'Problem' :
93+ def from_files (
94+ sbml_file : Union [str , Path , None ] = None ,
95+ condition_file : Union [str , Path , None ] = None ,
96+ measurement_file : Union [str , Path ,
97+ Iterable [Union [str , Path ]]] = None ,
98+ parameter_file : Union [str , Path ,
99+ Iterable [Union [str , Path ]]] = None ,
100+ visualization_files : Union [str , Path ,
101+ Iterable [Union [str , Path ]]] = None ,
102+ observable_files : Union [str , Path ,
103+ Iterable [Union [str , Path ]]] = None
104+ ) -> 'Problem' :
98105 """
99106 Factory method to load model and tables from files.
100107
@@ -146,18 +153,41 @@ def from_files(sbml_file: str = None,
146153 visualization_df = visualization_df )
147154
148155 @staticmethod
149- def from_yaml (yaml_config : Union [Dict , str ]) -> 'Problem' :
156+ def from_yaml (yaml_config : Union [Dict , Path , str ]) -> 'Problem' :
150157 """
151158 Factory method to load model and tables as specified by YAML file.
152159
153160 Arguments:
154161 yaml_config: PEtab configuration as dictionary or YAML file name
155162 """
163+ if isinstance (yaml_config , Path ):
164+ yaml_config = str (yaml_config )
165+
166+ get_path = lambda filename : filename # noqa: E731
156167 if isinstance (yaml_config , str ):
157- path_prefix = os . path . dirname ( yaml_config )
168+ yaml_path = yaml_config
158169 yaml_config = yaml .load_yaml (yaml_config )
159- else :
160- path_prefix = ""
170+
171+ # yaml_config may be path or URL
172+ path_url = urlparse (yaml_path )
173+ if not path_url .scheme or \
174+ (path_url .scheme != 'file' and not path_url .netloc ):
175+ # a regular file path string
176+ path_prefix = Path (yaml_path ).parent
177+ get_path = lambda filename : \
178+ path_prefix / filename # noqa: E731
179+ else :
180+ # a URL
181+ # extract parent path from
182+ url_path = unquote (urlparse (yaml_path ).path )
183+ parent_path = str (PurePosixPath (url_path ).parent )
184+ path_prefix = urlunparse (
185+ (path_url .scheme , path_url .netloc , parent_path ,
186+ path_url .params , path_url .query , path_url .fragment )
187+ )
188+ # need "/" on windows, not "\"
189+ get_path = lambda filename : \
190+ f"{ path_prefix } /{ filename } " # noqa: E731
161191
162192 if yaml .is_composite_problem (yaml_config ):
163193 raise ValueError ('petab.Problem.from_yaml() can only be used for '
@@ -176,26 +206,21 @@ def from_yaml(yaml_config: Union[Dict, str]) -> 'Problem':
176206
177207 if isinstance (yaml_config [PARAMETER_FILE ], list ):
178208 parameter_file = [
179- os .path .join (path_prefix , f )
180- for f in yaml_config [PARAMETER_FILE ]
209+ get_path (f ) for f in yaml_config [PARAMETER_FILE ]
181210 ]
182211 else :
183- parameter_file = os .path .join (
184- path_prefix , yaml_config [PARAMETER_FILE ])
212+ parameter_file = get_path (yaml_config [PARAMETER_FILE ])
185213
186214 return Problem .from_files (
187- sbml_file = os . path . join ( path_prefix , problem0 [SBML_FILES ][0 ]),
188- measurement_file = [os . path . join ( path_prefix , f )
215+ sbml_file = get_path ( problem0 [SBML_FILES ][0 ]),
216+ measurement_file = [get_path ( f )
189217 for f in problem0 [MEASUREMENT_FILES ]],
190- condition_file = os .path .join (
191- path_prefix , problem0 [CONDITION_FILES ][0 ]),
218+ condition_file = get_path (problem0 [CONDITION_FILES ][0 ]),
192219 parameter_file = parameter_file ,
193220 visualization_files = [
194- os .path .join (path_prefix , f )
195- for f in problem0 .get (VISUALIZATION_FILES , [])],
221+ get_path (f ) for f in problem0 .get (VISUALIZATION_FILES , [])],
196222 observable_files = [
197- os .path .join (path_prefix , f )
198- for f in problem0 .get (OBSERVABLE_FILES , [])]
223+ get_path (f ) for f in problem0 .get (OBSERVABLE_FILES , [])]
199224 )
200225
201226 @staticmethod
@@ -273,7 +298,7 @@ def from_combine(filename: Union[Path, str]) -> 'Problem':
273298 def to_files_generic (
274299 self ,
275300 prefix_path : Union [str , Path ],
276- ) -> None :
301+ ) -> str :
277302 """Save a PEtab problem to generic file names.
278303
279304 The PEtab problem YAML file is always created. PEtab data files are
@@ -318,15 +343,16 @@ def to_files_generic(
318343 return str (prefix_path / filenames ['yaml_file' ])
319344
320345 def to_files (self ,
321- sbml_file : Optional [str ] = None ,
322- condition_file : Optional [str ] = None ,
323- measurement_file : Optional [str ] = None ,
324- parameter_file : Optional [str ] = None ,
325- visualization_file : Optional [str ] = None ,
326- observable_file : Optional [str ] = None ,
327- yaml_file : Optional [str ] = None ,
328- prefix_path : Optional [Union [str , Path ]] = None ,
329- relative_paths : bool = True ,) -> None :
346+ sbml_file : Union [None , str , Path ] = None ,
347+ condition_file : Union [None , str , Path ] = None ,
348+ measurement_file : Union [None , str , Path ] = None ,
349+ parameter_file : Union [None , str , Path ] = None ,
350+ visualization_file : Union [None , str , Path ] = None ,
351+ observable_file : Union [None , str , Path ] = None ,
352+ yaml_file : Union [None , str , Path ] = None ,
353+ prefix_path : Union [None , str , Path ] = None ,
354+ relative_paths : bool = True ,
355+ ) -> None :
330356 """
331357 Write PEtab tables to files for this problem
332358
0 commit comments