diff --git a/pm4py/objects/log/importer/xes/importer.py b/pm4py/objects/log/importer/xes/importer.py index 95ba01be4..b43f82bd4 100644 --- a/pm4py/objects/log/importer/xes/importer.py +++ b/pm4py/objects/log/importer/xes/importer.py @@ -17,7 +17,7 @@ import importlib.util from enum import Enum -from pm4py.objects.log.importer.xes.variants import iterparse, line_by_line, iterparse_mem_compressed, iterparse_20, chunk_regex +from pm4py.objects.log.importer.xes.variants import iterparse, line_by_line, iterparse_mem_compressed, iterparse_20, chunk_regex, rustxes class Variants(Enum): @@ -26,6 +26,7 @@ class Variants(Enum): ITERPARSE_MEM_COMPRESSED = iterparse_mem_compressed ITERPARSE_20 = iterparse_20 CHUNK_REGEX = chunk_regex + RUSTXES = rustxes if importlib.util.find_spec("lxml"): @@ -71,6 +72,8 @@ def apply(path, parameters=None, variant=DEFAULT_VARIANT): variant = Variants.ITERPARSE_20 elif variant == "iterparse_mem_compressed": variant = Variants.ITERPARSE_MEM_COMPRESSED + elif variant == "rustxes": + variant = Variants.RUSTXES log = variant.value.apply(path, parameters=parameters) diff --git a/pm4py/objects/log/importer/xes/variants/rustxes.py b/pm4py/objects/log/importer/xes/variants/rustxes.py new file mode 100644 index 000000000..15d51e130 --- /dev/null +++ b/pm4py/objects/log/importer/xes/variants/rustxes.py @@ -0,0 +1,31 @@ +from enum import Enum +from pm4py.util import exec_utils +from typing import Optional, Dict, Any, Union +from pm4py.objects.log.obj import EventLog +from pm4py.objects.conversion.log import converter as log_converter +import pandas as pd +from copy import copy + + +class Parameters(Enum): + RETURN_LEGACY_LOG_OBJECT = "return_legacy_log_object" + + +def apply(log_path: str, parameters: Optional[Dict[Any, Any]] = None) -> Union[EventLog, pd.DataFrame]: + if parameters is None: + parameters = {} + + return_legacy_log_object = exec_utils.get_param_value(Parameters.RETURN_LEGACY_LOG_OBJECT, parameters, True) + + import rustxes + + log = rustxes.import_xes(log_path) + log = log[0].to_pandas() + + if return_legacy_log_object: + this_parameters = copy(parameters) + this_parameters["stream_postprocessing"] = True + + log = log_converter.apply(log, variant=log_converter.Variants.TO_EVENT_LOG, parameters=this_parameters) + + return log diff --git a/pm4py/read.py b/pm4py/read.py index 80b487253..bba99c07a 100644 --- a/pm4py/read.py +++ b/pm4py/read.py @@ -72,6 +72,8 @@ def read_xes(file_path: str, variant: str = "lxml", return_legacy_log_object: bo v = xes_importer.Variants.LINE_BY_LINE elif variant == "chunk_regex": v = xes_importer.Variants.CHUNK_REGEX + elif variant == "rustxes": + v = xes_importer.Variants.RUSTXES from copy import copy parameters = copy(kwargs) diff --git a/requirements_stable.txt b/requirements_stable.txt index 9620ff5e8..4cc3d3c9e 100644 --- a/requirements_stable.txt +++ b/requirements_stable.txt @@ -1,5 +1,5 @@ colorama==0.4.6 -contourpy==1.1.1 +contourpy==1.2.0 cycler==0.12.1 deprecation==2.1.0 fonttools==4.44.0 diff --git a/tests/xes_impexp_test.py b/tests/xes_impexp_test.py index 4c104e74b..df08db2b8 100644 --- a/tests/xes_impexp_test.py +++ b/tests/xes_impexp_test.py @@ -51,6 +51,14 @@ def test_importXESfromGZIP_imp2(self): log = xes_importer.apply(os.path.join(COMPRESSED_INPUT_DATA, "01_running-example.xes.gz")) del log + def test_rustxes_xes_import(self): + log = xes_importer.apply(os.path.join(INPUT_DATA_DIR, "receipt.xes"), variant=xes_importer.Variants.RUSTXES) + self.assertEqual(len(log), 1434) + + def test_rustxes_xesgz_import(self): + log = xes_importer.apply(os.path.join(INPUT_DATA_DIR, "bpic2012.xes.gz"), variant=xes_importer.Variants.RUSTXES) + self.assertEqual(len(log), 13087) + if __name__ == "__main__": unittest.main()