From 5075547a9a3398ed47b5189bd33a9ac8ed8c4d9b Mon Sep 17 00:00:00 2001 From: Jorge Lisa <64639359+AcquaDiGiorgio@users.noreply.github.com> Date: Mon, 2 Feb 2026 16:20:12 +0100 Subject: [PATCH 01/21] feat: UploadLogFile command implementation First approach, needs review --- src/dirac_cwl/commands/__init__.py | 3 +- src/dirac_cwl/commands/upload_log_file.py | 110 +++++++++++++++++++++ test/test_commands.py | 112 ++++++++++++++++++++++ 3 files changed, 224 insertions(+), 1 deletion(-) create mode 100644 src/dirac_cwl/commands/upload_log_file.py create mode 100644 test/test_commands.py diff --git a/src/dirac_cwl/commands/__init__.py b/src/dirac_cwl/commands/__init__.py index 01e8b17..aa213e4 100644 --- a/src/dirac_cwl/commands/__init__.py +++ b/src/dirac_cwl/commands/__init__.py @@ -1,5 +1,6 @@ """Command classes for workflow pre/post-processing operations.""" from .core import PostProcessCommand, PreProcessCommand +from .upload_log_file import UploadLogFile -__all__ = ["PreProcessCommand", "PostProcessCommand"] +__all__ = ["PreProcessCommand", "PostProcessCommand", "UploadLogFile"] diff --git a/src/dirac_cwl/commands/upload_log_file.py b/src/dirac_cwl/commands/upload_log_file.py new file mode 100644 index 0000000..7bcf8a5 --- /dev/null +++ b/src/dirac_cwl/commands/upload_log_file.py @@ -0,0 +1,110 @@ +"""Post-processing command for uploading logging information to a Storage Element.""" + +import glob +import os +import stat +import time +import zipfile + +from DIRACCommon.Core.Utilities.ReturnValues import S_ERROR, S_OK, returnSingleResult + +from dirac_cwl_proto.commands import PostProcessCommand +from dirac_cwl_proto.data_management_mocks.data_manager import MockDataManager as DataManager + + +def zip_files(outputFile, files=None, directory=None): + """Zip list of files.""" + with zipfile.ZipFile(outputFile, "w") as zipped: + for fileIn in files: + # ZIP does not support timestamps before 1980, so for those we simply "touch" + st = os.stat(fileIn) + mtime = time.localtime(st.st_mtime) + dateTime = mtime[0:6] + if dateTime[0] < 1980: + os.utime(fileIn, None) # same as "touch" + + zipped.write(fileIn) + + +def obtain_output_files(job_path): + """Obtain the files to be added to the log zip from the outputs.""" + log_file_extensions = [ + "*.txt", + "*.log", + "*.out", + "*.output", + "*.xml", + "*.sh", + "*.info", + "*.err", + "prodConf*.py", + "prodConf*.json", + ] + + files = [] + + for extension in log_file_extensions: + glob_list = glob.glob(extension, root_dir=job_path, recursive=True) + for check in glob_list: + path = os.path.join(job_path, check) + if os.path.isfile(path): + os.chmod(path, stat.S_IRWXU | stat.S_IRGRP | stat.S_IXGRP | stat.S_IROTH + stat.S_IXOTH) + files.append(path) + + return files + + +def get_zip_lfn(production_id, job_id, namespace, config_version): + """Form a logical file name from certain information from the workflow.""" + production_id = str(production_id).zfill(8) + job_id = str(job_id).zfill(8) + jobindex = str(int(int(job_id) / 10000)).zfill(4) + + log_path = os.path.join("/lhcb", namespace, config_version, "LOG", production_id, jobindex, "") + file_path = os.path.join(log_path, f"{job_id}.zip") + return file_path + + +class UploadLogFile(PostProcessCommand): + """Post-processing command for log file uploading.""" + + def execute(self, job_path, **kwargs): + """Execute the log uploading process. + + :param job_path: Path to the job working directory. + :param kwargs: Additional keyword arguments. + """ + # Obtain workflow information + output_files = kwargs.get("outputs", None) + job_id = kwargs.get("job_id", None) + production_id = kwargs.get("production_id", None) + namespace = kwargs.get("namespace", None) + config_version = kwargs.get("config_version", None) + + if not output_files: + output_files = obtain_output_files(job_path) + + if not job_path or not production_id or not namespace or not config_version: + return S_ERROR("Not enough information to perform the log upload") + + # Zip files + zip_name = job_id.zfill(8) + ".zip" + zip_path = os.path.join(job_path, zip_name) + zip_files(zip_path, output_files) + + # Obtain the log destination + file_lfn = get_zip_lfn(production_id, job_id, namespace, config_version) + + # Upload to the SE + dm = DataManager() + result = returnSingleResult(dm.put(file_lfn, zip_path, "LogSE")) + + if not result["OK"]: # Failed to uplaod to the LogSE + # TODO: "Tier1-Failover" should be a list of SEs and try until either it works or runs out of possible SEs + # The list is obtained from getDestinationSEList at ResolveSE.py in DIRAC + # The retry is done at transferAndRegisterFile at FailoverTransfer.py in DIRAC + result = returnSingleResult(dm.putAndRegister(file_lfn, zip_path, "Tier1-Failover")) + if not result["OK"]: # Failed to upload to the Failover SE + return S_ERROR("Failed to upload to FailoverSE") + + return S_OK() diff --git a/test/test_commands.py b/test/test_commands.py new file mode 100644 index 0000000..ec0cb83 --- /dev/null +++ b/test/test_commands.py @@ -0,0 +1,112 @@ +""".""" + +import os +import tempfile + +import pytest +from DIRACCommon.Core.Utilities.ReturnValues import S_OK +from pytest_mock import MockerFixture + +from dirac_cwl_proto.commands import UploadLogFile + + +class TestUploadLogFile: + """Collection of tests for the UploadLogFile command.""" + + FILENAMES = ["file.txt", "file.log", "file.err", "file.out", "file.extra"] + JOB_ID = "8042" + PRODUCTION_ID = "95376" + NAMESPACE = "MC" + CONFIG_VERSION = "2016" + + @pytest.fixture + def basedir(self): + """Fixture to initialize the working directory.""" + with tempfile.TemporaryDirectory() as tmpdir: + for file in self.FILENAMES: + with open(os.path.join(tmpdir, file), "x") as f: + f.write("EMPTY") + + yield tmpdir + + def test_upload_ok(self, basedir, mocker: MockerFixture): + """Test a correct upload.""" + base_lfn = f"/lhcb/{self.NAMESPACE}/{self.CONFIG_VERSION}/LOG/{self.PRODUCTION_ID.zfill(8)}/0000/" + zip_name = self.JOB_ID.zfill(8) + ".zip" + + expected_lfn = os.path.join(base_lfn, zip_name) + expected_zip = os.path.join(basedir, zip_name) + + mock_put = mocker.patch("dirac_cwl_proto.data_management_mocks.data_manager.MockDataManager.put") + mock_putAndRegister = mocker.patch( + "dirac_cwl_proto.data_management_mocks.data_manager.MockDataManager.putAndRegister", + ) + + mock_put.return_value = S_OK({"Successful": {expected_lfn: "OKAY"}, "Failed": {}}) + + result = UploadLogFile().execute( + basedir, + job_id=self.JOB_ID, + production_id=self.PRODUCTION_ID, + namespace=self.NAMESPACE, + config_version=self.CONFIG_VERSION, + ) + + mock_put.assert_called_once_with(expected_lfn, expected_zip, "LogSE") + mock_putAndRegister.assert_not_called() + assert result["OK"] + + def test_upload_ok_to_failover(self, basedir, mocker: MockerFixture): + """Test a failure to upload to the LogSE but a correct one to the Failover.""" + base_lfn = f"/lhcb/{self.NAMESPACE}/{self.CONFIG_VERSION}/LOG/{self.PRODUCTION_ID.zfill(8)}/0000/" + zip_name = self.JOB_ID.zfill(8) + ".zip" + + expected_lfn = os.path.join(base_lfn, zip_name) + expected_zip = os.path.join(basedir, zip_name) + + mock_put = mocker.patch("dirac_cwl_proto.data_management_mocks.data_manager.MockDataManager.put") + mock_putAndRegister = mocker.patch( + "dirac_cwl_proto.data_management_mocks.data_manager.MockDataManager.putAndRegister", + ) + + mock_put.return_value = S_OK({"Successful": {}, "Failed": {expected_lfn: "Borked"}}) + mock_putAndRegister.return_value = S_OK({"Successful": {expected_lfn: "OKAY"}, "Failed": {}}) + + result = UploadLogFile().execute( + basedir, + job_id=self.JOB_ID, + production_id=self.PRODUCTION_ID, + namespace=self.NAMESPACE, + config_version=self.CONFIG_VERSION, + ) + + mock_put.assert_called_once_with(expected_lfn, expected_zip, "LogSE") + mock_putAndRegister.assert_called_once_with(expected_lfn, expected_zip, "Tier1-Failover") + assert result["OK"] + + def test_upload_fail(self, basedir, mocker: MockerFixture): + """Test both a failure to LogSE and the FailoverSE.""" + base_lfn = f"/lhcb/{self.NAMESPACE}/{self.CONFIG_VERSION}/LOG/{self.PRODUCTION_ID.zfill(8)}/0000/" + zip_name = self.JOB_ID.zfill(8) + ".zip" + + expected_lfn = os.path.join(base_lfn, zip_name) + + mock_put = mocker.patch("dirac_cwl_proto.data_management_mocks.data_manager.MockDataManager.put") + mock_putAndRegister = mocker.patch( + "dirac_cwl_proto.data_management_mocks.data_manager.MockDataManager.putAndRegister", + ) + + mock_put.return_value = S_OK({"Successful": {}, "Failed": {expected_lfn: "Borked"}}) + mock_putAndRegister.return_value = S_OK({"Successful": {}, "Failed": {expected_lfn: "Borked"}}) + + result = UploadLogFile().execute( + basedir, + job_id=self.JOB_ID, + production_id=self.PRODUCTION_ID, + namespace=self.NAMESPACE, + config_version=self.CONFIG_VERSION, + ) + + assert not result["OK"] + + # TO TEST: Failed to zip files - No outputs generated by the job From 7a03ef2db9d9f54eb1bb9ea399ccec74c92bf52f Mon Sep 17 00:00:00 2001 From: Jorge Lisa <64639359+AcquaDiGiorgio@users.noreply.github.com> Date: Wed, 4 Feb 2026 16:25:54 +0100 Subject: [PATCH 02/21] chore: improve UploadLogFile tests --- test/test_commands.py | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/test/test_commands.py b/test/test_commands.py index ec0cb83..56729f7 100644 --- a/test/test_commands.py +++ b/test/test_commands.py @@ -29,6 +29,15 @@ def basedir(self): yield tmpdir + def test_correct_file_finding(self, basedir): + """Test output file finding.""" + from dirac_cwl_proto.commands.upload_log_file import obtain_output_files + + files = obtain_output_files(basedir) + files_names = [os.path.basename(file_path) for file_path in files] + + assert set(self.FILENAMES).difference(files_names) == {"file.extra"} + def test_upload_ok(self, basedir, mocker: MockerFixture): """Test a correct upload.""" base_lfn = f"/lhcb/{self.NAMESPACE}/{self.CONFIG_VERSION}/LOG/{self.PRODUCTION_ID.zfill(8)}/0000/" @@ -85,11 +94,12 @@ def test_upload_ok_to_failover(self, basedir, mocker: MockerFixture): assert result["OK"] def test_upload_fail(self, basedir, mocker: MockerFixture): - """Test both a failure to LogSE and the FailoverSE.""" + """Test both a failure to upload to the LogSE and the FailoverSE.""" base_lfn = f"/lhcb/{self.NAMESPACE}/{self.CONFIG_VERSION}/LOG/{self.PRODUCTION_ID.zfill(8)}/0000/" zip_name = self.JOB_ID.zfill(8) + ".zip" expected_lfn = os.path.join(base_lfn, zip_name) + expected_zip = os.path.join(basedir, zip_name) mock_put = mocker.patch("dirac_cwl_proto.data_management_mocks.data_manager.MockDataManager.put") mock_putAndRegister = mocker.patch( @@ -107,6 +117,8 @@ def test_upload_fail(self, basedir, mocker: MockerFixture): config_version=self.CONFIG_VERSION, ) + mock_put.assert_called_once_with(expected_lfn, expected_zip, "LogSE") + mock_putAndRegister.assert_called_once_with(expected_lfn, expected_zip, "Tier1-Failover") assert not result["OK"] # TO TEST: Failed to zip files - No outputs generated by the job From fd1249699e1133f82cbb02f7a62670eb3cb97830 Mon Sep 17 00:00:00 2001 From: Jorge Lisa <64639359+AcquaDiGiorgio@users.noreply.github.com> Date: Wed, 11 Feb 2026 16:34:09 +0100 Subject: [PATCH 03/21] feat: Change UploadLogFile DataManager Mocks to real DIRAC Classes Improve UploadLogFile tests --- src/dirac_cwl/commands/upload_log_file.py | 190 ++++++++++++------- test/test_commands.py | 217 ++++++++++++++++++---- 2 files changed, 304 insertions(+), 103 deletions(-) diff --git a/src/dirac_cwl/commands/upload_log_file.py b/src/dirac_cwl/commands/upload_log_file.py index 7bcf8a5..1b12163 100644 --- a/src/dirac_cwl/commands/upload_log_file.py +++ b/src/dirac_cwl/commands/upload_log_file.py @@ -2,67 +2,23 @@ import glob import os +import random import stat import time import zipfile - -from DIRACCommon.Core.Utilities.ReturnValues import S_ERROR, S_OK, returnSingleResult +from urllib.parse import urljoin + +from DIRAC import S_ERROR, S_OK, siteName +from DIRAC.ConfigurationSystem.Client.Helpers.Operations import Operations +from DIRAC.Core.Utilities.Adler import fileAdler +from DIRAC.Core.Utilities.ReturnValues import returnSingleResult +from DIRAC.DataManagementSystem.Client.FailoverTransfer import FailoverTransfer +from DIRAC.DataManagementSystem.Utilities.ResolveSE import getDestinationSEList +from DIRAC.Resources.Catalog.PoolXMLFile import getGUID +from DIRAC.Resources.Storage.StorageElement import StorageElement +from DIRAC.WorkloadManagementSystem.Client.JobReport import JobReport from dirac_cwl_proto.commands import PostProcessCommand -from dirac_cwl_proto.data_management_mocks.data_manager import MockDataManager as DataManager - - -def zip_files(outputFile, files=None, directory=None): - """Zip list of files.""" - with zipfile.ZipFile(outputFile, "w") as zipped: - for fileIn in files: - # ZIP does not support timestamps before 1980, so for those we simply "touch" - st = os.stat(fileIn) - mtime = time.localtime(st.st_mtime) - dateTime = mtime[0:6] - if dateTime[0] < 1980: - os.utime(fileIn, None) # same as "touch" - - zipped.write(fileIn) - - -def obtain_output_files(job_path): - """Obtain the files to be added to the log zip from the outputs.""" - log_file_extensions = [ - "*.txt", - "*.log", - "*.out", - "*.output", - "*.xml", - "*.sh", - "*.info", - "*.err", - "prodConf*.py", - "prodConf*.json", - ] - - files = [] - - for extension in log_file_extensions: - glob_list = glob.glob(extension, root_dir=job_path, recursive=True) - for check in glob_list: - path = os.path.join(job_path, check) - if os.path.isfile(path): - os.chmod(path, stat.S_IRWXU | stat.S_IRGRP | stat.S_IXGRP | stat.S_IROTH + stat.S_IXOTH) - files.append(path) - - return files - - -def get_zip_lfn(production_id, job_id, namespace, config_version): - """Form a logical file name from certain information from the workflow.""" - production_id = str(production_id).zfill(8) - job_id = str(job_id).zfill(8) - jobindex = str(int(int(job_id) / 10000)).zfill(4) - - log_path = os.path.join("/lhcb", namespace, config_version, "LOG", production_id, jobindex, "") - file_path = os.path.join(log_path, f"{job_id}.zip") - return file_path class UploadLogFile(PostProcessCommand): @@ -75,36 +31,130 @@ def execute(self, job_path, **kwargs): :param kwargs: Additional keyword arguments. """ # Obtain workflow information - output_files = kwargs.get("outputs", None) job_id = kwargs.get("job_id", None) production_id = kwargs.get("production_id", None) namespace = kwargs.get("namespace", None) config_version = kwargs.get("config_version", None) - if not output_files: - output_files = obtain_output_files(job_path) - if not job_path or not production_id or not namespace or not config_version: return S_ERROR("Not enough information to perform the log upload") + ops = Operations() + log_extensions = ops.getValue("LogFiles/Extensions", []) + log_se = ops.getValue("LogStorage/LogSE", "LogSE") + + job_report = JobReport(job_id) + + output_files = self.obtain_output_files(job_path, log_extensions) + + if not output_files: + return S_OK("No files to upload") + # Zip files zip_name = job_id.zfill(8) + ".zip" zip_path = os.path.join(job_path, zip_name) - zip_files(zip_path, output_files) + + try: + self.zip_files(zip_path, output_files) + except (AttributeError, OSError, ValueError) as e: + job_report.setApplicationStatus("Failed to create zip of log files") + return S_OK(f"Failed to zip files: {repr(e)}") # Obtain the log destination - file_lfn = get_zip_lfn(production_id, job_id, namespace, config_version) + zip_lfn = self.get_zip_lfn(production_id, job_id, namespace, config_version) # Upload to the SE - dm = DataManager() - result = returnSingleResult(dm.put(file_lfn, zip_path, "LogSE")) + result = returnSingleResult(StorageElement(log_se).putFile({zip_lfn: zip_path})) if not result["OK"]: # Failed to uplaod to the LogSE - # TODO: "Tier1-Failover" should be a list of SEs and try until either it works or runs out of possible SEs - # The list is obtained from getDestinationSEList at ResolveSE.py in DIRAC - # The retry is done at transferAndRegisterFile at FailoverTransfer.py in DIRAC - result = returnSingleResult(dm.putAndRegister(file_lfn, zip_path, "Tier1-Failover")) - if not result["OK"]: # Failed to upload to the Failover SE + result = self.generate_failover_transfer(zip_path, zip_name, zip_lfn) + + if not result["OK"]: + job_report.setApplicationStatus("Failed To Upload Logs") return S_ERROR("Failed to upload to FailoverSE") - return S_OK() + # Set the Log URL parameter + result = returnSingleResult(StorageElement(log_se).getURL(zip_path, protocol="https")) + if not result["OK"]: + # The rule for interpreting what is to be deflated can be found in /eos/lhcb/grid/prod/lhcb/logSE/.htaccess + logHttpsURL = urljoin("https://lhcb-dirac-logse.web.cern.ch/lhcb-dirac-logse/", zip_lfn) + else: + logHttpsURL = result["Value"] + job_report.setJobParameter("Log URL", f'Log file directory') + + return S_OK("Log Files uploaded") + + def zip_files(self, outputFile, files=None, directory=None): + """Zip list of files.""" + with zipfile.ZipFile(outputFile, "w") as zipped: + for fileIn in files: + # ZIP does not support timestamps before 1980, so for those we simply "touch" + st = os.stat(fileIn) + mtime = time.localtime(st.st_mtime) + dateTime = mtime[0:6] + if dateTime[0] < 1980: + os.utime(fileIn, None) # same as "touch" + + zipped.write(fileIn) + + def obtain_output_files(self, job_path, extensions=[]): + """Obtain the files to be added to the log zip from the outputs.""" + log_file_extensions = extensions + + if not log_file_extensions: + log_file_extensions = [ + "*.txt", + "*.log", + "*.out", + "*.output", + "*.xml", + "*.sh", + "*.info", + "*.err", + "prodConf*.py", + "prodConf*.json", + ] + + files = [] + + for extension in log_file_extensions: + glob_list = glob.glob(extension, root_dir=job_path, recursive=True) + for check in glob_list: + path = os.path.join(job_path, check) + if os.path.isfile(path): + os.chmod(path, stat.S_IRWXU | stat.S_IRGRP | stat.S_IXGRP | stat.S_IROTH + stat.S_IXOTH) + files.append(path) + + return files + + def get_zip_lfn(self, production_id, job_id, namespace, config_version): + """Form a logical file name from certain information from the workflow.""" + production_id = str(production_id).zfill(8) + job_id = str(job_id).zfill(8) + jobindex = str(int(int(job_id) / 10000)).zfill(4) + + log_path = os.path.join("/lhcb", namespace, config_version, "LOG", production_id, jobindex, "") + path = os.path.join(log_path, f"{job_id}.zip") + return path + + def generate_failover_transfer(self, zip_path, zip_name, zip_lfn): + """Prepare a failover transfer .""" + failoverSEs = getDestinationSEList("Tier1-Failover", siteName()) + random.shuffle(failoverSEs) + + fileMetaDict = { + "Size": os.path.getsize(zip_path), + "LFN": zip_lfn, + "GUID": getGUID(zip_path), + "Checksum": fileAdler(zip_path), + "ChecksumType": "ADLER32", + } + + return FailoverTransfer().transferAndRegisterFile( + fileName=zip_name, + localPath=zip_path, + lfn=zip_lfn, + destinationSEList=failoverSEs, + fileMetaDict=fileMetaDict, + masterCatalogOnly=True, + ) diff --git a/test/test_commands.py b/test/test_commands.py index 56729f7..0a01e5a 100644 --- a/test/test_commands.py +++ b/test/test_commands.py @@ -2,9 +2,10 @@ import os import tempfile +from urllib.parse import urljoin import pytest -from DIRACCommon.Core.Utilities.ReturnValues import S_OK +from DIRACCommon.Core.Utilities.ReturnValues import S_ERROR, S_OK from pytest_mock import MockerFixture from dirac_cwl_proto.commands import UploadLogFile @@ -31,29 +32,54 @@ def basedir(self): def test_correct_file_finding(self, basedir): """Test output file finding.""" - from dirac_cwl_proto.commands.upload_log_file import obtain_output_files - - files = obtain_output_files(basedir) + files = UploadLogFile().obtain_output_files(basedir) files_names = [os.path.basename(file_path) for file_path in files] assert set(self.FILENAMES).difference(files_names) == {"file.extra"} + def test_correct_file_extension_finding(self, basedir): + """Test output file finding.""" + extensions = ["*.extra"] + files = UploadLogFile().obtain_output_files(basedir, extensions) + files_names = [os.path.basename(file_path) for file_path in files] + + assert set(self.FILENAMES).difference(files_names) == {"file.txt", "file.log", "file.err", "file.out"} + def test_upload_ok(self, basedir, mocker: MockerFixture): """Test a correct upload.""" base_lfn = f"/lhcb/{self.NAMESPACE}/{self.CONFIG_VERSION}/LOG/{self.PRODUCTION_ID.zfill(8)}/0000/" zip_name = self.JOB_ID.zfill(8) + ".zip" expected_lfn = os.path.join(base_lfn, zip_name) - expected_zip = os.path.join(basedir, zip_name) + expected_path = os.path.join(basedir, zip_name) - mock_put = mocker.patch("dirac_cwl_proto.data_management_mocks.data_manager.MockDataManager.put") - mock_putAndRegister = mocker.patch( - "dirac_cwl_proto.data_management_mocks.data_manager.MockDataManager.putAndRegister", - ) + # Mock Operations + mock_ops = mocker.patch("dirac_cwl_proto.commands.upload_log_file.Operations") + mock_ops.return_value.getValue = lambda value, default=None: default - mock_put.return_value = S_OK({"Successful": {expected_lfn: "OKAY"}, "Failed": {}}) + # Mock JobReport + mock_job_report = mocker.patch("dirac_cwl_proto.commands.upload_log_file.JobReport") + mock_set_app_status = mocker.MagicMock() + mock_set_job_parameter = mocker.MagicMock() + mock_job_report.return_value.setApplicationStatus = mock_set_app_status + mock_job_report.return_value.setJobParameter = mock_set_job_parameter - result = UploadLogFile().execute( + # Mock StorageElement + mock_se = mocker.patch("dirac_cwl_proto.commands.upload_log_file.StorageElement") + mock_put_file = mocker.MagicMock() + mock_get_url = mocker.MagicMock() + mock_put_file.return_value = S_OK({"Successful": {expected_lfn: "Borked"}, "Failed": {}}) + mock_get_url.return_value = S_OK(urljoin("https://lhcb-dirac-logse.web.cern.ch/", expected_lfn)) + mock_se.return_value.putFile = mock_put_file + mock_se.return_value.getURL = mock_get_url + + command = UploadLogFile() + + # Mock failover + mock_failover = mocker.patch.object(command, "generate_failover_transfer") + mock_failover.return_value = S_OK() + + result = command.execute( basedir, job_id=self.JOB_ID, production_id=self.PRODUCTION_ID, @@ -61,9 +87,12 @@ def test_upload_ok(self, basedir, mocker: MockerFixture): config_version=self.CONFIG_VERSION, ) - mock_put.assert_called_once_with(expected_lfn, expected_zip, "LogSE") - mock_putAndRegister.assert_not_called() assert result["OK"] + mock_get_url.assert_called_once_with(expected_path, protocol="https") + mock_put_file.assert_called_once_with({expected_lfn: expected_path}) + mock_failover.assert_not_called() + mock_set_app_status.assert_not_called() + mock_set_job_parameter.assert_called_once() def test_upload_ok_to_failover(self, basedir, mocker: MockerFixture): """Test a failure to upload to the LogSE but a correct one to the Failover.""" @@ -71,17 +100,35 @@ def test_upload_ok_to_failover(self, basedir, mocker: MockerFixture): zip_name = self.JOB_ID.zfill(8) + ".zip" expected_lfn = os.path.join(base_lfn, zip_name) - expected_zip = os.path.join(basedir, zip_name) + expected_path = os.path.join(basedir, zip_name) - mock_put = mocker.patch("dirac_cwl_proto.data_management_mocks.data_manager.MockDataManager.put") - mock_putAndRegister = mocker.patch( - "dirac_cwl_proto.data_management_mocks.data_manager.MockDataManager.putAndRegister", - ) + # Mock Operations + mock_ops = mocker.patch("dirac_cwl_proto.commands.upload_log_file.Operations") + mock_ops.return_value.getValue = lambda value, default=None: default - mock_put.return_value = S_OK({"Successful": {}, "Failed": {expected_lfn: "Borked"}}) - mock_putAndRegister.return_value = S_OK({"Successful": {expected_lfn: "OKAY"}, "Failed": {}}) + # Mock JobReport + mock_job_report = mocker.patch("dirac_cwl_proto.commands.upload_log_file.JobReport") + mock_set_app_status = mocker.MagicMock() + mock_set_job_parameter = mocker.MagicMock() + mock_job_report.return_value.setApplicationStatus = mock_set_app_status + mock_job_report.return_value.setJobParameter = mock_set_job_parameter - result = UploadLogFile().execute( + # Mock StorageElement + mock_se = mocker.patch("dirac_cwl_proto.commands.upload_log_file.StorageElement") + mock_put_file = mocker.MagicMock() + mock_get_url = mocker.MagicMock() + mock_put_file.return_value = S_OK({"Successful": {}, "Failed": {expected_lfn: "Borked"}}) + mock_get_url.return_value = S_OK(urljoin("https://lhcb-dirac-logse.web.cern.ch/", expected_lfn)) + mock_se.return_value.putFile = mock_put_file + mock_se.return_value.getURL = mock_get_url + + command = UploadLogFile() + + # Mock failover + mock_failover = mocker.patch.object(command, "generate_failover_transfer") + mock_failover.return_value = S_OK() + + result = command.execute( basedir, job_id=self.JOB_ID, production_id=self.PRODUCTION_ID, @@ -89,9 +136,12 @@ def test_upload_ok_to_failover(self, basedir, mocker: MockerFixture): config_version=self.CONFIG_VERSION, ) - mock_put.assert_called_once_with(expected_lfn, expected_zip, "LogSE") - mock_putAndRegister.assert_called_once_with(expected_lfn, expected_zip, "Tier1-Failover") assert result["OK"] + mock_get_url.assert_called_once_with(expected_path, protocol="https") + mock_put_file.assert_called_once_with({expected_lfn: expected_path}) + mock_failover.assert_called_once_with(expected_path, zip_name, expected_lfn) + mock_set_app_status.assert_not_called() + mock_set_job_parameter.assert_called_once() def test_upload_fail(self, basedir, mocker: MockerFixture): """Test both a failure to upload to the LogSE and the FailoverSE.""" @@ -99,15 +149,57 @@ def test_upload_fail(self, basedir, mocker: MockerFixture): zip_name = self.JOB_ID.zfill(8) + ".zip" expected_lfn = os.path.join(base_lfn, zip_name) - expected_zip = os.path.join(basedir, zip_name) + expected_path = os.path.join(basedir, zip_name) - mock_put = mocker.patch("dirac_cwl_proto.data_management_mocks.data_manager.MockDataManager.put") - mock_putAndRegister = mocker.patch( - "dirac_cwl_proto.data_management_mocks.data_manager.MockDataManager.putAndRegister", + # Mock JobReport + mock_job_report = mocker.patch("dirac_cwl_proto.commands.upload_log_file.JobReport") + mock_set_app_status = mocker.MagicMock() + mock_set_job_parameter = mocker.MagicMock() + mock_job_report.return_value.setApplicationStatus = mock_set_app_status + mock_job_report.return_value.setJobParameter = mock_set_job_parameter + + # Mock StorageElement + mock_se = mocker.patch("dirac_cwl_proto.commands.upload_log_file.StorageElement") + mock_put_file = mocker.MagicMock() + mock_get_url = mocker.MagicMock() + mock_put_file.return_value = S_OK({"Successful": {}, "Failed": {expected_lfn: "Borked"}}) + mock_get_url.return_value = S_OK(urljoin("https://lhcb-dirac-logse.web.cern.ch/", expected_lfn)) + mock_se.return_value.putFile = mock_put_file + mock_se.return_value.getURL = mock_get_url + + command = UploadLogFile() + + # Mock failover + mock_failover = mocker.patch.object(command, "generate_failover_transfer") + mock_failover.return_value = S_ERROR() + + result = command.execute( + basedir, + job_id=self.JOB_ID, + production_id=self.PRODUCTION_ID, + namespace=self.NAMESPACE, + config_version=self.CONFIG_VERSION, ) - mock_put.return_value = S_OK({"Successful": {}, "Failed": {expected_lfn: "Borked"}}) - mock_putAndRegister.return_value = S_OK({"Successful": {}, "Failed": {expected_lfn: "Borked"}}) + assert not result["OK"] + mock_get_url.assert_not_called() + mock_put_file.assert_called_once_with({expected_lfn: expected_path}) + mock_failover.assert_called_once_with(expected_path, zip_name, expected_lfn) + mock_set_app_status.assert_called_once() + mock_set_job_parameter.assert_not_called() + + def test_no_files_to_zip(self, basedir, mocker): + """Test execution when the job did not return any files.""" + import shutil + + shutil.rmtree(basedir) + + # Mock JobReport + mock_job_report = mocker.patch("dirac_cwl_proto.commands.upload_log_file.JobReport") + mock_set_app_status = mocker.MagicMock() + mock_set_job_parameter = mocker.MagicMock() + mock_job_report.return_value.setApplicationStatus = mock_set_app_status + mock_job_report.return_value.setJobParameter = mock_set_job_parameter result = UploadLogFile().execute( basedir, @@ -117,8 +209,67 @@ def test_upload_fail(self, basedir, mocker: MockerFixture): config_version=self.CONFIG_VERSION, ) - mock_put.assert_called_once_with(expected_lfn, expected_zip, "LogSE") - mock_putAndRegister.assert_called_once_with(expected_lfn, expected_zip, "Tier1-Failover") - assert not result["OK"] + assert result["OK"] + assert result["Value"] == "No files to upload" + mock_set_app_status.assert_not_called() + + def test_failed_to_zip(self, basedir, mocker: MockerFixture): + """Test failure while zipping.""" + command = UploadLogFile() + + # Mocker zip + mock_zip = mocker.patch.object(command, "zip_files") + mock_zip.side_effect = [AttributeError(), OSError(), ValueError()] + + # Mock JobReport + mock_job_report = mocker.patch("dirac_cwl_proto.commands.upload_log_file.JobReport") + mock_set_app_status = mocker.MagicMock() + mock_set_job_parameter = mocker.MagicMock() + mock_job_report.return_value.setApplicationStatus = mock_set_app_status + mock_job_report.return_value.setJobParameter = mock_set_job_parameter + + # Test raising AttributeError + result = command.execute( + basedir, + job_id=self.JOB_ID, + production_id=self.PRODUCTION_ID, + namespace=self.NAMESPACE, + config_version=self.CONFIG_VERSION, + ) + + assert result["OK"] + assert "Failed to zip files" in result["Value"] + assert "AttributeError" in result["Value"] + mock_set_app_status.assert_called_once_with("Failed to create zip of log files") + mock_set_app_status.reset_mock() + + result = command.execute( + basedir, + job_id=self.JOB_ID, + production_id=self.PRODUCTION_ID, + namespace=self.NAMESPACE, + config_version=self.CONFIG_VERSION, + ) + + # Test raising OSError + assert result["OK"] + assert "Failed to zip files" in result["Value"] + assert "OSError" in result["Value"] + mock_set_app_status.assert_called_once_with("Failed to create zip of log files") + mock_set_app_status.reset_mock() + + result = command.execute( + basedir, + job_id=self.JOB_ID, + production_id=self.PRODUCTION_ID, + namespace=self.NAMESPACE, + config_version=self.CONFIG_VERSION, + ) + + # Test raising ValueError + assert result["OK"] + assert "Failed to zip files" in result["Value"] + assert "ValueError" in result["Value"] + mock_set_app_status.assert_called_once_with("Failed to create zip of log files") - # TO TEST: Failed to zip files - No outputs generated by the job + mock_set_job_parameter.assert_not_called() From 8317c9f7661b8354364a02bb48b00b3c0c8bd6ca Mon Sep 17 00:00:00 2001 From: Jorge Lisa <64639359+AcquaDiGiorgio@users.noreply.github.com> Date: Thu, 12 Feb 2026 16:53:13 +0100 Subject: [PATCH 04/21] chore: Update project name at imports --- src/dirac_cwl/commands/upload_log_file.py | 6 ++++-- test/test_commands.py | 22 +++++++++++----------- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/src/dirac_cwl/commands/upload_log_file.py b/src/dirac_cwl/commands/upload_log_file.py index 1b12163..3e8f0a9 100644 --- a/src/dirac_cwl/commands/upload_log_file.py +++ b/src/dirac_cwl/commands/upload_log_file.py @@ -18,7 +18,7 @@ from DIRAC.Resources.Storage.StorageElement import StorageElement from DIRAC.WorkloadManagementSystem.Client.JobReport import JobReport -from dirac_cwl_proto.commands import PostProcessCommand +from dirac_cwl.commands import PostProcessCommand class UploadLogFile(PostProcessCommand): @@ -80,7 +80,9 @@ def execute(self, job_path, **kwargs): logHttpsURL = urljoin("https://lhcb-dirac-logse.web.cern.ch/lhcb-dirac-logse/", zip_lfn) else: logHttpsURL = result["Value"] - job_report.setJobParameter("Log URL", f'Log file directory') + + logHttpsURL = logHttpsURL.replace(".zip", "/") + job_report.setJobParameter("Log URL", f'Log file directory') return S_OK("Log Files uploaded") diff --git a/test/test_commands.py b/test/test_commands.py index 0a01e5a..6b9e8dc 100644 --- a/test/test_commands.py +++ b/test/test_commands.py @@ -8,7 +8,7 @@ from DIRACCommon.Core.Utilities.ReturnValues import S_ERROR, S_OK from pytest_mock import MockerFixture -from dirac_cwl_proto.commands import UploadLogFile +from dirac_cwl.commands import UploadLogFile class TestUploadLogFile: @@ -54,18 +54,18 @@ def test_upload_ok(self, basedir, mocker: MockerFixture): expected_path = os.path.join(basedir, zip_name) # Mock Operations - mock_ops = mocker.patch("dirac_cwl_proto.commands.upload_log_file.Operations") + mock_ops = mocker.patch("dirac_cwl.commands.upload_log_file.Operations") mock_ops.return_value.getValue = lambda value, default=None: default # Mock JobReport - mock_job_report = mocker.patch("dirac_cwl_proto.commands.upload_log_file.JobReport") + mock_job_report = mocker.patch("dirac_cwl.commands.upload_log_file.JobReport") mock_set_app_status = mocker.MagicMock() mock_set_job_parameter = mocker.MagicMock() mock_job_report.return_value.setApplicationStatus = mock_set_app_status mock_job_report.return_value.setJobParameter = mock_set_job_parameter # Mock StorageElement - mock_se = mocker.patch("dirac_cwl_proto.commands.upload_log_file.StorageElement") + mock_se = mocker.patch("dirac_cwl.commands.upload_log_file.StorageElement") mock_put_file = mocker.MagicMock() mock_get_url = mocker.MagicMock() mock_put_file.return_value = S_OK({"Successful": {expected_lfn: "Borked"}, "Failed": {}}) @@ -103,18 +103,18 @@ def test_upload_ok_to_failover(self, basedir, mocker: MockerFixture): expected_path = os.path.join(basedir, zip_name) # Mock Operations - mock_ops = mocker.patch("dirac_cwl_proto.commands.upload_log_file.Operations") + mock_ops = mocker.patch("dirac_cwl.commands.upload_log_file.Operations") mock_ops.return_value.getValue = lambda value, default=None: default # Mock JobReport - mock_job_report = mocker.patch("dirac_cwl_proto.commands.upload_log_file.JobReport") + mock_job_report = mocker.patch("dirac_cwl.commands.upload_log_file.JobReport") mock_set_app_status = mocker.MagicMock() mock_set_job_parameter = mocker.MagicMock() mock_job_report.return_value.setApplicationStatus = mock_set_app_status mock_job_report.return_value.setJobParameter = mock_set_job_parameter # Mock StorageElement - mock_se = mocker.patch("dirac_cwl_proto.commands.upload_log_file.StorageElement") + mock_se = mocker.patch("dirac_cwl.commands.upload_log_file.StorageElement") mock_put_file = mocker.MagicMock() mock_get_url = mocker.MagicMock() mock_put_file.return_value = S_OK({"Successful": {}, "Failed": {expected_lfn: "Borked"}}) @@ -152,14 +152,14 @@ def test_upload_fail(self, basedir, mocker: MockerFixture): expected_path = os.path.join(basedir, zip_name) # Mock JobReport - mock_job_report = mocker.patch("dirac_cwl_proto.commands.upload_log_file.JobReport") + mock_job_report = mocker.patch("dirac_cwl.commands.upload_log_file.JobReport") mock_set_app_status = mocker.MagicMock() mock_set_job_parameter = mocker.MagicMock() mock_job_report.return_value.setApplicationStatus = mock_set_app_status mock_job_report.return_value.setJobParameter = mock_set_job_parameter # Mock StorageElement - mock_se = mocker.patch("dirac_cwl_proto.commands.upload_log_file.StorageElement") + mock_se = mocker.patch("dirac_cwl.commands.upload_log_file.StorageElement") mock_put_file = mocker.MagicMock() mock_get_url = mocker.MagicMock() mock_put_file.return_value = S_OK({"Successful": {}, "Failed": {expected_lfn: "Borked"}}) @@ -195,7 +195,7 @@ def test_no_files_to_zip(self, basedir, mocker): shutil.rmtree(basedir) # Mock JobReport - mock_job_report = mocker.patch("dirac_cwl_proto.commands.upload_log_file.JobReport") + mock_job_report = mocker.patch("dirac_cwl.commands.upload_log_file.JobReport") mock_set_app_status = mocker.MagicMock() mock_set_job_parameter = mocker.MagicMock() mock_job_report.return_value.setApplicationStatus = mock_set_app_status @@ -222,7 +222,7 @@ def test_failed_to_zip(self, basedir, mocker: MockerFixture): mock_zip.side_effect = [AttributeError(), OSError(), ValueError()] # Mock JobReport - mock_job_report = mocker.patch("dirac_cwl_proto.commands.upload_log_file.JobReport") + mock_job_report = mocker.patch("dirac_cwl.commands.upload_log_file.JobReport") mock_set_app_status = mocker.MagicMock() mock_set_job_parameter = mocker.MagicMock() mock_job_report.return_value.setApplicationStatus = mock_set_app_status From 91cef733ce95ddccd6a0c5e2c6a657411be708c2 Mon Sep 17 00:00:00 2001 From: Jorge Lisa <64639359+AcquaDiGiorgio@users.noreply.github.com> Date: Mon, 27 Apr 2026 15:52:49 +0200 Subject: [PATCH 05/21] chore: setup lhcbdirac dependency to fork --- pixi.lock | 882 +++++++++++++++++++++++++++++++++++++++++++++++-- pyproject.toml | 1 + 2 files changed, 862 insertions(+), 21 deletions(-) diff --git a/pixi.lock b/pixi.lock index 64d2eac..31fec78 100644 --- a/pixi.lock +++ b/pixi.lock @@ -127,7 +127,11 @@ environments: - pypi: https://files.pythonhosted.org/packages/74/f5/9373290775639cb67a2fce7f629a1c240dce9f12fe927bc32b2736e16dfc/argcomplete-3.6.3-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/ed/c9/d7977eaacb9df673210491da99e6a247e93df98c715fc43fd136ce1d3d33/arrow-1.4.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/54/51/321e821856452f7386c4e9df866f196720b1ad0c5ea1623ea7399969ae3b/authlib-1.6.6-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/77/39/4d8414260c3d83f22029a39e51553c173611b378d62ca391e5ca68e65cfa/awkward-2.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ca/aa/ab2d6d68c3ee50f6dedbbc91a31cd38f9fede9258d54e7aca29bfca4ebc1/awkward_cpp-52-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl - pypi: https://files.pythonhosted.org/packages/fc/d8/b8fcba9464f02b121f39de2db2bf57f0b216fe11d014513d666e8634380d/azure_core-1.38.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/24/b4/11f8a31d8b67cca3371e046db49baa7c0594d71eb40ac8121e2fc0888db0/bcrypt-5.0.0-cp39-abi3-manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/1a/39/47f9197bdd44df24d67ac8893641e16f386c984a0619ef2ee4c51fbbc019/beautifulsoup4-4.14.3-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/5e/0a/3966f239e1d9da93cb755dc0213835ce4e9ed93645192878d0a055ecdc31/boto3-1.42.42-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/e6/51/aac7e419521d5519e13087a7198623655648c939822bd7f4bdc9ccbe07f9/botocore-1.42.42-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/ef/79/c45f2d53efe6ada1110cf6f9fca095e4ff47a0454444aefdde6ac4789179/cachecontrol-0.14.4-py3-none-any.whl @@ -136,6 +140,7 @@ environments: - pypi: https://files.pythonhosted.org/packages/67/ff/f6b948ca32e4f2a4576aa129d8bed61f2e0543bf9f5f2b7fc3758ed005c9/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - pypi: https://files.pythonhosted.org/packages/98/78/01c019cdb5d6498122777c1a43056ebb3ebfeef2076d9d026bfe15583b2b/click-8.3.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/a7/06/3d6badcf13db419e25b07041d9c7b4a2c331d3f4e7134445ec5df57714cd/coloredlogs-15.0.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/19/0f/f6121b90b86b9093c066889274d26a1de3f29969d45c2ed1ecbe2033cb78/cramjam-2.11.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - pypi: https://files.pythonhosted.org/packages/2b/08/f83e2e0814248b844265802d081f2fac2f1cbe6cd258e72ba14ff006823a/cryptography-46.0.4-cp311-abi3-manylinux_2_28_x86_64.whl - pypi: https://files.pythonhosted.org/packages/db/2b/1239938a2629c29363e07724d7bd4c87a8b566947ecee2afb5f5ac34e1bb/cwl_upgrader-1.2.14-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/63/4b/ccab2a5ca9e0b6553810b85c06387e60fc9443cec3c987e3a062705bd225/cwl_utils-0.40-py3-none-any.whl @@ -143,9 +148,10 @@ environments: - pypi: https://files.pythonhosted.org/packages/65/ee/a7aba2b112c5ae879d5cfb231c75189a7fd2a5e84b6af7e07dd71fb2bb35/cwltool-3.1.20260108082145-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/5a/36/17015b7bae2783f7bbde50a8bafdeb702802c080322204f1bfcae25b9e02/DB12-1.0.4-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/4e/8c/f3147f5c4b73e7550fe5f9352eaa956ae838d5c51eb58e7a25b9f3e2643b/decorator-5.2.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/75/c0/63d2ab6ef062e05e795fb49ebcd8a907c1d4f78d9f01c577266b12bd0da2/dirac-9.0.18-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/84/d0/205d54408c08b13550c733c4b85429e7ead111c7f0014309637425520a9a/deprecated-1.3.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d0/d0/9e71fdc3394ffc632f35946c572e60fcc2a5452ba0a23c52493f23d60672/dirac-9.1.6-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/9f/90/279f55fff9481f9e0424c3c97b24dc10004ec8d8f98ddf5afd07a7b79194/diraccfg-1.0.1-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/06/d2/500c9ae651fd3821ca70814aa40cb5ab9bab9b479387ccd8dcb4df745d44/diraccommon-9.0.18-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f8/b2/ad8e7e63fdf5add3ceb7a0805d700e9fd7cb7d5743f765a4994b4ec286d7/diraccommon-9.1.6-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/ab/7e/5f02b757bb825e5cdc65f6f7a12c209963bec877d61497393bea8f41f9ce/diracx_api-0.0.8-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/b0/28/87e78ff0d6041f40431d88b8aa3b645be7476a420d8dcbf7197f5b394c5c/diracx_cli-0.0.8-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/f2/61/0c78d9778bffd844863d3173a5fefb506d7131ceebecee523a9e27024aa1/diracx_client-0.0.8-py3-none-any.whl @@ -154,7 +160,10 @@ environments: - pypi: https://files.pythonhosted.org/packages/dc/80/12235e5b75bb2c586733280854f131b86051e0bbdfb55349ff70d0f72cf9/dogpile_cache-1.5.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/58/19/0380af745f151a1648657bbcef0fb49ac28bf09083d94498163ffd9b32dc/dominate-2.9.1-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/de/15/545e2b6cf2e3be84bc1ed85613edd75b8aea69807a71c26f4ca6a9258e82/email_validator-2.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/37/f9/f8497ef8b873a8bb2a750ee2a6c5f0fc22258e1acb6245fd237042a6c279/fabric-3.2.3-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/a7/b2/fabede9fafd976b991e9f1b9c8c873ed86f202889b864756f240ce6dd855/frozenlist-1.8.0-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/d5/1f/5f4a3cd9e4440e9d9bc78ad0a91a1c8d46b4d429d5239ebe6793c9fe5c41/fsspec-2026.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/73/90/a2c51050d9254bd9134e6368b3f94f92f0eb2c34ed0ca19ec449ce2fc288/fsspec_xrootd-0.5.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/5f/e8/2e6301567e6debaad6abae0e217428471651ce877537b7095b6a8e7d8cd2/fts3-3.14.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/a0/61/5c78b91c3143ed5c14207f463aecfc8f9dbb5092fb2869baf37c273b2705/gitdb-4.0.12-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/b0/57/dea471da24ceac6de8c3dc5d37e4ddde57a5c340d6bac90010898734de34/gitlint_core-0.19.1-py3-none-any.whl @@ -164,17 +173,25 @@ environments: - pypi: https://files.pythonhosted.org/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/f0/0f/310fb31e39e2d734ccaa2c0fb981ee41f7bd5056ce9bc29b2248bd569169/humanfriendly-10.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d0/23/49cf8ea1d129637941f06fb78f5f66077bf362762c5f6c01712c4cd0e87f/hyperscan-0.8.2-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl - pypi: https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/fa/5e/f8e9a1d23b9c20a551a8a02ea3637b4642e22c2626e3a13a9a29cdea99eb/importlib_metadata-8.7.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/a4/ed/1f1afb2e9e7f38a545d628f864d562a5ae64fe6f7a10e28ffb9b185b4e89/importlib_resources-6.5.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/32/4b/b99e37f88336009971405cbb7630610322ed6fbfa31e1d7ab3fbf3049a2d/invoke-2.2.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/15/aa/0aca39a37d3c7eb941ba736ede56d689e7be91cab5d9ca846bde3999eba6/isodate-0.7.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/14/2f/967ba146e6d58cf6a652da73885f52fc68001525b4197effc174321d70b4/jmespath-1.1.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/a1/01/9674cc6d478406ae61d910cb16ca8b5699a8a9e6a2019987ebe5a5957d1d/joserfc-1.6.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/ba/24/c65fe1aef4e0681cb17ca136eb0f3e20a47d3941a306bc9d636938029ca5/lb_telemetry-0.5.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/87/a4/afc9dddc6b14fb3d52a900cd9b4c77770128edc4b07e576034bbd0ffd290/LbCondaWrappers-0.5.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/d7/4c/f3b97c7d6008b3a895bbadb2deb44ad3446ae5fe204c72cd540dc222e57d/lbenv-2.4.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/16/4a/b4d7feb029d4e75d4882d8d1d9029938c31a2e73074f87ffcff0f4a8ba9e/lbplatformutils-4.5.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/6d/10/b37ac718c5903758fa9058a5182026a4f3b65443196b82c7840389ea0dbd/lbplatformutils-4.6.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/02/64/c86924898062e8217ed914a29458cfde9e4a9b80e4d4cbcca141983ba339/lbprodrun-1.12.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/29/ce/ed422816fb30ffa3bc11597b30d5deca06b4a1388707a04215da73c65b53/levenshtein-0.27.3-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl + - pypi: git+ssh://git@gitlab.cern.ch:7999/jlisalab/LHCbDIRAC.git?rev=modules-to-cwl-migration#c441175f3289d6d85abf5d5612c3ff964edd9a5c + - pypi: https://files.pythonhosted.org/packages/7f/37/8ea3555769b6048b5e4ec162cc90fd32e761c0e381ffb3baf888cb0d8a71/lhcbdiracx_api-0.0.8-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/68/15/bfb0c717b8f23c16907f3e73e8f56010ccd72e9900a108209665b0d9ed4b/lhcbdiracx_cli-0.0.8-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2d/88/67602dfa2d7ab5d0518af82db34ab4d70dc2c3029b3ca788299a3be4a96d/lhcbdiracx_client-0.0.8-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/34/8f/6105afdd8f4e1f3b198d09e4b2622622923d9fa9e077aed852c0bb035a3a/lhcbdiracx_core-0.0.8-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/b3/68/aa714515d65090fcbcc9a1f3debd5a644b14aad11e59238f42f00bd4b298/logzero-1.7.0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/29/9c/47293c58cc91769130fbf85531280e8cc7868f7fbb6d92f4670071b9cb3e/lxml-6.0.2-cp314-cp314-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl - pypi: https://files.pythonhosted.org/packages/94/54/e7d793b573f298e1c9013b8c4dade17d481164aa517d1d7148619c2cedbf/markdown_it_py-4.0.0-py3-none-any.whl @@ -183,6 +200,8 @@ environments: - pypi: https://files.pythonhosted.org/packages/2f/40/dc34d1a8d5f1e51fc64640b62b191684da52ca469da9cd74e84936ffa4a6/msgpack-1.1.2-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - pypi: https://files.pythonhosted.org/packages/fe/3b/8ec5074bcfc450fe84273713b4b0a0dd47c0249358f5d82eb8104ffe2520/multidict-6.7.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - pypi: https://files.pythonhosted.org/packages/9e/c9/b2622292ea83fbb4ec318f5b9ab867d0a28ab43c5717bb85b0a5f6b3b0a4/networkx-3.6.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/15/88/3cdd54fa279341afa10acf8d2b503556b1375245dccc9315659f795dd2e9/pandas-3.0.2-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/a9/90/a744336f5af32c433bd09af7854599682a383b37cfd78f7de263de6ad6cb/paramiko-4.0.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/9e/c3/059298687310d527a58bb01f3b1965787ee3b40dce76752eda8b44e9a2c5/pexpect-4.9.0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/84/03/0d3ce49e2505ae70cf43bc5bb3033955d2fc9f932163e84dc0779cc47f48/prompt_toolkit-3.0.52-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/b2/f2/889ad4b2408f72fe1a4f6a19491177b30ea7bf1a0fd5f17050ca08cfc882/propcache-0.4.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl @@ -195,12 +214,16 @@ environments: - pypi: https://files.pythonhosted.org/packages/c1/60/5d4751ba3f4a40a6891f24eec885f51afd78d208498268c734e256fb13c4/pydantic_settings-2.12.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/7e/32/a7125fb28c4261a627f999d5fb4afff25b523800faed2c30979949d6facd/pydot-4.0.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/6f/01/c26ce75ba460d5cd503da9e13b21a33804d38c2165dec7b716d06b13010c/pyjwt-2.11.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3e/d0/f301f83ac8dbe53442c5a43f6a39016f94f754d7a9815a875b65e218a307/pynacl-1.6.2-cp38-abi3-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl - pypi: https://files.pythonhosted.org/packages/10/bd/c038d7cc38edc1aa5bf91ab8068b63d4308c66c4c8bb3cbba7dfbc049f9c/pyparsing-3.3.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/14/1b/a298b06749107c305e1fe0f814c6c74aea7b2f1e10989cb30f544a1b3253/python_dotenv-1.2.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/38/ee/a61bb562bdf6f0bc6c51cdcf80ab5503cbb4b2f5053fa4b054cc0a56e48a/python_gitlab-8.2.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/81/c4/34e93fe5f5429d7570ec1fa436f1986fb1f00c3e0f43a589fe2bbcd22c3f/pytz-2025.2-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c8/85/9535df0b78ba51f478c9ce7eb6d1f85535cc31fe356773b48fd9d3e563ca/rapidfuzz-3.14.5-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl - pypi: https://files.pythonhosted.org/packages/b9/20/35d2baebacf357b562bd081936b66cd845775442973cb033a377fd639a84/rdflib-7.5.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/1e/db/4254e3eabe8020b458f1a747140d32277ec7a271daf1d235b70dc0b4e6e3/requests-2.32.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3f/51/d4db610ef29373b879047326cbf6fa98b6c1969d6f6dc423279de2b1be2c/requests_toolbelt-1.0.0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/ef/45/615f5babd880b4bd7d405cc0dc348234c5ffb6ed1ea33e152ede08b2072d/rich-14.3.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/04/80/97b6f357ac458d9ad9872cc3183ca09ef7439ac89e030ea43053ba1294b6/rich_argparse-1.7.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/af/fe/b6045c782f1fd1ae317d2a6ca1884857ce5c20f59befe6ab25a8603c43a7/ruamel_yaml-0.18.17-py3-none-any.whl @@ -212,6 +235,7 @@ environments: - pypi: https://files.pythonhosted.org/packages/e0/f9/0595336914c5619e5f28a1fb793285925a8cd4b432c9da0a987836c7f822/shellingham-1.5.4-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/04/be/d09147ad1ec7934636ad912901c5fd7667e1c858e19d355237db0d0cd5e4/smmap-5.0.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/46/2c/1462b1d0a634697ae9e55b3cecdcb64788e8b7d63f54d923fcd0bb140aed/soupsieve-2.8.3-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/f9/38/8b6fc7a8153cb49eb3a9a13acfa9eeb6cc476e37888781e593e6f02ac05e/spython-0.3.14-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/05/45/1256fb597bb83b58a01ddb600c59fe6fdf0e5afe333f0456ed75c0f8d7bd/sqlalchemy-2.0.46-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - pypi: https://files.pythonhosted.org/packages/f4/40/8561ce06dc46fd17242c7724ab25b257a2ac1b35f4ebf551b40ce6105cfa/stevedore-5.6.0-py3-none-any.whl @@ -219,11 +243,14 @@ environments: - pypi: https://files.pythonhosted.org/packages/a0/1d/d9257dd49ff2ca23ea5f132edf1281a0c4f9de8a762b9ae399b670a59235/typer-0.21.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/dc/9b/47798a6c91d8bdb567fe2698fe81e0c6b7cb7ef4d13da4114b41d239f65d/typing_inspection-0.4.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/c7/b0/003792df09decd6849a5e39c28b513c06e84436a54440380862b5aeff25d/tzdata-2025.3-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c4/55/85e2732345dd8b66437cddedac4ee7ef2d9c25bf8792830b095f2ee658f3/uproot-5.7.3-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/39/08/aaaad47bc4e9dc8c725e68f9d04865dbcb2052843ff09c97b08904852d84/urllib3-2.6.3-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/3c/c1/d73f12f8cdb1891334a2ccf7389eed244d3941e74d80dd220badb937f3fb/wcwidth-0.5.3-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/db/56/073989deb4b5d7d6e7ea424476a4ae4bda02140f2dbeaafb14ba4864dd60/wrapt-2.1.1-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl - pypi: https://files.pythonhosted.org/packages/1c/1c/ab905d19a1349e847e37e02933316d17adfd1dd70b64d366885ab0bd959d/xattr-1.3.0-cp314-cp314-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl - pypi: https://files.pythonhosted.org/packages/ca/6d/b1a49f9712a910acdcb8dc5765e57d60c2be9fe9b001a21b6a98a1d85adb/xenv-0.0.6-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/38/34/98a2f52245f4d47be93b580dae5f9861ef58977d73a79eb47c58f1ad1f3a/xmltodict-1.0.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ed/ba/603ce3961e339413543d8cd44f21f2c80e2a7c5cfe692a7b1f2cccf58f3c/xxhash-3.6.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - pypi: https://files.pythonhosted.org/packages/f5/e7/d8c5a7752fef68205296201f8ec2bf718f5c805a7a7e9880576c67600658/yarl-1.22.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - pypi: https://files.pythonhosted.org/packages/2e/54/647ade08bf0db230bfea292f893923872fd20be6ac6f53b2b936ba839d75/zipp-3.23.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/31/dc/cc50210e11e465c975462439a492516a73300ab8caa8f5e0902544fd748b/zstandard-0.25.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl @@ -342,7 +369,11 @@ environments: - pypi: https://files.pythonhosted.org/packages/74/f5/9373290775639cb67a2fce7f629a1c240dce9f12fe927bc32b2736e16dfc/argcomplete-3.6.3-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/ed/c9/d7977eaacb9df673210491da99e6a247e93df98c715fc43fd136ce1d3d33/arrow-1.4.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/54/51/321e821856452f7386c4e9df866f196720b1ad0c5ea1623ea7399969ae3b/authlib-1.6.6-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/77/39/4d8414260c3d83f22029a39e51553c173611b378d62ca391e5ca68e65cfa/awkward-2.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9a/02/0e550c9606ffae81603a9d240369a93cdf1e4bc48e2e314d367825a1c02d/awkward_cpp-52-cp314-cp314-macosx_10_15_x86_64.whl - pypi: https://files.pythonhosted.org/packages/fc/d8/b8fcba9464f02b121f39de2db2bf57f0b216fe11d014513d666e8634380d/azure_core-1.38.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5d/ba/2af136406e1c3839aea9ecadc2f6be2bcd1eff255bd451dd39bcf302c47a/bcrypt-5.0.0-cp39-abi3-macosx_10_12_universal2.whl + - pypi: https://files.pythonhosted.org/packages/1a/39/47f9197bdd44df24d67ac8893641e16f386c984a0619ef2ee4c51fbbc019/beautifulsoup4-4.14.3-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/5e/0a/3966f239e1d9da93cb755dc0213835ce4e9ed93645192878d0a055ecdc31/boto3-1.42.42-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/e6/51/aac7e419521d5519e13087a7198623655648c939822bd7f4bdc9ccbe07f9/botocore-1.42.42-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/ef/79/c45f2d53efe6ada1110cf6f9fca095e4ff47a0454444aefdde6ac4789179/cachecontrol-0.14.4-py3-none-any.whl @@ -351,6 +382,7 @@ environments: - pypi: https://files.pythonhosted.org/packages/2a/35/7051599bd493e62411d6ede36fd5af83a38f37c4767b92884df7301db25d/charset_normalizer-3.4.4-cp314-cp314-macosx_10_13_universal2.whl - pypi: https://files.pythonhosted.org/packages/98/78/01c019cdb5d6498122777c1a43056ebb3ebfeef2076d9d026bfe15583b2b/click-8.3.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/a7/06/3d6badcf13db419e25b07041d9c7b4a2c331d3f4e7134445ec5df57714cd/coloredlogs-15.0.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/de/07/a1051cdbbe6d723df16d756b97f09da7c1adb69e29695c58f0392bc12515/cramjam-2.11.0-cp314-cp314-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl - pypi: https://files.pythonhosted.org/packages/8d/99/157aae7949a5f30d51fcb1a9851e8ebd5c74bf99b5285d8bb4b8b9ee641e/cryptography-46.0.4-cp311-abi3-macosx_10_9_universal2.whl - pypi: https://files.pythonhosted.org/packages/db/2b/1239938a2629c29363e07724d7bd4c87a8b566947ecee2afb5f5ac34e1bb/cwl_upgrader-1.2.14-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/63/4b/ccab2a5ca9e0b6553810b85c06387e60fc9443cec3c987e3a062705bd225/cwl_utils-0.40-py3-none-any.whl @@ -358,9 +390,10 @@ environments: - pypi: https://files.pythonhosted.org/packages/65/ee/a7aba2b112c5ae879d5cfb231c75189a7fd2a5e84b6af7e07dd71fb2bb35/cwltool-3.1.20260108082145-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/5a/36/17015b7bae2783f7bbde50a8bafdeb702802c080322204f1bfcae25b9e02/DB12-1.0.4-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/4e/8c/f3147f5c4b73e7550fe5f9352eaa956ae838d5c51eb58e7a25b9f3e2643b/decorator-5.2.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/75/c0/63d2ab6ef062e05e795fb49ebcd8a907c1d4f78d9f01c577266b12bd0da2/dirac-9.0.18-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/84/d0/205d54408c08b13550c733c4b85429e7ead111c7f0014309637425520a9a/deprecated-1.3.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d0/d0/9e71fdc3394ffc632f35946c572e60fcc2a5452ba0a23c52493f23d60672/dirac-9.1.6-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/9f/90/279f55fff9481f9e0424c3c97b24dc10004ec8d8f98ddf5afd07a7b79194/diraccfg-1.0.1-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/06/d2/500c9ae651fd3821ca70814aa40cb5ab9bab9b479387ccd8dcb4df745d44/diraccommon-9.0.18-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f8/b2/ad8e7e63fdf5add3ceb7a0805d700e9fd7cb7d5743f765a4994b4ec286d7/diraccommon-9.1.6-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/ab/7e/5f02b757bb825e5cdc65f6f7a12c209963bec877d61497393bea8f41f9ce/diracx_api-0.0.8-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/b0/28/87e78ff0d6041f40431d88b8aa3b645be7476a420d8dcbf7197f5b394c5c/diracx_cli-0.0.8-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/f2/61/0c78d9778bffd844863d3173a5fefb506d7131ceebecee523a9e27024aa1/diracx_client-0.0.8-py3-none-any.whl @@ -369,7 +402,10 @@ environments: - pypi: https://files.pythonhosted.org/packages/dc/80/12235e5b75bb2c586733280854f131b86051e0bbdfb55349ff70d0f72cf9/dogpile_cache-1.5.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/58/19/0380af745f151a1648657bbcef0fb49ac28bf09083d94498163ffd9b32dc/dominate-2.9.1-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/de/15/545e2b6cf2e3be84bc1ed85613edd75b8aea69807a71c26f4ca6a9258e82/email_validator-2.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/37/f9/f8497ef8b873a8bb2a750ee2a6c5f0fc22258e1acb6245fd237042a6c279/fabric-3.2.3-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/8e/e8/a1185e236ec66c20afd72399522f142c3724c785789255202d27ae992818/frozenlist-1.8.0-cp314-cp314-macosx_10_13_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/d5/1f/5f4a3cd9e4440e9d9bc78ad0a91a1c8d46b4d429d5239ebe6793c9fe5c41/fsspec-2026.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/73/90/a2c51050d9254bd9134e6368b3f94f92f0eb2c34ed0ca19ec449ce2fc288/fsspec_xrootd-0.5.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/5f/e8/2e6301567e6debaad6abae0e217428471651ce877537b7095b6a8e7d8cd2/fts3-3.14.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/a0/61/5c78b91c3143ed5c14207f463aecfc8f9dbb5092fb2869baf37c273b2705/gitdb-4.0.12-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/b0/57/dea471da24ceac6de8c3dc5d37e4ddde57a5c340d6bac90010898734de34/gitlint_core-0.19.1-py3-none-any.whl @@ -379,17 +415,25 @@ environments: - pypi: https://files.pythonhosted.org/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/f0/0f/310fb31e39e2d734ccaa2c0fb981ee41f7bd5056ce9bc29b2248bd569169/humanfriendly-10.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/22/ed/9c45c468fd6c31df3fe0622394b1853c00b86545d1e297f3fb9fba1232ce/hyperscan-0.8.2-cp314-cp314-macosx_10_15_x86_64.whl - pypi: https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/fa/5e/f8e9a1d23b9c20a551a8a02ea3637b4642e22c2626e3a13a9a29cdea99eb/importlib_metadata-8.7.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/a4/ed/1f1afb2e9e7f38a545d628f864d562a5ae64fe6f7a10e28ffb9b185b4e89/importlib_resources-6.5.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/32/4b/b99e37f88336009971405cbb7630610322ed6fbfa31e1d7ab3fbf3049a2d/invoke-2.2.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/15/aa/0aca39a37d3c7eb941ba736ede56d689e7be91cab5d9ca846bde3999eba6/isodate-0.7.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/14/2f/967ba146e6d58cf6a652da73885f52fc68001525b4197effc174321d70b4/jmespath-1.1.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/a1/01/9674cc6d478406ae61d910cb16ca8b5699a8a9e6a2019987ebe5a5957d1d/joserfc-1.6.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/ba/24/c65fe1aef4e0681cb17ca136eb0f3e20a47d3941a306bc9d636938029ca5/lb_telemetry-0.5.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/87/a4/afc9dddc6b14fb3d52a900cd9b4c77770128edc4b07e576034bbd0ffd290/LbCondaWrappers-0.5.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/d7/4c/f3b97c7d6008b3a895bbadb2deb44ad3446ae5fe204c72cd540dc222e57d/lbenv-2.4.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/16/4a/b4d7feb029d4e75d4882d8d1d9029938c31a2e73074f87ffcff0f4a8ba9e/lbplatformutils-4.5.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/6d/10/b37ac718c5903758fa9058a5182026a4f3b65443196b82c7840389ea0dbd/lbplatformutils-4.6.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/02/64/c86924898062e8217ed914a29458cfde9e4a9b80e4d4cbcca141983ba339/lbprodrun-1.12.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f3/e1/2f705da403f865a5fa3449b155738dc9c53021698fd6926253a9af03180b/levenshtein-0.27.3-cp314-cp314-macosx_10_15_x86_64.whl + - pypi: git+ssh://git@gitlab.cern.ch:7999/jlisalab/LHCbDIRAC.git?rev=modules-to-cwl-migration#c441175f3289d6d85abf5d5612c3ff964edd9a5c + - pypi: https://files.pythonhosted.org/packages/7f/37/8ea3555769b6048b5e4ec162cc90fd32e761c0e381ffb3baf888cb0d8a71/lhcbdiracx_api-0.0.8-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/68/15/bfb0c717b8f23c16907f3e73e8f56010ccd72e9900a108209665b0d9ed4b/lhcbdiracx_cli-0.0.8-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2d/88/67602dfa2d7ab5d0518af82db34ab4d70dc2c3029b3ca788299a3be4a96d/lhcbdiracx_client-0.0.8-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/34/8f/6105afdd8f4e1f3b198d09e4b2622622923d9fa9e077aed852c0bb035a3a/lhcbdiracx_core-0.0.8-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/b3/68/aa714515d65090fcbcc9a1f3debd5a644b14aad11e59238f42f00bd4b298/logzero-1.7.0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/c8/e8/c128e37589463668794d503afaeb003987373c5f94d667124ffd8078bbd9/lxml-6.0.2-cp314-cp314-macosx_10_13_x86_64.whl - pypi: https://files.pythonhosted.org/packages/94/54/e7d793b573f298e1c9013b8c4dade17d481164aa517d1d7148619c2cedbf/markdown_it_py-4.0.0-py3-none-any.whl @@ -398,6 +442,8 @@ environments: - pypi: https://files.pythonhosted.org/packages/22/71/201105712d0a2ff07b7873ed3c220292fb2ea5120603c00c4b634bcdafb3/msgpack-1.1.2-cp314-cp314-macosx_10_13_x86_64.whl - pypi: https://files.pythonhosted.org/packages/d5/22/492f2246bb5b534abd44804292e81eeaf835388901f0c574bac4eeec73c5/multidict-6.7.1-cp314-cp314-macosx_10_15_x86_64.whl - pypi: https://files.pythonhosted.org/packages/9e/c9/b2622292ea83fbb4ec318f5b9ab867d0a28ab43c5717bb85b0a5f6b3b0a4/networkx-3.6.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/bb/40/c6ea527147c73b24fc15c891c3fcffe9c019793119c5742b8784a062c7db/pandas-3.0.2-cp314-cp314-macosx_10_15_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/a9/90/a744336f5af32c433bd09af7854599682a383b37cfd78f7de263de6ad6cb/paramiko-4.0.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/9e/c3/059298687310d527a58bb01f3b1965787ee3b40dce76752eda8b44e9a2c5/pexpect-4.9.0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/84/03/0d3ce49e2505ae70cf43bc5bb3033955d2fc9f932163e84dc0779cc47f48/prompt_toolkit-3.0.52-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/65/9b/03b04e7d82a5f54fb16113d839f5ea1ede58a61e90edf515f6577c66fa8f/propcache-0.4.1-cp314-cp314-macosx_10_13_x86_64.whl @@ -410,12 +456,16 @@ environments: - pypi: https://files.pythonhosted.org/packages/c1/60/5d4751ba3f4a40a6891f24eec885f51afd78d208498268c734e256fb13c4/pydantic_settings-2.12.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/7e/32/a7125fb28c4261a627f999d5fb4afff25b523800faed2c30979949d6facd/pydot-4.0.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/6f/01/c26ce75ba460d5cd503da9e13b21a33804d38c2165dec7b716d06b13010c/pyjwt-2.11.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/be/7b/4845bbf88e94586ec47a432da4e9107e3fc3ce37eb412b1398630a37f7dd/pynacl-1.6.2-cp38-abi3-macosx_10_10_universal2.whl - pypi: https://files.pythonhosted.org/packages/10/bd/c038d7cc38edc1aa5bf91ab8068b63d4308c66c4c8bb3cbba7dfbc049f9c/pyparsing-3.3.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/14/1b/a298b06749107c305e1fe0f814c6c74aea7b2f1e10989cb30f544a1b3253/python_dotenv-1.2.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/38/ee/a61bb562bdf6f0bc6c51cdcf80ab5503cbb4b2f5053fa4b054cc0a56e48a/python_gitlab-8.2.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/81/c4/34e93fe5f5429d7570ec1fa436f1986fb1f00c3e0f43a589fe2bbcd22c3f/pytz-2025.2-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/81/41/aa3ffb3355e62e1bf91f6599b3092e866bc88487a07c524004943c7676df/rapidfuzz-3.14.5-cp314-cp314-macosx_10_15_x86_64.whl - pypi: https://files.pythonhosted.org/packages/b9/20/35d2baebacf357b562bd081936b66cd845775442973cb033a377fd639a84/rdflib-7.5.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/1e/db/4254e3eabe8020b458f1a747140d32277ec7a271daf1d235b70dc0b4e6e3/requests-2.32.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3f/51/d4db610ef29373b879047326cbf6fa98b6c1969d6f6dc423279de2b1be2c/requests_toolbelt-1.0.0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/ef/45/615f5babd880b4bd7d405cc0dc348234c5ffb6ed1ea33e152ede08b2072d/rich-14.3.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/04/80/97b6f357ac458d9ad9872cc3183ca09ef7439ac89e030ea43053ba1294b6/rich_argparse-1.7.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/af/fe/b6045c782f1fd1ae317d2a6ca1884857ce5c20f59befe6ab25a8603c43a7/ruamel_yaml-0.18.17-py3-none-any.whl @@ -427,6 +477,7 @@ environments: - pypi: https://files.pythonhosted.org/packages/e0/f9/0595336914c5619e5f28a1fb793285925a8cd4b432c9da0a987836c7f822/shellingham-1.5.4-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/04/be/d09147ad1ec7934636ad912901c5fd7667e1c858e19d355237db0d0cd5e4/smmap-5.0.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/46/2c/1462b1d0a634697ae9e55b3cecdcb64788e8b7d63f54d923fcd0bb140aed/soupsieve-2.8.3-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/f9/38/8b6fc7a8153cb49eb3a9a13acfa9eeb6cc476e37888781e593e6f02ac05e/spython-0.3.14-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/fc/a1/9c4efa03300926601c19c18582531b45aededfb961ab3c3585f1e24f120b/sqlalchemy-2.0.46-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/f4/40/8561ce06dc46fd17242c7724ab25b257a2ac1b35f4ebf551b40ce6105cfa/stevedore-5.6.0-py3-none-any.whl @@ -434,11 +485,14 @@ environments: - pypi: https://files.pythonhosted.org/packages/a0/1d/d9257dd49ff2ca23ea5f132edf1281a0c4f9de8a762b9ae399b670a59235/typer-0.21.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/dc/9b/47798a6c91d8bdb567fe2698fe81e0c6b7cb7ef4d13da4114b41d239f65d/typing_inspection-0.4.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/c7/b0/003792df09decd6849a5e39c28b513c06e84436a54440380862b5aeff25d/tzdata-2025.3-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c4/55/85e2732345dd8b66437cddedac4ee7ef2d9c25bf8792830b095f2ee658f3/uproot-5.7.3-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/39/08/aaaad47bc4e9dc8c725e68f9d04865dbcb2052843ff09c97b08904852d84/urllib3-2.6.3-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/3c/c1/d73f12f8cdb1891334a2ccf7389eed244d3941e74d80dd220badb937f3fb/wcwidth-0.5.3-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/95/a0/1c2396e272f91efe6b16a6a8bce7ad53856c8f9ae4f34ceaa711d63ec9e1/wrapt-2.1.1-cp314-cp314-macosx_10_15_x86_64.whl - pypi: https://files.pythonhosted.org/packages/9d/0a/03192e78071cfb86e6d8ceae0e5dcec4bacf0fd734755263aabd01532e50/xattr-1.3.0-cp314-cp314-macosx_10_15_x86_64.whl - pypi: https://files.pythonhosted.org/packages/ca/6d/b1a49f9712a910acdcb8dc5765e57d60c2be9fe9b001a21b6a98a1d85adb/xenv-0.0.6-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/38/34/98a2f52245f4d47be93b580dae5f9861ef58977d73a79eb47c58f1ad1f3a/xmltodict-1.0.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/7e/5e/0138bc4484ea9b897864d59fce9be9086030825bc778b76cb5a33a906d37/xxhash-3.6.0-cp314-cp314-macosx_10_13_x86_64.whl - pypi: https://files.pythonhosted.org/packages/e4/04/3532d990fdbab02e5ede063676b5c4260e7f3abea2151099c2aa745acc4c/yarl-1.22.0-cp314-cp314-macosx_10_13_x86_64.whl - pypi: https://files.pythonhosted.org/packages/2e/54/647ade08bf0db230bfea292f893923872fd20be6ac6f53b2b936ba839d75/zipp-3.23.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/3d/5c/f8923b595b55fe49e30612987ad8bf053aef555c14f05bb659dd5dbe3e8a/zstandard-0.25.0-cp314-cp314-macosx_10_13_x86_64.whl @@ -557,7 +611,11 @@ environments: - pypi: https://files.pythonhosted.org/packages/74/f5/9373290775639cb67a2fce7f629a1c240dce9f12fe927bc32b2736e16dfc/argcomplete-3.6.3-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/ed/c9/d7977eaacb9df673210491da99e6a247e93df98c715fc43fd136ce1d3d33/arrow-1.4.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/54/51/321e821856452f7386c4e9df866f196720b1ad0c5ea1623ea7399969ae3b/authlib-1.6.6-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/77/39/4d8414260c3d83f22029a39e51553c173611b378d62ca391e5ca68e65cfa/awkward-2.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fb/b9/0978fa6f21f504b617ccee4843210d7ab8921a10e94e3bbf084498dcfad7/awkward_cpp-52-cp314-cp314-macosx_11_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/fc/d8/b8fcba9464f02b121f39de2db2bf57f0b216fe11d014513d666e8634380d/azure_core-1.38.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5d/ba/2af136406e1c3839aea9ecadc2f6be2bcd1eff255bd451dd39bcf302c47a/bcrypt-5.0.0-cp39-abi3-macosx_10_12_universal2.whl + - pypi: https://files.pythonhosted.org/packages/1a/39/47f9197bdd44df24d67ac8893641e16f386c984a0619ef2ee4c51fbbc019/beautifulsoup4-4.14.3-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/5e/0a/3966f239e1d9da93cb755dc0213835ce4e9ed93645192878d0a055ecdc31/boto3-1.42.42-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/e6/51/aac7e419521d5519e13087a7198623655648c939822bd7f4bdc9ccbe07f9/botocore-1.42.42-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/ef/79/c45f2d53efe6ada1110cf6f9fca095e4ff47a0454444aefdde6ac4789179/cachecontrol-0.14.4-py3-none-any.whl @@ -566,6 +624,7 @@ environments: - pypi: https://files.pythonhosted.org/packages/2a/35/7051599bd493e62411d6ede36fd5af83a38f37c4767b92884df7301db25d/charset_normalizer-3.4.4-cp314-cp314-macosx_10_13_universal2.whl - pypi: https://files.pythonhosted.org/packages/98/78/01c019cdb5d6498122777c1a43056ebb3ebfeef2076d9d026bfe15583b2b/click-8.3.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/a7/06/3d6badcf13db419e25b07041d9c7b4a2c331d3f4e7134445ec5df57714cd/coloredlogs-15.0.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/de/07/a1051cdbbe6d723df16d756b97f09da7c1adb69e29695c58f0392bc12515/cramjam-2.11.0-cp314-cp314-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl - pypi: https://files.pythonhosted.org/packages/8d/99/157aae7949a5f30d51fcb1a9851e8ebd5c74bf99b5285d8bb4b8b9ee641e/cryptography-46.0.4-cp311-abi3-macosx_10_9_universal2.whl - pypi: https://files.pythonhosted.org/packages/db/2b/1239938a2629c29363e07724d7bd4c87a8b566947ecee2afb5f5ac34e1bb/cwl_upgrader-1.2.14-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/63/4b/ccab2a5ca9e0b6553810b85c06387e60fc9443cec3c987e3a062705bd225/cwl_utils-0.40-py3-none-any.whl @@ -573,9 +632,10 @@ environments: - pypi: https://files.pythonhosted.org/packages/65/ee/a7aba2b112c5ae879d5cfb231c75189a7fd2a5e84b6af7e07dd71fb2bb35/cwltool-3.1.20260108082145-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/5a/36/17015b7bae2783f7bbde50a8bafdeb702802c080322204f1bfcae25b9e02/DB12-1.0.4-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/4e/8c/f3147f5c4b73e7550fe5f9352eaa956ae838d5c51eb58e7a25b9f3e2643b/decorator-5.2.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/75/c0/63d2ab6ef062e05e795fb49ebcd8a907c1d4f78d9f01c577266b12bd0da2/dirac-9.0.18-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/84/d0/205d54408c08b13550c733c4b85429e7ead111c7f0014309637425520a9a/deprecated-1.3.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d0/d0/9e71fdc3394ffc632f35946c572e60fcc2a5452ba0a23c52493f23d60672/dirac-9.1.6-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/9f/90/279f55fff9481f9e0424c3c97b24dc10004ec8d8f98ddf5afd07a7b79194/diraccfg-1.0.1-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/06/d2/500c9ae651fd3821ca70814aa40cb5ab9bab9b479387ccd8dcb4df745d44/diraccommon-9.0.18-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f8/b2/ad8e7e63fdf5add3ceb7a0805d700e9fd7cb7d5743f765a4994b4ec286d7/diraccommon-9.1.6-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/ab/7e/5f02b757bb825e5cdc65f6f7a12c209963bec877d61497393bea8f41f9ce/diracx_api-0.0.8-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/b0/28/87e78ff0d6041f40431d88b8aa3b645be7476a420d8dcbf7197f5b394c5c/diracx_cli-0.0.8-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/f2/61/0c78d9778bffd844863d3173a5fefb506d7131ceebecee523a9e27024aa1/diracx_client-0.0.8-py3-none-any.whl @@ -584,7 +644,10 @@ environments: - pypi: https://files.pythonhosted.org/packages/dc/80/12235e5b75bb2c586733280854f131b86051e0bbdfb55349ff70d0f72cf9/dogpile_cache-1.5.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/58/19/0380af745f151a1648657bbcef0fb49ac28bf09083d94498163ffd9b32dc/dominate-2.9.1-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/de/15/545e2b6cf2e3be84bc1ed85613edd75b8aea69807a71c26f4ca6a9258e82/email_validator-2.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/37/f9/f8497ef8b873a8bb2a750ee2a6c5f0fc22258e1acb6245fd237042a6c279/fabric-3.2.3-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/a1/93/72b1736d68f03fda5fdf0f2180fb6caaae3894f1b854d006ac61ecc727ee/frozenlist-1.8.0-cp314-cp314-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/d5/1f/5f4a3cd9e4440e9d9bc78ad0a91a1c8d46b4d429d5239ebe6793c9fe5c41/fsspec-2026.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/73/90/a2c51050d9254bd9134e6368b3f94f92f0eb2c34ed0ca19ec449ce2fc288/fsspec_xrootd-0.5.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/5f/e8/2e6301567e6debaad6abae0e217428471651ce877537b7095b6a8e7d8cd2/fts3-3.14.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/a0/61/5c78b91c3143ed5c14207f463aecfc8f9dbb5092fb2869baf37c273b2705/gitdb-4.0.12-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/b0/57/dea471da24ceac6de8c3dc5d37e4ddde57a5c340d6bac90010898734de34/gitlint_core-0.19.1-py3-none-any.whl @@ -593,17 +656,25 @@ environments: - pypi: https://files.pythonhosted.org/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/f0/0f/310fb31e39e2d734ccaa2c0fb981ee41f7bd5056ce9bc29b2248bd569169/humanfriendly-10.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d8/da/a8bb48a4fee86b5dad8a358559b70b010cd7effaa70ca5bb4e6e82e13703/hyperscan-0.8.2-cp314-cp314-macosx_11_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/fa/5e/f8e9a1d23b9c20a551a8a02ea3637b4642e22c2626e3a13a9a29cdea99eb/importlib_metadata-8.7.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/a4/ed/1f1afb2e9e7f38a545d628f864d562a5ae64fe6f7a10e28ffb9b185b4e89/importlib_resources-6.5.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/32/4b/b99e37f88336009971405cbb7630610322ed6fbfa31e1d7ab3fbf3049a2d/invoke-2.2.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/15/aa/0aca39a37d3c7eb941ba736ede56d689e7be91cab5d9ca846bde3999eba6/isodate-0.7.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/14/2f/967ba146e6d58cf6a652da73885f52fc68001525b4197effc174321d70b4/jmespath-1.1.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/a1/01/9674cc6d478406ae61d910cb16ca8b5699a8a9e6a2019987ebe5a5957d1d/joserfc-1.6.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/ba/24/c65fe1aef4e0681cb17ca136eb0f3e20a47d3941a306bc9d636938029ca5/lb_telemetry-0.5.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/87/a4/afc9dddc6b14fb3d52a900cd9b4c77770128edc4b07e576034bbd0ffd290/LbCondaWrappers-0.5.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/d7/4c/f3b97c7d6008b3a895bbadb2deb44ad3446ae5fe204c72cd540dc222e57d/lbenv-2.4.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/16/4a/b4d7feb029d4e75d4882d8d1d9029938c31a2e73074f87ffcff0f4a8ba9e/lbplatformutils-4.5.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/6d/10/b37ac718c5903758fa9058a5182026a4f3b65443196b82c7840389ea0dbd/lbplatformutils-4.6.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/02/64/c86924898062e8217ed914a29458cfde9e4a9b80e4d4cbcca141983ba339/lbprodrun-1.12.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/76/2c/bb6ef359e007fe7b6b3195b68a94f4dd3ecd1885ee337ee8fbd4df55996f/levenshtein-0.27.3-cp314-cp314-macosx_11_0_arm64.whl + - pypi: git+ssh://git@gitlab.cern.ch:7999/jlisalab/LHCbDIRAC.git?rev=modules-to-cwl-migration#c441175f3289d6d85abf5d5612c3ff964edd9a5c + - pypi: https://files.pythonhosted.org/packages/7f/37/8ea3555769b6048b5e4ec162cc90fd32e761c0e381ffb3baf888cb0d8a71/lhcbdiracx_api-0.0.8-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/68/15/bfb0c717b8f23c16907f3e73e8f56010ccd72e9900a108209665b0d9ed4b/lhcbdiracx_cli-0.0.8-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2d/88/67602dfa2d7ab5d0518af82db34ab4d70dc2c3029b3ca788299a3be4a96d/lhcbdiracx_client-0.0.8-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/34/8f/6105afdd8f4e1f3b198d09e4b2622622923d9fa9e077aed852c0bb035a3a/lhcbdiracx_core-0.0.8-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/b3/68/aa714515d65090fcbcc9a1f3debd5a644b14aad11e59238f42f00bd4b298/logzero-1.7.0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/03/15/d4a377b385ab693ce97b472fe0c77c2b16ec79590e688b3ccc71fba19884/lxml-6.0.2-cp314-cp314-macosx_10_13_universal2.whl - pypi: https://files.pythonhosted.org/packages/94/54/e7d793b573f298e1c9013b8c4dade17d481164aa517d1d7148619c2cedbf/markdown_it_py-4.0.0-py3-none-any.whl @@ -612,6 +683,8 @@ environments: - pypi: https://files.pythonhosted.org/packages/1b/9f/38ff9e57a2eade7bf9dfee5eae17f39fc0e998658050279cbb14d97d36d9/msgpack-1.1.2-cp314-cp314-macosx_11_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/f1/4f/733c48f270565d78b4544f2baddc2fb2a245e5a8640254b12c36ac7ac68e/multidict-6.7.1-cp314-cp314-macosx_11_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/9e/c9/b2622292ea83fbb4ec318f5b9ab867d0a28ab43c5717bb85b0a5f6b3b0a4/networkx-3.6.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/95/25/bdb9326c3b5455f8d4d3549fce7abcf967259de146fe2cf7a82368141948/pandas-3.0.2-cp314-cp314-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/a9/90/a744336f5af32c433bd09af7854599682a383b37cfd78f7de263de6ad6cb/paramiko-4.0.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/9e/c3/059298687310d527a58bb01f3b1965787ee3b40dce76752eda8b44e9a2c5/pexpect-4.9.0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/84/03/0d3ce49e2505ae70cf43bc5bb3033955d2fc9f932163e84dc0779cc47f48/prompt_toolkit-3.0.52-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/b2/fa/89a8ef0468d5833a23fff277b143d0573897cf75bd56670a6d28126c7d68/propcache-0.4.1-cp314-cp314-macosx_11_0_arm64.whl @@ -624,12 +697,16 @@ environments: - pypi: https://files.pythonhosted.org/packages/c1/60/5d4751ba3f4a40a6891f24eec885f51afd78d208498268c734e256fb13c4/pydantic_settings-2.12.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/7e/32/a7125fb28c4261a627f999d5fb4afff25b523800faed2c30979949d6facd/pydot-4.0.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/6f/01/c26ce75ba460d5cd503da9e13b21a33804d38c2165dec7b716d06b13010c/pyjwt-2.11.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/be/7b/4845bbf88e94586ec47a432da4e9107e3fc3ce37eb412b1398630a37f7dd/pynacl-1.6.2-cp38-abi3-macosx_10_10_universal2.whl - pypi: https://files.pythonhosted.org/packages/10/bd/c038d7cc38edc1aa5bf91ab8068b63d4308c66c4c8bb3cbba7dfbc049f9c/pyparsing-3.3.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/14/1b/a298b06749107c305e1fe0f814c6c74aea7b2f1e10989cb30f544a1b3253/python_dotenv-1.2.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/38/ee/a61bb562bdf6f0bc6c51cdcf80ab5503cbb4b2f5053fa4b054cc0a56e48a/python_gitlab-8.2.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/81/c4/34e93fe5f5429d7570ec1fa436f1986fb1f00c3e0f43a589fe2bbcd22c3f/pytz-2025.2-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2d/e1/c2141f1840a41e07ad2db6f724945f8f8ff3065463899a22939152dd6e09/rapidfuzz-3.14.5-cp314-cp314-macosx_11_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/b9/20/35d2baebacf357b562bd081936b66cd845775442973cb033a377fd639a84/rdflib-7.5.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/1e/db/4254e3eabe8020b458f1a747140d32277ec7a271daf1d235b70dc0b4e6e3/requests-2.32.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3f/51/d4db610ef29373b879047326cbf6fa98b6c1969d6f6dc423279de2b1be2c/requests_toolbelt-1.0.0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/ef/45/615f5babd880b4bd7d405cc0dc348234c5ffb6ed1ea33e152ede08b2072d/rich-14.3.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/04/80/97b6f357ac458d9ad9872cc3183ca09ef7439ac89e030ea43053ba1294b6/rich_argparse-1.7.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/af/fe/b6045c782f1fd1ae317d2a6ca1884857ce5c20f59befe6ab25a8603c43a7/ruamel_yaml-0.18.17-py3-none-any.whl @@ -641,6 +718,7 @@ environments: - pypi: https://files.pythonhosted.org/packages/e0/f9/0595336914c5619e5f28a1fb793285925a8cd4b432c9da0a987836c7f822/shellingham-1.5.4-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/04/be/d09147ad1ec7934636ad912901c5fd7667e1c858e19d355237db0d0cd5e4/smmap-5.0.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/46/2c/1462b1d0a634697ae9e55b3cecdcb64788e8b7d63f54d923fcd0bb140aed/soupsieve-2.8.3-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/f9/38/8b6fc7a8153cb49eb3a9a13acfa9eeb6cc476e37888781e593e6f02ac05e/spython-0.3.14-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/e9/f8/5ecdfc73383ec496de038ed1614de9e740a82db9ad67e6e4514ebc0708a3/sqlalchemy-2.0.46-cp314-cp314-macosx_11_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/f4/40/8561ce06dc46fd17242c7724ab25b257a2ac1b35f4ebf551b40ce6105cfa/stevedore-5.6.0-py3-none-any.whl @@ -648,11 +726,14 @@ environments: - pypi: https://files.pythonhosted.org/packages/a0/1d/d9257dd49ff2ca23ea5f132edf1281a0c4f9de8a762b9ae399b670a59235/typer-0.21.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/dc/9b/47798a6c91d8bdb567fe2698fe81e0c6b7cb7ef4d13da4114b41d239f65d/typing_inspection-0.4.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/c7/b0/003792df09decd6849a5e39c28b513c06e84436a54440380862b5aeff25d/tzdata-2025.3-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c4/55/85e2732345dd8b66437cddedac4ee7ef2d9c25bf8792830b095f2ee658f3/uproot-5.7.3-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/39/08/aaaad47bc4e9dc8c725e68f9d04865dbcb2052843ff09c97b08904852d84/urllib3-2.6.3-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/3c/c1/d73f12f8cdb1891334a2ccf7389eed244d3941e74d80dd220badb937f3fb/wcwidth-0.5.3-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/b0/9a/d2faba7e61072a7507b5722db63562fdb22f5a24e237d460d18755627f15/wrapt-2.1.1-cp314-cp314-macosx_11_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/3d/36/9ab4f0b5c3d10df3aceaecf7e395cabe7fb7c7c004b2dc3f3cff0ef70fc3/xattr-1.3.0-cp314-cp314-macosx_11_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/ca/6d/b1a49f9712a910acdcb8dc5765e57d60c2be9fe9b001a21b6a98a1d85adb/xenv-0.0.6-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/38/34/98a2f52245f4d47be93b580dae5f9861ef58977d73a79eb47c58f1ad1f3a/xmltodict-1.0.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/18/d7/5dac2eb2ec75fd771957a13e5dda560efb2176d5203f39502a5fc571f899/xxhash-3.6.0-cp314-cp314-macosx_11_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/11/63/ff458113c5c2dac9a9719ac68ee7c947cb621432bcf28c9972b1c0e83938/yarl-1.22.0-cp314-cp314-macosx_11_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/2e/54/647ade08bf0db230bfea292f893923872fd20be6ac6f53b2b936ba839d75/zipp-3.23.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/8d/09/d0a2a14fc3439c5f874042dca72a79c70a532090b7ba0003be73fee37ae2/zstandard-0.25.0-cp314-cp314-macosx_11_0_arm64.whl @@ -859,6 +940,39 @@ packages: requires_dist: - cryptography requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/77/39/4d8414260c3d83f22029a39e51553c173611b378d62ca391e5ca68e65cfa/awkward-2.9.0-py3-none-any.whl + name: awkward + version: 2.9.0 + sha256: 4859e371c606ca7fe737546f302de08110d53ed986cdd1254fb059dd48912db6 + requires_dist: + - awkward-cpp==52 + - fsspec>=2022.11.0 + - importlib-metadata>=4.13.0 ; python_full_version < '3.12' + - numpy>=1.21.3 + - packaging + - typing-extensions>=4.1.0 ; python_full_version < '3.11' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/9a/02/0e550c9606ffae81603a9d240369a93cdf1e4bc48e2e314d367825a1c02d/awkward_cpp-52-cp314-cp314-macosx_10_15_x86_64.whl + name: awkward-cpp + version: '52' + sha256: d792c969c5261d8141c0b817a6a541849355b0fafe49e6e63a542a501cc0b73a + requires_dist: + - numpy>=1.21.3 + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/ca/aa/ab2d6d68c3ee50f6dedbbc91a31cd38f9fede9258d54e7aca29bfca4ebc1/awkward_cpp-52-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl + name: awkward-cpp + version: '52' + sha256: bbfd5745b59684a044c91394d7c1c5a82bac204ed9ef6125f37ffe35aa719e2b + requires_dist: + - numpy>=1.21.3 + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/fb/b9/0978fa6f21f504b617ccee4843210d7ab8921a10e94e3bbf084498dcfad7/awkward_cpp-52-cp314-cp314-macosx_11_0_arm64.whl + name: awkward-cpp + version: '52' + sha256: 626e75125267c7ce51fdb891fa628e7cf3ea9c37df19126e25dd9587917f94ab + requires_dist: + - numpy>=1.21.3 + requires_python: '>=3.10' - pypi: https://files.pythonhosted.org/packages/fc/d8/b8fcba9464f02b121f39de2db2bf57f0b216fe11d014513d666e8634380d/azure_core-1.38.0-py3-none-any.whl name: azure-core version: 1.38.0 @@ -882,6 +996,35 @@ packages: purls: [] size: 10186 timestamp: 1753456386827 +- pypi: https://files.pythonhosted.org/packages/24/b4/11f8a31d8b67cca3371e046db49baa7c0594d71eb40ac8121e2fc0888db0/bcrypt-5.0.0-cp39-abi3-manylinux_2_28_x86_64.whl + name: bcrypt + version: 5.0.0 + sha256: f8429e1c410b4073944f03bd778a9e066e7fad723564a52ff91841d278dfc822 + requires_dist: + - pytest>=3.2.1,!=3.3.0 ; extra == 'tests' + - mypy ; extra == 'typecheck' + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/5d/ba/2af136406e1c3839aea9ecadc2f6be2bcd1eff255bd451dd39bcf302c47a/bcrypt-5.0.0-cp39-abi3-macosx_10_12_universal2.whl + name: bcrypt + version: 5.0.0 + sha256: 0c418ca99fd47e9c59a301744d63328f17798b5947b0f791e9af3c1c499c2d0a + requires_dist: + - pytest>=3.2.1,!=3.3.0 ; extra == 'tests' + - mypy ; extra == 'typecheck' + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/1a/39/47f9197bdd44df24d67ac8893641e16f386c984a0619ef2ee4c51fbbc019/beautifulsoup4-4.14.3-py3-none-any.whl + name: beautifulsoup4 + version: 4.14.3 + sha256: 0918bfe44902e6ad8d57732ba310582e98da931428d231a5ecb9e7c703a735bb + requires_dist: + - soupsieve>=1.6.1 + - typing-extensions>=4.0.0 + - cchardet ; extra == 'cchardet' + - chardet ; extra == 'chardet' + - charset-normalizer ; extra == 'charset-normalizer' + - html5lib ; extra == 'html5lib' + - lxml ; extra == 'lxml' + requires_python: '>=3.7.0' - pypi: https://files.pythonhosted.org/packages/5e/0a/3966f239e1d9da93cb755dc0213835ce4e9ed93645192878d0a055ecdc31/boto3-1.42.42-py3-none-any.whl name: boto3 version: 1.42.42 @@ -1117,6 +1260,30 @@ packages: - humanfriendly>=9.1 - capturer>=2.4 ; extra == 'cron' requires_python: '>=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*' +- pypi: https://files.pythonhosted.org/packages/19/0f/f6121b90b86b9093c066889274d26a1de3f29969d45c2ed1ecbe2033cb78/cramjam-2.11.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl + name: cramjam + version: 2.11.0 + sha256: 17eb39b1696179fb471eea2de958fa21f40a2cd8bf6b40d428312d5541e19dc4 + requires_dist: + - black==22.3.0 ; extra == 'dev' + - numpy ; extra == 'dev' + - pytest>=5.30 ; extra == 'dev' + - pytest-xdist ; extra == 'dev' + - pytest-benchmark ; extra == 'dev' + - hypothesis==6.60.0 ; extra == 'dev' + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/de/07/a1051cdbbe6d723df16d756b97f09da7c1adb69e29695c58f0392bc12515/cramjam-2.11.0-cp314-cp314-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl + name: cramjam + version: 2.11.0 + sha256: 7ba5e38c9fbd06f086f4a5a64a1a5b7b417cd3f8fc07a20e5c03651f72f36100 + requires_dist: + - black==22.3.0 ; extra == 'dev' + - numpy ; extra == 'dev' + - pytest>=5.30 ; extra == 'dev' + - pytest-xdist ; extra == 'dev' + - pytest-benchmark ; extra == 'dev' + - hypothesis==6.60.0 ; extra == 'dev' + requires_python: '>=3.8' - pypi: https://files.pythonhosted.org/packages/2b/08/f83e2e0814248b844265802d081f2fac2f1cbe6cd258e72ba14ff006823a/cryptography-46.0.4-cp311-abi3-manylinux_2_28_x86_64.whl name: cryptography version: 46.0.4 @@ -1389,10 +1556,23 @@ packages: version: 5.2.1 sha256: d316bb415a2d9e2d2b3abcc4084c6502fc09240e292cd76a76afc106a1c8e04a requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/75/c0/63d2ab6ef062e05e795fb49ebcd8a907c1d4f78d9f01c577266b12bd0da2/dirac-9.0.18-py3-none-any.whl +- pypi: https://files.pythonhosted.org/packages/84/d0/205d54408c08b13550c733c4b85429e7ead111c7f0014309637425520a9a/deprecated-1.3.1-py2.py3-none-any.whl + name: deprecated + version: 1.3.1 + sha256: 597bfef186b6f60181535a29fbe44865ce137a5079f295b479886c82729d5f3f + requires_dist: + - wrapt>=1.10,<3 + - inspect2 ; python_full_version < '3' + - tox ; extra == 'dev' + - pytest ; extra == 'dev' + - pytest-cov ; extra == 'dev' + - bump2version<1 ; extra == 'dev' + - setuptools ; python_full_version >= '3.12' and extra == 'dev' + requires_python: '>=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*' +- pypi: https://files.pythonhosted.org/packages/d0/d0/9e71fdc3394ffc632f35946c572e60fcc2a5452ba0a23c52493f23d60672/dirac-9.1.6-py3-none-any.whl name: dirac - version: 9.0.18 - sha256: 8e32e7486eb49ad88278b2cb3d56a4ec684715de639f6c09c8a4e05b837e268a + version: 9.1.6 + sha256: d818427204216f239df4171ddaa3cc646d7e208a34577bb8c86f2d9d50f6ffb3 requires_dist: - boto3>=1.35 - botocore>=1.35 @@ -1400,17 +1580,20 @@ packages: - certifi - cwltool - diraccfg - - diraccommon==9.0.18 + - diraccommon==9.1.6 - diracx-client>=0.0.1 - diracx-core>=0.0.1 - diracx-cli>=0.0.1 - db12 + - fabric - fts3 - gfal2-python - importlib-metadata>=4.4 - importlib-resources + - invoke - m2crypto>=0.36 - packaging + - paramiko - pexpect - prompt-toolkit>=3 - psutil @@ -1456,8 +1639,8 @@ packages: requires_python: '>=3.11' - pypi: ./ name: dirac-cwl - version: 1.2.1.dev14+g6f8f6ff96.d20260303 - sha256: 0b624b7b1adb33bc3b4cb29dbf85bb2db495122acda95aaa775f0aedef77767f + version: 1.2.1.dev8+g8317c9f76.d20260427 + sha256: 827f00c9f462c00995c99046a12618a97b94bd8085f0ea7fadb6faeaabb7c002 requires_dist: - cwl-utils - cwlformat @@ -1468,6 +1651,7 @@ packages: - diracx-client>=0.0.8 - diracx-cli>=0.0.8 - lbprodrun + - lhcbdirac @ git+ssh://git@gitlab.cern.ch:7999/jlisalab/LHCbDIRAC.git@modules-to-cwl-migration - pydantic - pyyaml - typer @@ -1488,10 +1672,10 @@ packages: - pytest-cov ; extra == 'testing' - pylint>=1.6.5 ; extra == 'testing' requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/06/d2/500c9ae651fd3821ca70814aa40cb5ab9bab9b479387ccd8dcb4df745d44/diraccommon-9.0.18-py3-none-any.whl +- pypi: https://files.pythonhosted.org/packages/f8/b2/ad8e7e63fdf5add3ceb7a0805d700e9fd7cb7d5743f765a4994b4ec286d7/diraccommon-9.1.6-py3-none-any.whl name: diraccommon - version: 9.0.18 - sha256: e32f417cb4805c8c73b940921f6f4d06d2926ac834c02e3a99d5db2ac5c2fe14 + version: 9.1.6 + sha256: 53c765edf120eff9764d49e57d4073c0f2d671ed391f52a2ca940abef0810963 requires_dist: - diraccfg - pydantic>=2.0.0 @@ -1653,6 +1837,16 @@ packages: purls: [] size: 143991 timestamp: 1763549744569 +- pypi: https://files.pythonhosted.org/packages/37/f9/f8497ef8b873a8bb2a750ee2a6c5f0fc22258e1acb6245fd237042a6c279/fabric-3.2.3-py3-none-any.whl + name: fabric + version: 3.2.3 + sha256: ce61917f4f398018337ce279b357650a3a74baecf3fdd53a5839013944af965e + requires_dist: + - invoke>=2.0,<3.0 + - paramiko>=2.4 + - decorator>=5 + - deprecated>=1.2 + - pytest>=7 ; extra == 'pytest' - conda: https://conda.anaconda.org/conda-forge/noarch/filelock-3.20.3-pyhd8ed1ab_0.conda sha256: 8b90dc21f00167a7e58abb5141a140bdb31a7c5734fe1361b5f98f4a4183fd32 md5: 2cfaaccf085c133a477f0a7a8657afe9 @@ -1678,6 +1872,129 @@ packages: version: 1.8.0 sha256: cba69cb73723c3f329622e34bdbf5ce1f80c21c290ff04256cff1cd3c2036ed2 requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/d5/1f/5f4a3cd9e4440e9d9bc78ad0a91a1c8d46b4d429d5239ebe6793c9fe5c41/fsspec-2026.3.0-py3-none-any.whl + name: fsspec + version: 2026.3.0 + sha256: d2ceafaad1b3457968ed14efa28798162f1638dbb5d2a6868a2db002a5ee39a4 + requires_dist: + - adlfs ; extra == 'abfs' + - adlfs ; extra == 'adl' + - pyarrow>=1 ; extra == 'arrow' + - dask ; extra == 'dask' + - distributed ; extra == 'dask' + - pre-commit ; extra == 'dev' + - ruff>=0.5 ; extra == 'dev' + - numpydoc ; extra == 'doc' + - sphinx ; extra == 'doc' + - sphinx-design ; extra == 'doc' + - sphinx-rtd-theme ; extra == 'doc' + - yarl ; extra == 'doc' + - dropbox ; extra == 'dropbox' + - dropboxdrivefs ; extra == 'dropbox' + - requests ; extra == 'dropbox' + - adlfs ; extra == 'full' + - aiohttp!=4.0.0a0,!=4.0.0a1 ; extra == 'full' + - dask ; extra == 'full' + - distributed ; extra == 'full' + - dropbox ; extra == 'full' + - dropboxdrivefs ; extra == 'full' + - fusepy ; extra == 'full' + - gcsfs>2024.2.0 ; extra == 'full' + - libarchive-c ; extra == 'full' + - ocifs ; extra == 'full' + - panel ; extra == 'full' + - paramiko ; extra == 'full' + - pyarrow>=1 ; extra == 'full' + - pygit2 ; extra == 'full' + - requests ; extra == 'full' + - s3fs>2024.2.0 ; extra == 'full' + - smbprotocol ; extra == 'full' + - tqdm ; extra == 'full' + - fusepy ; extra == 'fuse' + - gcsfs>2024.2.0 ; extra == 'gcs' + - pygit2 ; extra == 'git' + - requests ; extra == 'github' + - gcsfs ; extra == 'gs' + - panel ; extra == 'gui' + - pyarrow>=1 ; extra == 'hdfs' + - aiohttp!=4.0.0a0,!=4.0.0a1 ; extra == 'http' + - libarchive-c ; extra == 'libarchive' + - ocifs ; extra == 'oci' + - s3fs>2024.2.0 ; extra == 's3' + - paramiko ; extra == 'sftp' + - smbprotocol ; extra == 'smb' + - paramiko ; extra == 'ssh' + - aiohttp!=4.0.0a0,!=4.0.0a1 ; extra == 'test' + - numpy ; extra == 'test' + - pytest ; extra == 'test' + - pytest-asyncio!=0.22.0 ; extra == 'test' + - pytest-benchmark ; extra == 'test' + - pytest-cov ; extra == 'test' + - pytest-mock ; extra == 'test' + - pytest-recording ; extra == 'test' + - pytest-rerunfailures ; extra == 'test' + - requests ; extra == 'test' + - aiobotocore>=2.5.4,<3.0.0 ; extra == 'test-downstream' + - dask[dataframe,test] ; extra == 'test-downstream' + - moto[server]>4,<5 ; extra == 'test-downstream' + - pytest-timeout ; extra == 'test-downstream' + - xarray ; extra == 'test-downstream' + - adlfs ; extra == 'test-full' + - aiohttp!=4.0.0a0,!=4.0.0a1 ; extra == 'test-full' + - backports-zstd ; python_full_version < '3.14' and extra == 'test-full' + - cloudpickle ; extra == 'test-full' + - dask ; extra == 'test-full' + - distributed ; extra == 'test-full' + - dropbox ; extra == 'test-full' + - dropboxdrivefs ; extra == 'test-full' + - fastparquet ; extra == 'test-full' + - fusepy ; extra == 'test-full' + - gcsfs ; extra == 'test-full' + - jinja2 ; extra == 'test-full' + - kerchunk ; extra == 'test-full' + - libarchive-c ; extra == 'test-full' + - lz4 ; extra == 'test-full' + - notebook ; extra == 'test-full' + - numpy ; extra == 'test-full' + - ocifs ; extra == 'test-full' + - pandas<3.0.0 ; extra == 'test-full' + - panel ; extra == 'test-full' + - paramiko ; extra == 'test-full' + - pyarrow ; extra == 'test-full' + - pyarrow>=1 ; extra == 'test-full' + - pyftpdlib ; extra == 'test-full' + - pygit2 ; extra == 'test-full' + - pytest ; extra == 'test-full' + - pytest-asyncio!=0.22.0 ; extra == 'test-full' + - pytest-benchmark ; extra == 'test-full' + - pytest-cov ; extra == 'test-full' + - pytest-mock ; extra == 'test-full' + - pytest-recording ; extra == 'test-full' + - pytest-rerunfailures ; extra == 'test-full' + - python-snappy ; extra == 'test-full' + - requests ; extra == 'test-full' + - smbprotocol ; extra == 'test-full' + - tqdm ; extra == 'test-full' + - urllib3 ; extra == 'test-full' + - zarr ; extra == 'test-full' + - zstandard ; python_full_version < '3.14' and extra == 'test-full' + - tqdm ; extra == 'tqdm' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/73/90/a2c51050d9254bd9134e6368b3f94f92f0eb2c34ed0ca19ec449ce2fc288/fsspec_xrootd-0.5.2-py3-none-any.whl + name: fsspec-xrootd + version: 0.5.2 + sha256: 314763b6f31c01358ffe1fb1dca038085690efbee80ac5f5204f66d0ae9fd417 + requires_dist: + - fsspec + - pytest>=6 ; extra == 'dev' + - sphinx>=4.0 ; extra == 'docs' + - myst-parser>=0.13 ; extra == 'docs' + - sphinx-book-theme>=0.1.0 ; extra == 'docs' + - sphinx-copybutton ; extra == 'docs' + - pytest>=6 ; extra == 'test' + - pytest-rerunfailures ; extra == 'test' + - pytest-timeout ; extra == 'test' + requires_python: '>=3.10' - pypi: https://files.pythonhosted.org/packages/5f/e8/2e6301567e6debaad6abae0e217428471651ce877537b7095b6a8e7d8cd2/fts3-3.14.2-py3-none-any.whl name: fts3 version: 3.14.2 @@ -1995,6 +2312,21 @@ packages: - pyreadline ; python_full_version < '3.8' and sys_platform == 'win32' - pyreadline3 ; python_full_version >= '3.8' and sys_platform == 'win32' requires_python: '>=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*' +- pypi: https://files.pythonhosted.org/packages/22/ed/9c45c468fd6c31df3fe0622394b1853c00b86545d1e297f3fb9fba1232ce/hyperscan-0.8.2-cp314-cp314-macosx_10_15_x86_64.whl + name: hyperscan + version: 0.8.2 + sha256: 2c579c1ebccc384d904de4a20e7a105df6041dd82adb54cb9acd5bb19b9b07dc + requires_python: '>=3.9,<4.0' +- pypi: https://files.pythonhosted.org/packages/d0/23/49cf8ea1d129637941f06fb78f5f66077bf362762c5f6c01712c4cd0e87f/hyperscan-0.8.2-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl + name: hyperscan + version: 0.8.2 + sha256: 0c0af5d882bd6afb61e2b9a13c0d39fcbcee49c62f392096d6303bd34452813f + requires_python: '>=3.9,<4.0' +- pypi: https://files.pythonhosted.org/packages/d8/da/a8bb48a4fee86b5dad8a358559b70b010cd7effaa70ca5bb4e6e82e13703/hyperscan-0.8.2-cp314-cp314-macosx_11_0_arm64.whl + name: hyperscan + version: 0.8.2 + sha256: 4e9f8d1ae2c9596385d906e062b9e0081ae843e3975fd4a656e5fcf6bbc48c13 + requires_python: '>=3.9,<4.0' - conda: https://conda.anaconda.org/conda-forge/linux-64/icu-78.2-h33c6efd_0.conda sha256: 142a722072fa96cf16ff98eaaf641f54ab84744af81754c292cb81e0881c0329 md5: 186a18e3ba246eccfc7cff00cd19a870 @@ -2107,6 +2439,11 @@ packages: - pkg:pypi/iniconfig?source=compressed-mapping size: 13387 timestamp: 1760831448842 +- pypi: https://files.pythonhosted.org/packages/32/4b/b99e37f88336009971405cbb7630610322ed6fbfa31e1d7ab3fbf3049a2d/invoke-2.2.1-py3-none-any.whl + name: invoke + version: 2.2.1 + sha256: 2413bc441b376e5cd3f55bb5d364f973ad8bdd7bf87e53c79de3c11bf3feecc8 + requires_python: '>=3.6' - pypi: https://files.pythonhosted.org/packages/15/aa/0aca39a37d3c7eb941ba736ede56d689e7be91cab5d9ca846bde3999eba6/isodate-0.7.2-py3-none-any.whl name: isodate version: 0.7.2 @@ -2275,10 +2612,10 @@ packages: - pytest-cov ; extra == 'testing' - coverage ; extra == 'testing' requires_python: '>=3.7' -- pypi: https://files.pythonhosted.org/packages/16/4a/b4d7feb029d4e75d4882d8d1d9029938c31a2e73074f87ffcff0f4a8ba9e/lbplatformutils-4.5.1-py3-none-any.whl +- pypi: https://files.pythonhosted.org/packages/6d/10/b37ac718c5903758fa9058a5182026a4f3b65443196b82c7840389ea0dbd/lbplatformutils-4.6.1-py3-none-any.whl name: lbplatformutils - version: 4.5.1 - sha256: f61f8192bf93da16d50a3e039e9998d75aed8ffc486c226ab838bdaeb1b98679 + version: 4.6.1 + sha256: 92e6dd273e77873ba6cbd302c8b29fde71e5dbb7706f05856e362fb44fd9eee8 requires_python: '>=3.7,<4.0' - pypi: https://files.pythonhosted.org/packages/02/64/c86924898062e8217ed914a29458cfde9e4a9b80e4d4cbcca141983ba339/lbprodrun-1.12.4-py3-none-any.whl name: lbprodrun @@ -2310,6 +2647,111 @@ packages: purls: [] size: 725507 timestamp: 1770267139900 +- pypi: https://files.pythonhosted.org/packages/29/ce/ed422816fb30ffa3bc11597b30d5deca06b4a1388707a04215da73c65b53/levenshtein-0.27.3-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl + name: levenshtein + version: 0.27.3 + sha256: ce3bbbe92172a08b599d79956182c6b7ab6ec8d4adbe7237417a363b968ad87b + requires_dist: + - rapidfuzz>=3.9.0,<4.0.0 + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/76/2c/bb6ef359e007fe7b6b3195b68a94f4dd3ecd1885ee337ee8fbd4df55996f/levenshtein-0.27.3-cp314-cp314-macosx_11_0_arm64.whl + name: levenshtein + version: 0.27.3 + sha256: 8e5037c4a6f97a238e24aad6f98a1e984348b7931b1b04b6bd02bd4f8238150d + requires_dist: + - rapidfuzz>=3.9.0,<4.0.0 + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/f3/e1/2f705da403f865a5fa3449b155738dc9c53021698fd6926253a9af03180b/levenshtein-0.27.3-cp314-cp314-macosx_10_15_x86_64.whl + name: levenshtein + version: 0.27.3 + sha256: a6728bfae9a86002f0223576675fc7e2a6e7735da47185a1d13d1eaaa73dd4be + requires_dist: + - rapidfuzz>=3.9.0,<4.0.0 + requires_python: '>=3.10' +- pypi: git+ssh://git@gitlab.cern.ch:7999/jlisalab/LHCbDIRAC.git?rev=modules-to-cwl-migration#c441175f3289d6d85abf5d5612c3ff964edd9a5c + name: lhcbdirac + version: 0.1.dev20447+gc441175f3 + requires_dist: + - dirac~=9.1 + - lbplatformutils>=4.6.1 + - lbenv>=2.3.0 + - lbprodrun + - lbcondawrappers + - requests + - pydantic>=2 + - uproot[xrootd]>=5.3 + - pyyaml + - xmltodict + - hyperscan + - levenshtein + - zstandard + - rich + - httpx + - beautifulsoup4 + - python-gitlab + - pandas + - numpy + - lhcbdiracx-client + - lhcbdiracx-core + - lhcbdiracx-cli + - oracledb ; extra == 'server' + - dirac[server]~=9.1.0 ; extra == 'server' + - psutil ; extra == 'server' + - stomp-py ; extra == 'server' + - suds ; extra == 'server' + - mock ; extra == 'testing' + - pytest-mock ; extra == 'testing' + - pillow ; extra == 'testing' + - pytest ; extra == 'testing' + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/7f/37/8ea3555769b6048b5e4ec162cc90fd32e761c0e381ffb3baf888cb0d8a71/lhcbdiracx_api-0.0.8-py3-none-any.whl + name: lhcbdiracx-api + version: 0.0.8 + sha256: 13337f9b98b0907e372e014ee1012d99c7d1f1d8e3877daf96d73b165ca10aca + requires_dist: + - lhcbdiracx-core + - lhcbdiracx-client + - diracx-api==0.0.8 + - diracx-api[types]==0.0.8 ; extra == 'types' + - diracx-api[testing]==0.0.8 ; extra == 'testing' + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/68/15/bfb0c717b8f23c16907f3e73e8f56010ccd72e9900a108209665b0d9ed4b/lhcbdiracx_cli-0.0.8-py3-none-any.whl + name: lhcbdiracx-cli + version: 0.0.8 + sha256: 85e357eed0578796f78a5502c2235949dcd7fa456e7efaf1a0b2913f926f1b64 + requires_dist: + - lhcbdiracx-core + - lhcbdiracx-client + - lhcbdiracx-api + - diracx-cli==0.0.8 + - diracx-cli[types]==0.0.8 ; extra == 'types' + - diracx-cli[testing]==0.0.8 ; extra == 'testing' + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/2d/88/67602dfa2d7ab5d0518af82db34ab4d70dc2c3029b3ca788299a3be4a96d/lhcbdiracx_client-0.0.8-py3-none-any.whl + name: lhcbdiracx-client + version: 0.0.8 + sha256: 72bea573c481d011d816cbf02e39cee610b4b7aa8b57a2941659036de483907e + requires_dist: + - lhcbdiracx-core + - diracx-client==0.0.8 + - types-requests ; extra == 'types' + - diracx-api[types]==0.0.8 ; extra == 'types' + - diracx-client[testing]==0.0.8 ; extra == 'testing' + - diracx-testing==0.0.8 ; extra == 'testing' + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/34/8f/6105afdd8f4e1f3b198d09e4b2622622923d9fa9e077aed852c0bb035a3a/lhcbdiracx_core-0.0.8-py3-none-any.whl + name: lhcbdiracx-core + version: 0.0.8 + sha256: a23f9b343efddb80cb53c3e06c409c65221ff29a339d4aebe336f930d04c7942 + requires_dist: + - diracx-core==0.0.8 + - lhcbdiracx-testing ; extra == 'testing' + - diracx-testing ; extra == 'testing' + - diracx-core[types]==0.0.8 ; extra == 'testing' + - diracx-core[testing]==0.0.8 ; extra == 'types' + - types-cachetools ; extra == 'types' + - types-pyyaml ; extra == 'types' + requires_python: '>=3.11' - conda: https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-5_h4a7cf45_openblas.conda build_number: 5 sha256: 18c72545080b86739352482ba14ba2c4815e19e26a7417ca21a95b76ec8da24c @@ -4042,6 +4484,289 @@ packages: - pkg:pypi/packaging?source=compressed-mapping size: 72010 timestamp: 1769093650580 +- pypi: https://files.pythonhosted.org/packages/15/88/3cdd54fa279341afa10acf8d2b503556b1375245dccc9315659f795dd2e9/pandas-3.0.2-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl + name: pandas + version: 3.0.2 + sha256: deeca1b5a931fdf0c2212c8a659ade6d3b1edc21f0914ce71ef24456ca7a6535 + requires_dist: + - numpy>=1.26.0 ; python_full_version < '3.14' + - numpy>=2.3.3 ; python_full_version >= '3.14' + - python-dateutil>=2.8.2 + - tzdata ; sys_platform == 'win32' + - tzdata ; sys_platform == 'emscripten' + - hypothesis>=6.116.0 ; extra == 'test' + - pytest>=8.3.4 ; extra == 'test' + - pytest-xdist>=3.6.1 ; extra == 'test' + - pyarrow>=13.0.0 ; extra == 'pyarrow' + - bottleneck>=1.4.2 ; extra == 'performance' + - numba>=0.60.0 ; extra == 'performance' + - numexpr>=2.10.2 ; extra == 'performance' + - scipy>=1.14.1 ; extra == 'computation' + - xarray>=2024.10.0 ; extra == 'computation' + - fsspec>=2024.10.0 ; extra == 'fss' + - s3fs>=2024.10.0 ; extra == 'aws' + - gcsfs>=2024.10.0 ; extra == 'gcp' + - odfpy>=1.4.1 ; extra == 'excel' + - openpyxl>=3.1.5 ; extra == 'excel' + - python-calamine>=0.3.0 ; extra == 'excel' + - pyxlsb>=1.0.10 ; extra == 'excel' + - xlrd>=2.0.1 ; extra == 'excel' + - xlsxwriter>=3.2.0 ; extra == 'excel' + - pyarrow>=13.0.0 ; extra == 'parquet' + - pyarrow>=13.0.0 ; extra == 'feather' + - pyiceberg>=0.8.1 ; extra == 'iceberg' + - tables>=3.10.1 ; extra == 'hdf5' + - pyreadstat>=1.2.8 ; extra == 'spss' + - sqlalchemy>=2.0.36 ; extra == 'postgresql' + - psycopg2>=2.9.10 ; extra == 'postgresql' + - adbc-driver-postgresql>=1.2.0 ; extra == 'postgresql' + - sqlalchemy>=2.0.36 ; extra == 'mysql' + - pymysql>=1.1.1 ; extra == 'mysql' + - sqlalchemy>=2.0.36 ; extra == 'sql-other' + - adbc-driver-postgresql>=1.2.0 ; extra == 'sql-other' + - adbc-driver-sqlite>=1.2.0 ; extra == 'sql-other' + - beautifulsoup4>=4.12.3 ; extra == 'html' + - html5lib>=1.1 ; extra == 'html' + - lxml>=5.3.0 ; extra == 'html' + - lxml>=5.3.0 ; extra == 'xml' + - matplotlib>=3.9.3 ; extra == 'plot' + - jinja2>=3.1.5 ; extra == 'output-formatting' + - tabulate>=0.9.0 ; extra == 'output-formatting' + - pyqt5>=5.15.9 ; extra == 'clipboard' + - qtpy>=2.4.2 ; extra == 'clipboard' + - zstandard>=0.23.0 ; extra == 'compression' + - pytz>=2024.2 ; extra == 'timezone' + - adbc-driver-postgresql>=1.2.0 ; extra == 'all' + - adbc-driver-sqlite>=1.2.0 ; extra == 'all' + - beautifulsoup4>=4.12.3 ; extra == 'all' + - bottleneck>=1.4.2 ; extra == 'all' + - fastparquet>=2024.11.0 ; extra == 'all' + - fsspec>=2024.10.0 ; extra == 'all' + - gcsfs>=2024.10.0 ; extra == 'all' + - html5lib>=1.1 ; extra == 'all' + - hypothesis>=6.116.0 ; extra == 'all' + - jinja2>=3.1.5 ; extra == 'all' + - lxml>=5.3.0 ; extra == 'all' + - matplotlib>=3.9.3 ; extra == 'all' + - numba>=0.60.0 ; extra == 'all' + - numexpr>=2.10.2 ; extra == 'all' + - odfpy>=1.4.1 ; extra == 'all' + - openpyxl>=3.1.5 ; extra == 'all' + - psycopg2>=2.9.10 ; extra == 'all' + - pyarrow>=13.0.0 ; extra == 'all' + - pyiceberg>=0.8.1 ; extra == 'all' + - pymysql>=1.1.1 ; extra == 'all' + - pyqt5>=5.15.9 ; extra == 'all' + - pyreadstat>=1.2.8 ; extra == 'all' + - pytest>=8.3.4 ; extra == 'all' + - pytest-xdist>=3.6.1 ; extra == 'all' + - python-calamine>=0.3.0 ; extra == 'all' + - pytz>=2024.2 ; extra == 'all' + - pyxlsb>=1.0.10 ; extra == 'all' + - qtpy>=2.4.2 ; extra == 'all' + - scipy>=1.14.1 ; extra == 'all' + - s3fs>=2024.10.0 ; extra == 'all' + - sqlalchemy>=2.0.36 ; extra == 'all' + - tables>=3.10.1 ; extra == 'all' + - tabulate>=0.9.0 ; extra == 'all' + - xarray>=2024.10.0 ; extra == 'all' + - xlrd>=2.0.1 ; extra == 'all' + - xlsxwriter>=3.2.0 ; extra == 'all' + - zstandard>=0.23.0 ; extra == 'all' + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/95/25/bdb9326c3b5455f8d4d3549fce7abcf967259de146fe2cf7a82368141948/pandas-3.0.2-cp314-cp314-macosx_11_0_arm64.whl + name: pandas + version: 3.0.2 + sha256: 0555c5882688a39317179ab4a0ed41d3ebc8812ab14c69364bbee8fb7a3f6288 + requires_dist: + - numpy>=1.26.0 ; python_full_version < '3.14' + - numpy>=2.3.3 ; python_full_version >= '3.14' + - python-dateutil>=2.8.2 + - tzdata ; sys_platform == 'win32' + - tzdata ; sys_platform == 'emscripten' + - hypothesis>=6.116.0 ; extra == 'test' + - pytest>=8.3.4 ; extra == 'test' + - pytest-xdist>=3.6.1 ; extra == 'test' + - pyarrow>=13.0.0 ; extra == 'pyarrow' + - bottleneck>=1.4.2 ; extra == 'performance' + - numba>=0.60.0 ; extra == 'performance' + - numexpr>=2.10.2 ; extra == 'performance' + - scipy>=1.14.1 ; extra == 'computation' + - xarray>=2024.10.0 ; extra == 'computation' + - fsspec>=2024.10.0 ; extra == 'fss' + - s3fs>=2024.10.0 ; extra == 'aws' + - gcsfs>=2024.10.0 ; extra == 'gcp' + - odfpy>=1.4.1 ; extra == 'excel' + - openpyxl>=3.1.5 ; extra == 'excel' + - python-calamine>=0.3.0 ; extra == 'excel' + - pyxlsb>=1.0.10 ; extra == 'excel' + - xlrd>=2.0.1 ; extra == 'excel' + - xlsxwriter>=3.2.0 ; extra == 'excel' + - pyarrow>=13.0.0 ; extra == 'parquet' + - pyarrow>=13.0.0 ; extra == 'feather' + - pyiceberg>=0.8.1 ; extra == 'iceberg' + - tables>=3.10.1 ; extra == 'hdf5' + - pyreadstat>=1.2.8 ; extra == 'spss' + - sqlalchemy>=2.0.36 ; extra == 'postgresql' + - psycopg2>=2.9.10 ; extra == 'postgresql' + - adbc-driver-postgresql>=1.2.0 ; extra == 'postgresql' + - sqlalchemy>=2.0.36 ; extra == 'mysql' + - pymysql>=1.1.1 ; extra == 'mysql' + - sqlalchemy>=2.0.36 ; extra == 'sql-other' + - adbc-driver-postgresql>=1.2.0 ; extra == 'sql-other' + - adbc-driver-sqlite>=1.2.0 ; extra == 'sql-other' + - beautifulsoup4>=4.12.3 ; extra == 'html' + - html5lib>=1.1 ; extra == 'html' + - lxml>=5.3.0 ; extra == 'html' + - lxml>=5.3.0 ; extra == 'xml' + - matplotlib>=3.9.3 ; extra == 'plot' + - jinja2>=3.1.5 ; extra == 'output-formatting' + - tabulate>=0.9.0 ; extra == 'output-formatting' + - pyqt5>=5.15.9 ; extra == 'clipboard' + - qtpy>=2.4.2 ; extra == 'clipboard' + - zstandard>=0.23.0 ; extra == 'compression' + - pytz>=2024.2 ; extra == 'timezone' + - adbc-driver-postgresql>=1.2.0 ; extra == 'all' + - adbc-driver-sqlite>=1.2.0 ; extra == 'all' + - beautifulsoup4>=4.12.3 ; extra == 'all' + - bottleneck>=1.4.2 ; extra == 'all' + - fastparquet>=2024.11.0 ; extra == 'all' + - fsspec>=2024.10.0 ; extra == 'all' + - gcsfs>=2024.10.0 ; extra == 'all' + - html5lib>=1.1 ; extra == 'all' + - hypothesis>=6.116.0 ; extra == 'all' + - jinja2>=3.1.5 ; extra == 'all' + - lxml>=5.3.0 ; extra == 'all' + - matplotlib>=3.9.3 ; extra == 'all' + - numba>=0.60.0 ; extra == 'all' + - numexpr>=2.10.2 ; extra == 'all' + - odfpy>=1.4.1 ; extra == 'all' + - openpyxl>=3.1.5 ; extra == 'all' + - psycopg2>=2.9.10 ; extra == 'all' + - pyarrow>=13.0.0 ; extra == 'all' + - pyiceberg>=0.8.1 ; extra == 'all' + - pymysql>=1.1.1 ; extra == 'all' + - pyqt5>=5.15.9 ; extra == 'all' + - pyreadstat>=1.2.8 ; extra == 'all' + - pytest>=8.3.4 ; extra == 'all' + - pytest-xdist>=3.6.1 ; extra == 'all' + - python-calamine>=0.3.0 ; extra == 'all' + - pytz>=2024.2 ; extra == 'all' + - pyxlsb>=1.0.10 ; extra == 'all' + - qtpy>=2.4.2 ; extra == 'all' + - scipy>=1.14.1 ; extra == 'all' + - s3fs>=2024.10.0 ; extra == 'all' + - sqlalchemy>=2.0.36 ; extra == 'all' + - tables>=3.10.1 ; extra == 'all' + - tabulate>=0.9.0 ; extra == 'all' + - xarray>=2024.10.0 ; extra == 'all' + - xlrd>=2.0.1 ; extra == 'all' + - xlsxwriter>=3.2.0 ; extra == 'all' + - zstandard>=0.23.0 ; extra == 'all' + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/bb/40/c6ea527147c73b24fc15c891c3fcffe9c019793119c5742b8784a062c7db/pandas-3.0.2-cp314-cp314-macosx_10_15_x86_64.whl + name: pandas + version: 3.0.2 + sha256: db0dbfd2a6cdf3770aa60464d50333d8f3d9165b2f2671bcc299b72de5a6677b + requires_dist: + - numpy>=1.26.0 ; python_full_version < '3.14' + - numpy>=2.3.3 ; python_full_version >= '3.14' + - python-dateutil>=2.8.2 + - tzdata ; sys_platform == 'win32' + - tzdata ; sys_platform == 'emscripten' + - hypothesis>=6.116.0 ; extra == 'test' + - pytest>=8.3.4 ; extra == 'test' + - pytest-xdist>=3.6.1 ; extra == 'test' + - pyarrow>=13.0.0 ; extra == 'pyarrow' + - bottleneck>=1.4.2 ; extra == 'performance' + - numba>=0.60.0 ; extra == 'performance' + - numexpr>=2.10.2 ; extra == 'performance' + - scipy>=1.14.1 ; extra == 'computation' + - xarray>=2024.10.0 ; extra == 'computation' + - fsspec>=2024.10.0 ; extra == 'fss' + - s3fs>=2024.10.0 ; extra == 'aws' + - gcsfs>=2024.10.0 ; extra == 'gcp' + - odfpy>=1.4.1 ; extra == 'excel' + - openpyxl>=3.1.5 ; extra == 'excel' + - python-calamine>=0.3.0 ; extra == 'excel' + - pyxlsb>=1.0.10 ; extra == 'excel' + - xlrd>=2.0.1 ; extra == 'excel' + - xlsxwriter>=3.2.0 ; extra == 'excel' + - pyarrow>=13.0.0 ; extra == 'parquet' + - pyarrow>=13.0.0 ; extra == 'feather' + - pyiceberg>=0.8.1 ; extra == 'iceberg' + - tables>=3.10.1 ; extra == 'hdf5' + - pyreadstat>=1.2.8 ; extra == 'spss' + - sqlalchemy>=2.0.36 ; extra == 'postgresql' + - psycopg2>=2.9.10 ; extra == 'postgresql' + - adbc-driver-postgresql>=1.2.0 ; extra == 'postgresql' + - sqlalchemy>=2.0.36 ; extra == 'mysql' + - pymysql>=1.1.1 ; extra == 'mysql' + - sqlalchemy>=2.0.36 ; extra == 'sql-other' + - adbc-driver-postgresql>=1.2.0 ; extra == 'sql-other' + - adbc-driver-sqlite>=1.2.0 ; extra == 'sql-other' + - beautifulsoup4>=4.12.3 ; extra == 'html' + - html5lib>=1.1 ; extra == 'html' + - lxml>=5.3.0 ; extra == 'html' + - lxml>=5.3.0 ; extra == 'xml' + - matplotlib>=3.9.3 ; extra == 'plot' + - jinja2>=3.1.5 ; extra == 'output-formatting' + - tabulate>=0.9.0 ; extra == 'output-formatting' + - pyqt5>=5.15.9 ; extra == 'clipboard' + - qtpy>=2.4.2 ; extra == 'clipboard' + - zstandard>=0.23.0 ; extra == 'compression' + - pytz>=2024.2 ; extra == 'timezone' + - adbc-driver-postgresql>=1.2.0 ; extra == 'all' + - adbc-driver-sqlite>=1.2.0 ; extra == 'all' + - beautifulsoup4>=4.12.3 ; extra == 'all' + - bottleneck>=1.4.2 ; extra == 'all' + - fastparquet>=2024.11.0 ; extra == 'all' + - fsspec>=2024.10.0 ; extra == 'all' + - gcsfs>=2024.10.0 ; extra == 'all' + - html5lib>=1.1 ; extra == 'all' + - hypothesis>=6.116.0 ; extra == 'all' + - jinja2>=3.1.5 ; extra == 'all' + - lxml>=5.3.0 ; extra == 'all' + - matplotlib>=3.9.3 ; extra == 'all' + - numba>=0.60.0 ; extra == 'all' + - numexpr>=2.10.2 ; extra == 'all' + - odfpy>=1.4.1 ; extra == 'all' + - openpyxl>=3.1.5 ; extra == 'all' + - psycopg2>=2.9.10 ; extra == 'all' + - pyarrow>=13.0.0 ; extra == 'all' + - pyiceberg>=0.8.1 ; extra == 'all' + - pymysql>=1.1.1 ; extra == 'all' + - pyqt5>=5.15.9 ; extra == 'all' + - pyreadstat>=1.2.8 ; extra == 'all' + - pytest>=8.3.4 ; extra == 'all' + - pytest-xdist>=3.6.1 ; extra == 'all' + - python-calamine>=0.3.0 ; extra == 'all' + - pytz>=2024.2 ; extra == 'all' + - pyxlsb>=1.0.10 ; extra == 'all' + - qtpy>=2.4.2 ; extra == 'all' + - scipy>=1.14.1 ; extra == 'all' + - s3fs>=2024.10.0 ; extra == 'all' + - sqlalchemy>=2.0.36 ; extra == 'all' + - tables>=3.10.1 ; extra == 'all' + - tabulate>=0.9.0 ; extra == 'all' + - xarray>=2024.10.0 ; extra == 'all' + - xlrd>=2.0.1 ; extra == 'all' + - xlsxwriter>=3.2.0 ; extra == 'all' + - zstandard>=0.23.0 ; extra == 'all' + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/a9/90/a744336f5af32c433bd09af7854599682a383b37cfd78f7de263de6ad6cb/paramiko-4.0.0-py3-none-any.whl + name: paramiko + version: 4.0.0 + sha256: 0e20e00ac666503bf0b4eda3b6d833465a2b7aff2e2b3d79a8bba5ef144ee3b9 + requires_dist: + - bcrypt>=3.2 + - cryptography>=3.3 + - invoke>=2.0 + - pynacl>=1.5 + - pyasn1>=0.1.7 ; extra == 'gssapi' + - gssapi>=1.4.1 ; sys_platform != 'win32' and extra == 'gssapi' + - pywin32>=2.1.8 ; sys_platform == 'win32' and extra == 'gssapi' + requires_python: '>=3.9' - conda: https://conda.anaconda.org/conda-forge/noarch/pathspec-1.0.4-pyhd8ed1ab_0.conda sha256: 29ea20d0faf20374fcd61c25f6d32fb8e9a2c786a7f1473a0c3ead359470fbe1 md5: 2908273ac396d2cd210a8127f5f1c0d6 @@ -4397,6 +5122,34 @@ packages: - coverage[toml]==7.10.7 ; extra == 'tests' - pytest>=8.4.2,<9.0.0 ; extra == 'tests' requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/3e/d0/f301f83ac8dbe53442c5a43f6a39016f94f754d7a9815a875b65e218a307/pynacl-1.6.2-cp38-abi3-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl + name: pynacl + version: 1.6.2 + sha256: 8a66d6fb6ae7661c58995f9c6435bda2b1e68b54b598a6a10247bfcdadac996c + requires_dist: + - cffi>=1.4.1 ; python_full_version < '3.9' and platform_python_implementation != 'PyPy' + - cffi>=2.0.0 ; python_full_version >= '3.9' and platform_python_implementation != 'PyPy' + - pytest>=7.4.0 ; extra == 'tests' + - pytest-cov>=2.10.1 ; extra == 'tests' + - pytest-xdist>=3.5.0 ; extra == 'tests' + - hypothesis>=3.27.0 ; extra == 'tests' + - sphinx<7 ; extra == 'docs' + - sphinx-rtd-theme ; extra == 'docs' + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/be/7b/4845bbf88e94586ec47a432da4e9107e3fc3ce37eb412b1398630a37f7dd/pynacl-1.6.2-cp38-abi3-macosx_10_10_universal2.whl + name: pynacl + version: 1.6.2 + sha256: c949ea47e4206af7c8f604b8278093b674f7c79ed0d4719cc836902bf4517465 + requires_dist: + - cffi>=1.4.1 ; python_full_version < '3.9' and platform_python_implementation != 'PyPy' + - cffi>=2.0.0 ; python_full_version >= '3.9' and platform_python_implementation != 'PyPy' + - pytest>=7.4.0 ; extra == 'tests' + - pytest-cov>=2.10.1 ; extra == 'tests' + - pytest-xdist>=3.5.0 ; extra == 'tests' + - hypothesis>=3.27.0 ; extra == 'tests' + - sphinx<7 ; extra == 'docs' + - sphinx-rtd-theme ; extra == 'docs' + requires_python: '>=3.8' - pypi: https://files.pythonhosted.org/packages/10/bd/c038d7cc38edc1aa5bf91ab8068b63d4308c66c4c8bb3cbba7dfbc049f9c/pyparsing-3.3.2-py3-none-any.whl name: pyparsing version: 3.3.2 @@ -4598,6 +5351,17 @@ packages: - pkg:pypi/gfal2-python?source=hash-mapping size: 185917 timestamp: 1769083275804 +- pypi: https://files.pythonhosted.org/packages/38/ee/a61bb562bdf6f0bc6c51cdcf80ab5503cbb4b2f5053fa4b054cc0a56e48a/python_gitlab-8.2.0-py3-none-any.whl + name: python-gitlab + version: 8.2.0 + sha256: 884618d4d60beadb21bb0c5f0cca46e70c6e501784f136bf0b6f85f5bc15ce62 + requires_dist: + - requests>=2.32.0 + - requests-toolbelt>=1.0.0 + - argcomplete>=1.10.0,<3 ; extra == 'autocompletion' + - pyyaml>=6.0.1 ; extra == 'yaml' + - gql[httpx]>=3.5.0,<5 ; extra == 'graphql' + requires_python: '>=3.10.0' - conda: https://conda.anaconda.org/conda-forge/linux-64/python-librt-0.7.8-py314h0f05182_0.conda sha256: 7c4615367e1d8bee1e98abcfccd742fb0c382a150f21cb592a66af69063eae43 md5: 1cdbb8798d700d90f33998d41baed1ec @@ -4698,6 +5462,27 @@ packages: - pkg:pypi/pyyaml?source=compressed-mapping size: 189475 timestamp: 1770223788648 +- pypi: https://files.pythonhosted.org/packages/2d/e1/c2141f1840a41e07ad2db6f724945f8f8ff3065463899a22939152dd6e09/rapidfuzz-3.14.5-cp314-cp314-macosx_11_0_arm64.whl + name: rapidfuzz + version: 3.14.5 + sha256: 0298d357e2bc59d572da4db0bc631009b6f8f6c9bc8c11e99a12b833f16b6575 + requires_dist: + - numpy ; extra == 'all' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/81/41/aa3ffb3355e62e1bf91f6599b3092e866bc88487a07c524004943c7676df/rapidfuzz-3.14.5-cp314-cp314-macosx_10_15_x86_64.whl + name: rapidfuzz + version: 3.14.5 + sha256: 1a31cc6d7d03e7318a0974c038959c59e19c752b81115f2e9138b3331cd64d45 + requires_dist: + - numpy ; extra == 'all' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/c8/85/9535df0b78ba51f478c9ce7eb6d1f85535cc31fe356773b48fd9d3e563ca/rapidfuzz-3.14.5-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl + name: rapidfuzz + version: 3.14.5 + sha256: 4900143d82071bdda533b00300c40b14b963ff826b3642cc463b6dd0f036585e + requires_dist: + - numpy ; extra == 'all' + requires_python: '>=3.10' - pypi: https://files.pythonhosted.org/packages/b9/20/35d2baebacf357b562bd081936b66cd845775442973cb033a377fd639a84/rdflib-7.5.0-py3-none-any.whl name: rdflib version: 7.5.0 @@ -4773,6 +5558,13 @@ packages: - pysocks>=1.5.6,!=1.5.7 ; extra == 'socks' - chardet>=3.0.2,<6 ; extra == 'use-chardet-on-py3' requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/3f/51/d4db610ef29373b879047326cbf6fa98b6c1969d6f6dc423279de2b1be2c/requests_toolbelt-1.0.0-py2.py3-none-any.whl + name: requests-toolbelt + version: 1.0.0 + sha256: cccfdd665f0a24fcf4726e690f65639d272bb0637b9b92dfd91a5568ccf6bd06 + requires_dist: + - requests>=2.0.1,<3.0.0 + requires_python: '>=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*' - pypi: https://files.pythonhosted.org/packages/ef/45/615f5babd880b4bd7d405cc0dc348234c5ffb6ed1ea33e152ede08b2072d/rich-14.3.2-py3-none-any.whl name: rich version: 14.3.2 @@ -5070,6 +5862,11 @@ packages: version: 5.0.2 sha256: b30115f0def7d7531d22a0fb6502488d879e75b260a9db4d0819cfb25403af5e requires_python: '>=3.7' +- pypi: https://files.pythonhosted.org/packages/46/2c/1462b1d0a634697ae9e55b3cecdcb64788e8b7d63f54d923fcd0bb140aed/soupsieve-2.8.3-py3-none-any.whl + name: soupsieve + version: 2.8.3 + sha256: ed64f2ba4eebeab06cc4962affce381647455978ffc1e36bb79a545b91f45a95 + requires_python: '>=3.9' - pypi: https://files.pythonhosted.org/packages/f9/38/8b6fc7a8153cb49eb3a9a13acfa9eeb6cc476e37888781e593e6f02ac05e/spython-0.3.14-py3-none-any.whl name: spython version: 0.3.14 @@ -5380,6 +6177,26 @@ packages: - pkg:pypi/ukkonen?source=hash-mapping size: 14884 timestamp: 1769439056290 +- pypi: https://files.pythonhosted.org/packages/c4/55/85e2732345dd8b66437cddedac4ee7ef2d9c25bf8792830b095f2ee658f3/uproot-5.7.3-py3-none-any.whl + name: uproot + version: 5.7.3 + sha256: aeb096ab2ef10f96c3914fcf981352b69e350fac58a4658586f7eb9e3326b957 + requires_dist: + - awkward>=2.8.2 + - cramjam>=2.5.0 + - fsspec!=2026.2.0 + - numpy + - packaging + - typing-extensions>=4.1.0 ; python_full_version < '3.11' + - xxhash + - kvikio-cu12 ; extra == 'gds-cu12' + - nvidia-nvcomp-cu12 ; extra == 'gds-cu12' + - kvikio-cu13 ; extra == 'gds-cu13' + - nvidia-nvcomp-cu13 ; extra == 'gds-cu13' + - aiohttp ; extra == 'http' + - s3fs ; extra == 's3' + - fsspec-xrootd>=0.5.0 ; extra == 'xrootd' + requires_python: '>=3.10' - pypi: https://files.pythonhosted.org/packages/39/08/aaaad47bc4e9dc8c725e68f9d04865dbcb2052843ff09c97b08904852d84/urllib3-2.6.3-py3-none-any.whl name: urllib3 version: 2.6.3 @@ -5483,6 +6300,14 @@ packages: requires_dist: - coverage ; extra == 'testing' requires_python: '>=3.7' +- pypi: https://files.pythonhosted.org/packages/38/34/98a2f52245f4d47be93b580dae5f9861ef58977d73a79eb47c58f1ad1f3a/xmltodict-1.0.4-py3-none-any.whl + name: xmltodict + version: 1.0.4 + sha256: a4a00d300b0e1c59fc2bfccb53d7b2e88c32f200df138a0dd2229f842497026a + requires_dist: + - pytest ; extra == 'test' + - pytest-cov ; extra == 'test' + requires_python: '>=3.9' - conda: https://conda.anaconda.org/conda-forge/linux-64/xrootd-5.9.1-py314h75aeccf_0.conda sha256: 2351cace7322d68dd834c276f4cb19bc35a68d90642dd7083b4924bb26a66228 md5: d9b7e0eeecec187f4344983ba341c2d7 @@ -5576,6 +6401,21 @@ packages: - pkg:pypi/xrootd?source=hash-mapping size: 3347452 timestamp: 1769448002819 +- pypi: https://files.pythonhosted.org/packages/18/d7/5dac2eb2ec75fd771957a13e5dda560efb2176d5203f39502a5fc571f899/xxhash-3.6.0-cp314-cp314-macosx_11_0_arm64.whl + name: xxhash + version: 3.6.0 + sha256: a54844be970d3fc22630b32d515e79a90d0a3ddb2644d8d7402e3c4c8da61405 + requires_python: '>=3.7' +- pypi: https://files.pythonhosted.org/packages/7e/5e/0138bc4484ea9b897864d59fce9be9086030825bc778b76cb5a33a906d37/xxhash-3.6.0-cp314-cp314-macosx_10_13_x86_64.whl + name: xxhash + version: 3.6.0 + sha256: a40a3d35b204b7cc7643cbcf8c9976d818cb47befcfac8bbefec8038ac363f3e + requires_python: '>=3.7' +- pypi: https://files.pythonhosted.org/packages/ed/ba/603ce3961e339413543d8cd44f21f2c80e2a7c5cfe692a7b1f2cccf58f3c/xxhash-3.6.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + name: xxhash + version: 3.6.0 + sha256: 0226aa89035b62b6a86d3c68df4d7c1f47a342b8683da2b60cedcddb46c4d95b + requires_python: '>=3.7' - conda: https://conda.anaconda.org/conda-forge/linux-64/yaml-0.2.5-h280c20c_3.conda sha256: 6d9ea2f731e284e9316d95fa61869fe7bbba33df7929f82693c121022810f4ad md5: a77f85f77be52ff59391544bfe73390a diff --git a/pyproject.toml b/pyproject.toml index 2837f9f..f31a72c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -31,6 +31,7 @@ dependencies = [ "diracx-client>=0.0.8", "diracx-cli>=0.0.8", "lbprodrun", + "LHCbDIRAC @ git+ssh://git@gitlab.cern.ch:7999/jlisalab/LHCbDIRAC.git@modules-to-cwl-migration", # Temporary fork dependency "pydantic", "pyyaml", "typer", From 98ccc37b9909fe02d5dbd948bccafdd514b83644 Mon Sep 17 00:00:00 2001 From: Jorge Lisa <64639359+AcquaDiGiorgio@users.noreply.github.com> Date: Mon, 27 Apr 2026 16:09:47 +0200 Subject: [PATCH 06/21] feat: Migrate BookkeepingReport command to cwl-dirac --- src/dirac_cwl/commands/__init__.py | 3 +- src/dirac_cwl/commands/bookkeeping_report.py | 159 +++++++ src/dirac_cwl/commands/utils.py | 92 ++++ test/test_commands.py | 476 ++++++++++++++++++- 4 files changed, 728 insertions(+), 2 deletions(-) create mode 100644 src/dirac_cwl/commands/bookkeeping_report.py create mode 100644 src/dirac_cwl/commands/utils.py diff --git a/src/dirac_cwl/commands/__init__.py b/src/dirac_cwl/commands/__init__.py index aa213e4..7367a47 100644 --- a/src/dirac_cwl/commands/__init__.py +++ b/src/dirac_cwl/commands/__init__.py @@ -1,6 +1,7 @@ """Command classes for workflow pre/post-processing operations.""" +from .bookkeeping_report import BookeepingReport from .core import PostProcessCommand, PreProcessCommand from .upload_log_file import UploadLogFile -__all__ = ["PreProcessCommand", "PostProcessCommand", "UploadLogFile"] +__all__ = ["PreProcessCommand", "PostProcessCommand", "UploadLogFile", "BookeepingReport"] diff --git a/src/dirac_cwl/commands/bookkeeping_report.py b/src/dirac_cwl/commands/bookkeeping_report.py new file mode 100644 index 0000000..771d456 --- /dev/null +++ b/src/dirac_cwl/commands/bookkeeping_report.py @@ -0,0 +1,159 @@ +"""LHCb command for bookkeeping report file generation based on the XMLSummary and the XML catalog.""" + +import os + +from DIRAC.Workflow.Utilities.Utils import getStepCPUTimes +from LHCbDIRAC.BookkeepingSystem.Client.BookkeepingClient import BookkeepingClient +from LHCbDIRAC.Core.Utilities.ProductionData import constructProductionLFNs +from LHCbDIRAC.Core.Utilities.XMLSummaries import XMLSummary +from LHCbDIRAC.Workflow.Modules.BookkeepingReport import ( + _generate_xml_object, + _generateInputFiles, + _generateOutputFiles, + _prepare_job_info, + _process_time, +) +from LHCbDIRAC.Workflow.Modules.ModulesUtilities import getNumberOfProcessorsToUse + +from dirac_cwl.core.exceptions import WorkflowProcessingException + +from .core import PostProcessCommand +from .utils import prepare_lhcb_workflow_commons + + +class BookeepingReport(PostProcessCommand): + """Generates a bookkeeping report file based on the XMLSummary and the pool XML catalog.""" + + def execute(self, job_path, **kwargs): + """Execute the command. + + :param job_path: Path to the job working directory. + :param kwargs: Additional keyword arguments. + """ + # Obtain Workflow Commons + workflow_commons_path = kwargs.get("workflow-commons-path", os.path.join(job_path, "workflow_commons.json")) + + workflow_commons = prepare_lhcb_workflow_commons( + workflow_commons_path, + extra_mandatory_values=[ + "bk_step_id", + ], + extra_default_values={ + "bookkeeping_LFNs": [], + "size": {}, + "md5": {}, + "guid": {}, + "sim_description": "NoSimConditions", + }, + ) + + if not workflow_commons["step_status"]["OK"]: + return + + # Setup variables + start_time = workflow_commons.get("start_time", None) + + cpu_times = {} + if start_time: + cpu_times["StartTime"] = start_time + if "start_stats" in workflow_commons: + cpu_times["StartStats"] = workflow_commons["start_stats"] + + exectime, cputime = getStepCPUTimes(cpu_times) + + number_of_processors = getNumberOfProcessorsToUse( + workflow_commons["job_id"], workflow_commons["max_number_of_processors"] + ) + + bk_client = BookkeepingClient() + + parameters = { + "PRODUCTION_ID": workflow_commons["production_id"], + "JOB_ID": workflow_commons["prod_job_id"], + "configVersion": workflow_commons["config_version"], + "outputList": workflow_commons["outputs"], + "configName": workflow_commons["config_name"], + "outputDataFileMask": workflow_commons["output_data_file_mask"], + } + + if "bookkeeping_LFNs" in workflow_commons and "production_output_data" in workflow_commons: + bk_lfns = workflow_commons["bookkeeping_LFNs"] + + if not isinstance(bk_lfns, list): + bk_lfns = [i.strip() for i in bk_lfns.split(";")] + + else: + result = constructProductionLFNs(parameters, bk_client) + if not result["OK"]: + raise WorkflowProcessingException("Could not create production LFNs") + + bk_lfns = result["Value"]["BookkeepingLFNs"] + + ldate, ltime, ldatestart, ltimestart = _process_time(start_time) + + # Obtain XMLSummary + if "xml_summary_path" in workflow_commons: + xf_o = XMLSummary(workflow_commons["xml_summary_path"]) + else: + xf_o = _generate_xml_object( + workflow_commons["cleaned_application_name"], + workflow_commons["production_id"], + workflow_commons["prod_job_id"], + workflow_commons["command_number"], + workflow_commons["command_id"], + ) + + info_dict = { + "exectime": exectime, + "cputime": cputime, + "numberOfProcessors": number_of_processors, + "production_id": workflow_commons["production_id"], + "jobID": workflow_commons["job_id"], + "siteName": workflow_commons["site_name"], + "jobType": workflow_commons["job_type"], + "applicationName": workflow_commons["application_name"], + "applicationVersion": workflow_commons["application_version"], + "numberOfEvents": workflow_commons["number_of_events"], + } + + # Generate job_info object + job_info = _prepare_job_info( + info_dict, + ldatestart, + ltimestart, + ldate, + ltime, + xf_o, + workflow_commons["inputs"], + workflow_commons["command_id"], + workflow_commons["bk_step_id"], + bk_client, + workflow_commons["config_name"], + workflow_commons["config_version"], + ) + + # Add input files to job_info + _generateInputFiles(job_info, bk_lfns, workflow_commons["inputs"]) + + # Add output files to job_info + _generateOutputFiles( + job_info, + bk_lfns, + workflow_commons["event_type"], + workflow_commons["application_name"], + xf_o, + workflow_commons["outputs"], + workflow_commons["inputs"], + ) + + # Generate SimulationConditions + if workflow_commons["application_name"] == "Gauss": + job_info.simulation_condition = workflow_commons["sim_description"] + + # Convert job_info object to XML + doc = job_info.to_xml() + + # Write to file + bfilename = f"bookkeeping_{workflow_commons['command_id']}.xml" + with open(bfilename, "wb") as bfile: + bfile.write(doc) diff --git a/src/dirac_cwl/commands/utils.py b/src/dirac_cwl/commands/utils.py new file mode 100644 index 0000000..917a71e --- /dev/null +++ b/src/dirac_cwl/commands/utils.py @@ -0,0 +1,92 @@ +""".""" + +import json +import os + +from DIRAC import siteName +from DIRAC.Core.Utilities.ReturnValues import S_OK + +from dirac_cwl.core.exceptions import WorkflowProcessingException + + +def prepare_lhcb_workflow_commons(workflow_commons_path, extra_mandatory_values=[], extra_default_values={}): + """Return a dictionary containing the values of a workflow_commons.json file. + + Also performs a series of checks to ensure everything is in order. + """ + if not os.path.exists(workflow_commons_path): + raise WorkflowProcessingException(f"{workflow_commons_path} file not found") + + with open(workflow_commons_path, "r", encoding="utf-8") as f: + workflow_commons = json.load(f) + + if not workflow_commons: + raise WorkflowProcessingException(f"{workflow_commons_path} cannot be empty") + + mandatory_values = [ + "job_id", + "job_type", + "production_id", + "prod_job_id", + "number_of_events", + "application_name", + "application_version", + "inputs", + "outputs", # outputList + "executable", + "command_id", # StepID + "command_number", + ] + + mandatory_values.extend(extra_mandatory_values) + missing_values = [] + + for value in mandatory_values: + if value not in workflow_commons: + missing_values.append(value) + + if missing_values: + raise WorkflowProcessingException( + f"The following values are missing in workflow_commons.json: {missing_values}" + ) + + commons_defaults = { + "output_data_file_mask": "", + "run_metadata": {}, + "log_target_path": "", + "output_mode": "", + "production_output_data": [], + "CPUe": 0, + "max_number_of_events": "0", + "output_SEs": {}, + "output_data_type": None, + "application_log": "", + "application_type": None, + "options_file": None, + "options_line": None, + "extra_packages": "", + "multi_core": False, + "max_number_of_processors": None, + "system_config": None, + "mcTCK": None, + "condDB_tag": None, + "DQ_tag": None, + "step_status": S_OK(), + "config_name": None, + "config_version": None, + } + + for k, v in extra_default_values.items(): + if k not in commons_defaults: + commons_defaults[k] = v + + for k, v in commons_defaults.items(): + if k not in workflow_commons: + workflow_commons[k] = v + + cleaned_application_name = workflow_commons["application_name"].replace("/", "") + workflow_commons["cleaned_application_name"] = cleaned_application_name + + workflow_commons["site_name"] = siteName() + + return workflow_commons diff --git a/test/test_commands.py b/test/test_commands.py index 6b9e8dc..2569c06 100644 --- a/test/test_commands.py +++ b/test/test_commands.py @@ -1,14 +1,55 @@ """.""" +import json import os import tempfile +import time +import xml.etree.ElementTree as ET +from pathlib import Path +from textwrap import dedent from urllib.parse import urljoin +import LHCbDIRAC import pytest +from DIRAC import siteName from DIRACCommon.Core.Utilities.ReturnValues import S_ERROR, S_OK +from LHCbDIRAC.Core.Utilities.XMLSummaries import XMLSummary from pytest_mock import MockerFixture -from dirac_cwl.commands import UploadLogFile +from dirac_cwl.commands import BookeepingReport, UploadLogFile + + +def prepare_XMLSummary_file(xml_summary, content): + """Pepares a xml summary file and returns it as a class.""" + with open(xml_summary, "w", encoding="utf-8") as f: + f.write(content) + return XMLSummary(xml_summary) + + +def get_typed_parameter_value(name, root): + """Find the value of a specific TypedParameter by its name.""" + for child in root: + if child.tag == "TypedParameter" and child.attrib["Name"] == name: + return child.attrib["Value"] + return None + + +def get_output_file_details(output_file): + """Extract details from an OutputFile element.""" + details = { + "Name": output_file.attrib["Name"], + "TypeName": output_file.attrib["TypeName"], + "Parameters": {}, + "Replicas": [], + } + + for elem in output_file: + if elem.tag == "Parameter": + details["Parameters"][elem.attrib["Name"]] = elem.attrib["Value"] + elif elem.tag == "Replica": + details["Replicas"].append({"Name": elem.attrib["Name"], "Location": elem.attrib["Location"]}) + + return details class TestUploadLogFile: @@ -273,3 +314,436 @@ def test_failed_to_zip(self, basedir, mocker: MockerFixture): mock_set_app_status.assert_called_once_with("Failed to create zip of log files") mock_set_job_parameter.assert_not_called() + + +class TestBookkeepingReport: + """Collection of tests for the TestBookkeepingReport command.""" + + wms_job_id = 0 + job_type = "merge" + production_id = "123" + prod_job_id = "00000456" + event_type = "123456789" + number_of_events = "100" + config_name = "aConfigName" + config_version = "aConfigVersion" + application_name = "someApp" + application_version = "v1r0" + bk_step_id = "123" + command_id = "1" + number_of_processors = 1 + job_path = "." + + xml_summary_file = os.path.join( + job_path, f"summary{application_name}_{production_id}_{prod_job_id}_{command_id}.xml" + ) + wf_commons_file = os.path.join(job_path, "workflow_commons.json") + bookkeeping_file = os.path.join(job_path, f"bookkeeping_{command_id}.xml") + + @pytest.fixture + def wf_commons(self): + """Workflow Commons dictionary fixture.""" + content = { + "job_id": self.wms_job_id, + "job_type": self.job_type, + "production_id": self.production_id, + "prod_job_id": self.prod_job_id, + "event_type": self.event_type, + "number_of_events": self.number_of_events, + "config_name": self.config_name, + "config_version": self.config_version, + "application_name": self.application_name, + "application_version": self.application_version, + "bk_step_id": self.bk_step_id, + "inputs": [], + "outputs": [], + "executable": "", + "command_id": self.command_id, + "command_number": 1, + } + + yield content + + @pytest.fixture + def bk_report(self, mocker): + """BookkeepingReport mocked command. + + Cleans created files after execution. + """ + mock_get_n_procs = mocker.patch("dirac_cwl.commands.bookkeeping_report.getNumberOfProcessorsToUse") + + mock_get_n_procs.return_value = self.number_of_processors + + yield BookeepingReport() + + Path(self.wf_commons_file).unlink(missing_ok=True) + Path(self.bookkeeping_file).unlink(missing_ok=True) + Path(self.xml_summary_file).unlink(missing_ok=True) + + Path("00209455_00001537_1").unlink(missing_ok=True) + Path("00209455_00001537_1.sim").unlink(missing_ok=True) + + def test_bkreport_prod_mcsimulation_success(self, bk_report, wf_commons): + """Test successful execution of BookkeepingReport module.""" + wf_commons["application_name"] = "Gauss" + wf_commons["application_version"] = self.application_version + wf_commons["job_type"] = "MCSimulation" + + wf_commons["bookkeeping_LFNs"] = [ + "/lhcb/LHCb/Collision16/SIM/00209455/0000/00209455_00001537_1.sim", + ] + wf_commons["production_output_data"] = [ + "/lhcb/LHCb/Collision16/SIM/00209455/0000/00209455_00001537_1.sim", + ] + + wf_commons["start_time"] = time.time() - 1000 + + # Input data should be None as we use Gauss (MCSimulation) + wf_commons["outputs"] = [ + {"outputDataName": "00209455_00001537_1.sim", "outputDataType": "sim"}, + ] + Path(wf_commons["outputs"][0]["outputDataName"]).touch() + + # Mock the XMLSummary object + xml_content = dedent("""\ + + + True + finalize + + 2129228.0 + + + + + 1 + + + + 1 + 77 + 2644 + 6262 + 8391 + 963 + 18139 + 45169 + 52237 + 79 + + + + """) + + wf_commons["xml_summary_path"] = self.xml_summary_file + xf_o = prepare_XMLSummary_file(self.xml_summary_file, xml_content) + + with open(self.wf_commons_file, "w", encoding="utf-8") as f: + json.dump(wf_commons, f) + + # Execute the module + bk_report.execute(self.job_path) + + xml_path = self.bookkeeping_file + assert Path(xml_path).exists(), "XML report file not created." + + # Validate the XML file + tree = ET.parse(xml_path) + root = tree.getroot() + + # Extract fields from the XML and perform further operations + assert root.tag == "Job", "Root tag should be Job." + assert root.attrib["ConfigName"] == self.config_name + assert root.attrib["ConfigVersion"] == self.config_version + assert root.attrib["Date"] + assert root.attrib["Time"] + + assert get_typed_parameter_value("ProgramName", root) == wf_commons["application_name"] + assert get_typed_parameter_value("ProgramVersion", root) == wf_commons["application_version"] + assert get_typed_parameter_value("DiracVersion", root) == LHCbDIRAC.__version__ + assert get_typed_parameter_value("Name", root) == self.command_id + assert float(get_typed_parameter_value("ExecTime", root)) > 1000 + assert get_typed_parameter_value("CPUTIME", root) == "0" + + assert get_typed_parameter_value("FirstEventNumber", root) == "1" + assert get_typed_parameter_value("StatisticsRequested", root) == str(wf_commons["number_of_events"]) + assert get_typed_parameter_value("NumberOfEvents", root) == str(xf_o.outputEventsTotal) + + assert get_typed_parameter_value("Production", root) == self.production_id + assert get_typed_parameter_value("DiracJobId", root) == str(self.wms_job_id) + assert get_typed_parameter_value("Location", root) == siteName() + assert get_typed_parameter_value("JobStart", root) + assert get_typed_parameter_value("JobEnd", root) + assert get_typed_parameter_value("JobType", root) == wf_commons["job_type"] + + assert get_typed_parameter_value("WorkerNode", root) + assert get_typed_parameter_value("WNMEMORY", root) + assert get_typed_parameter_value("WNCPUPOWER", root) + assert get_typed_parameter_value("WNMODEL", root) + assert get_typed_parameter_value("WNCACHE", root) + assert get_typed_parameter_value("WNCPUHS06", root) + assert get_typed_parameter_value("NumberOfProcessors", root) == str(self.number_of_processors) + + # Input should be empty + input_file = root.find("InputFile") + assert input_file is None, "InputFile element should not be present." + + # Output should not be empty + output_files = root.findall("OutputFile") + assert output_files, "No OutputFile elements found." + + first_output_details = get_output_file_details(output_files[0]) + assert first_output_details["Name"] == wf_commons["production_output_data"][0] + assert first_output_details["TypeName"] == "SIM" + assert first_output_details["Parameters"]["FileSize"] == "0" + assert "CreationDate" in first_output_details["Parameters"] + assert "MD5Sum" in first_output_details["Parameters"] + assert "Guid" in first_output_details["Parameters"] + + assert len(output_files) == 1 + + def test_bkreport_prod_mcsimulation_noinputoutput_success(self, bk_report, wf_commons): + """Test successful execution of BookkeepingReport module. + + * No input files because wf_commons["stepInputData is empty + * No output files because wf_commons["stepOutputData is empty + * No pool xml catalog + * Simulation conditions because the application used is Gauss + """ + # Mock the BookkeepingReport module + wf_commons["application_name"] = "Gauss" + wf_commons["application_version"] = self.application_version + wf_commons["job_type"] = "MCSimulation" + + # This was obtained from a previous module (likely GaudiApplication) + wf_commons["bookkeeping_LFNs"] = [ + "/lhcb/LHCb/Collision16/SIM/00209455/0000/00209455_00001537_1", + ] + wf_commons["production_output_data"] = [ + "/lhcb/LHCb/Collision16/SIM/00209455/0000/00209455_00001537_1", + ] + + wf_commons["start_time"] = time.time() - 1000 + + # Mock the XMLSummary object + xml_content = dedent("""\ + + + True + finalize + + 2129228.0 + + + + + 1 + + + + 1 + 77 + 2644 + 6262 + 8391 + 963 + 18139 + 45169 + 52237 + 79 + + + + """) + + wf_commons["xml_summary_path"] = self.xml_summary_file + xf_o = prepare_XMLSummary_file(self.xml_summary_file, xml_content) + + with open(self.wf_commons_file, "w", encoding="utf-8") as f: + json.dump(wf_commons, f) + + # Execute the module + bk_report.execute(self.job_path) + + # Check if the XML report file is created + xml_path = self.bookkeeping_file + assert Path(xml_path).exists(), "XML report file not created." + + # Validate the XML file + tree = ET.parse(xml_path) + root = tree.getroot() + + # Extract fields from the XML and perform further operations + assert root.tag == "Job", "Root tag should be Job." + assert root.attrib["ConfigName"] == self.config_name + assert root.attrib["ConfigVersion"] == self.config_version + assert root.attrib["Date"] + assert root.attrib["Time"] + + assert get_typed_parameter_value("ProgramName", root) == wf_commons["application_name"] + assert get_typed_parameter_value("ProgramVersion", root) == wf_commons["application_version"] + assert get_typed_parameter_value("DiracVersion", root) == LHCbDIRAC.__version__ + assert get_typed_parameter_value("Name", root) == self.command_id + assert float(get_typed_parameter_value("ExecTime", root)) > 1000 + assert get_typed_parameter_value("CPUTIME", root) == "0" + + assert get_typed_parameter_value("FirstEventNumber", root) == "1" + assert get_typed_parameter_value("StatisticsRequested", root) == str(wf_commons["number_of_events"]) + assert get_typed_parameter_value("NumberOfEvents", root) == str(xf_o.outputEventsTotal) + + assert get_typed_parameter_value("Production", root) == self.production_id + assert get_typed_parameter_value("DiracJobId", root) == str(self.wms_job_id) + assert get_typed_parameter_value("Location", root) == siteName() + assert get_typed_parameter_value("JobStart", root) + assert get_typed_parameter_value("JobEnd", root) + assert get_typed_parameter_value("JobType", root) == wf_commons["job_type"] + + assert get_typed_parameter_value("WorkerNode", root) + assert get_typed_parameter_value("WNMEMORY", root) + assert get_typed_parameter_value("WNCPUPOWER", root) + assert get_typed_parameter_value("WNMODEL", root) + assert get_typed_parameter_value("WNCACHE", root) + assert get_typed_parameter_value("WNCPUHS06", root) + assert get_typed_parameter_value("NumberOfProcessors", root) == str(self.number_of_processors) + + # Input should be empty + input_file = root.find("InputFile") + assert input_file is None, "InputFile element should not be present." + + # Output should be empty + output_file = root.find("OutputFile") + assert output_file is None, "OutputFile element should not be present." + + def test_bk_report_prod_mcreconstruction_success(self, bk_report, wf_commons): + """Test successful execution of BookkeepingReport module.""" + wf_commons["application_name"] = "Boole" + wf_commons["application_version"] = self.application_version + wf_commons["job_type"] = "MCReconstruction" + + wf_commons["bookkeeping_LFNs"] = [ + "/lhcb/LHCb/Collision16/SIM/00209455/0000/00209455_00001537_1", + ] + wf_commons["log_file_path"] = "/lhcb/LHCb/Collision16/LOG/00209455/0000/" + wf_commons["production_output_data"] = [ + "/lhcb/LHCb/Collision16/SIM/00209455/0000/00209455_00001537_1", + ] + + wf_commons["start_time"] = time.time() - 1000 + + wf_commons["inputs"] = ["/lhcb/MC/2018/SIM/00212581/0000/00212581_00001446_1.sim"] + wf_commons["outputs"] = [ + {"outputDataName": "00209455_00001537_1", "outputDataType": "digi"}, + ] + wf_commons["application_log"] = "application.log" + Path(wf_commons["application_log"]).touch() + Path(wf_commons["outputs"][0]["outputDataName"]).touch() + + # Mock the XMLSummary object + xml_content = dedent("""\ + + + True + finalize + + 866104.0 + + + 200 + + + 200 + + + """) + + wf_commons["xml_summary_path"] = self.xml_summary_file + + xf_o = prepare_XMLSummary_file(self.xml_summary_file, xml_content) + + with open(self.wf_commons_file, "w", encoding="utf-8") as f: + json.dump(wf_commons, f) + + # Execute the module + bk_report.execute(self.job_path) + + # Check if the XML report file is created + xml_path = self.bookkeeping_file + assert Path(xml_path).exists(), "XML report file not created." + + # Validate the XML file + tree = ET.parse(xml_path) + root = tree.getroot() + + # Extract fields from the XML and perform further operations + assert root.tag == "Job", "Root tag should be Job." + assert root.attrib["ConfigName"] == self.config_name + assert root.attrib["ConfigVersion"] == self.config_version + assert root.attrib["Date"] + assert root.attrib["Time"] + + assert get_typed_parameter_value("ProgramName", root) == wf_commons["application_name"] + assert get_typed_parameter_value("ProgramVersion", root) == wf_commons["application_version"] + assert get_typed_parameter_value("DiracVersion", root) == LHCbDIRAC.__version__ + assert get_typed_parameter_value("Name", root) == self.command_id + assert float(get_typed_parameter_value("ExecTime", root)) > 1000 + assert get_typed_parameter_value("CPUTIME", root) == "0" + + assert get_typed_parameter_value("FirstEventNumber", root) == "1" + assert get_typed_parameter_value("StatisticsRequested", root) == str(wf_commons["number_of_events"]) + assert get_typed_parameter_value("NumberOfEvents", root) == str(xf_o.inputEventsTotal) + + assert get_typed_parameter_value("Production", root) == self.production_id + assert get_typed_parameter_value("DiracJobId", root) == str(self.wms_job_id) + assert get_typed_parameter_value("Location", root) == siteName() + assert get_typed_parameter_value("JobStart", root) + assert get_typed_parameter_value("JobEnd", root) + assert get_typed_parameter_value("JobType", root) == wf_commons["job_type"] + + assert get_typed_parameter_value("WorkerNode", root) + assert get_typed_parameter_value("WNMEMORY", root) + assert get_typed_parameter_value("WNCPUPOWER", root) + assert get_typed_parameter_value("WNMODEL", root) + assert get_typed_parameter_value("WNCACHE", root) + assert get_typed_parameter_value("WNCPUHS06", root) + assert get_typed_parameter_value("NumberOfProcessors", root) == str(self.number_of_processors) + + # Input should not be empty + input_file = root.find("InputFile") + assert input_file is not None, "InputFile element should be present." + + # Output should not be empty + output_files = root.findall("OutputFile") + assert output_files, "No OutputFile elements found." + + first_output_details = get_output_file_details(output_files[0]) + assert first_output_details["Name"] == wf_commons["production_output_data"][0] + assert first_output_details["TypeName"] == "DIGI" + assert first_output_details["Parameters"]["FileSize"] == "0" + assert "CreationDate" in first_output_details["Parameters"] + assert "MD5Sum" in first_output_details["Parameters"] + assert "Guid" in first_output_details["Parameters"] + + assert len(output_files) == 1 + + # Because we are using Gauss, sim conditions should be present too + simulation_condition = root.find("SimulationCondition") + assert simulation_condition is None, "SimulationCondition element should not be present." + + def test_bkreport_previousError_success(self, mocker, bk_report, wf_commons): + """.""" + wf_commons["application_name"] = "Gauss" + wf_commons["application_version"] = self.config_version + wf_commons["job_type"] = "MCSimulation" + wf_commons["step_status"] = S_ERROR() + + with open(self.wf_commons_file, "w", encoding="utf-8") as f: + json.dump(wf_commons, f) + + bk_report.execute(self.job_path) + + assert not os.path.exists(self.bookkeeping_file) From 1da58a2a5cabc163cb5099da3e36e2467f51c9af Mon Sep 17 00:00:00 2001 From: Jorge Lisa <64639359+AcquaDiGiorgio@users.noreply.github.com> Date: Mon, 27 Apr 2026 16:50:21 +0200 Subject: [PATCH 07/21] chore: set lhcbdirac dependency to https instead of ssh --- pixi.lock | 14 +++++++------- pyproject.toml | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/pixi.lock b/pixi.lock index 31fec78..127cd49 100644 --- a/pixi.lock +++ b/pixi.lock @@ -187,7 +187,7 @@ environments: - pypi: https://files.pythonhosted.org/packages/6d/10/b37ac718c5903758fa9058a5182026a4f3b65443196b82c7840389ea0dbd/lbplatformutils-4.6.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/02/64/c86924898062e8217ed914a29458cfde9e4a9b80e4d4cbcca141983ba339/lbprodrun-1.12.4-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/29/ce/ed422816fb30ffa3bc11597b30d5deca06b4a1388707a04215da73c65b53/levenshtein-0.27.3-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl - - pypi: git+ssh://git@gitlab.cern.ch:7999/jlisalab/LHCbDIRAC.git?rev=modules-to-cwl-migration#c441175f3289d6d85abf5d5612c3ff964edd9a5c + - pypi: git+https://gitlab.cern.ch/jlisalab/LHCbDIRAC.git?rev=modules-to-cwl-migration#c441175f3289d6d85abf5d5612c3ff964edd9a5c - pypi: https://files.pythonhosted.org/packages/7f/37/8ea3555769b6048b5e4ec162cc90fd32e761c0e381ffb3baf888cb0d8a71/lhcbdiracx_api-0.0.8-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/68/15/bfb0c717b8f23c16907f3e73e8f56010ccd72e9900a108209665b0d9ed4b/lhcbdiracx_cli-0.0.8-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/2d/88/67602dfa2d7ab5d0518af82db34ab4d70dc2c3029b3ca788299a3be4a96d/lhcbdiracx_client-0.0.8-py3-none-any.whl @@ -429,7 +429,7 @@ environments: - pypi: https://files.pythonhosted.org/packages/6d/10/b37ac718c5903758fa9058a5182026a4f3b65443196b82c7840389ea0dbd/lbplatformutils-4.6.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/02/64/c86924898062e8217ed914a29458cfde9e4a9b80e4d4cbcca141983ba339/lbprodrun-1.12.4-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/f3/e1/2f705da403f865a5fa3449b155738dc9c53021698fd6926253a9af03180b/levenshtein-0.27.3-cp314-cp314-macosx_10_15_x86_64.whl - - pypi: git+ssh://git@gitlab.cern.ch:7999/jlisalab/LHCbDIRAC.git?rev=modules-to-cwl-migration#c441175f3289d6d85abf5d5612c3ff964edd9a5c + - pypi: git+https://gitlab.cern.ch/jlisalab/LHCbDIRAC.git?rev=modules-to-cwl-migration#c441175f3289d6d85abf5d5612c3ff964edd9a5c - pypi: https://files.pythonhosted.org/packages/7f/37/8ea3555769b6048b5e4ec162cc90fd32e761c0e381ffb3baf888cb0d8a71/lhcbdiracx_api-0.0.8-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/68/15/bfb0c717b8f23c16907f3e73e8f56010ccd72e9900a108209665b0d9ed4b/lhcbdiracx_cli-0.0.8-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/2d/88/67602dfa2d7ab5d0518af82db34ab4d70dc2c3029b3ca788299a3be4a96d/lhcbdiracx_client-0.0.8-py3-none-any.whl @@ -670,7 +670,7 @@ environments: - pypi: https://files.pythonhosted.org/packages/6d/10/b37ac718c5903758fa9058a5182026a4f3b65443196b82c7840389ea0dbd/lbplatformutils-4.6.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/02/64/c86924898062e8217ed914a29458cfde9e4a9b80e4d4cbcca141983ba339/lbprodrun-1.12.4-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/76/2c/bb6ef359e007fe7b6b3195b68a94f4dd3ecd1885ee337ee8fbd4df55996f/levenshtein-0.27.3-cp314-cp314-macosx_11_0_arm64.whl - - pypi: git+ssh://git@gitlab.cern.ch:7999/jlisalab/LHCbDIRAC.git?rev=modules-to-cwl-migration#c441175f3289d6d85abf5d5612c3ff964edd9a5c + - pypi: git+https://gitlab.cern.ch/jlisalab/LHCbDIRAC.git?rev=modules-to-cwl-migration#c441175f3289d6d85abf5d5612c3ff964edd9a5c - pypi: https://files.pythonhosted.org/packages/7f/37/8ea3555769b6048b5e4ec162cc90fd32e761c0e381ffb3baf888cb0d8a71/lhcbdiracx_api-0.0.8-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/68/15/bfb0c717b8f23c16907f3e73e8f56010ccd72e9900a108209665b0d9ed4b/lhcbdiracx_cli-0.0.8-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/2d/88/67602dfa2d7ab5d0518af82db34ab4d70dc2c3029b3ca788299a3be4a96d/lhcbdiracx_client-0.0.8-py3-none-any.whl @@ -1639,8 +1639,8 @@ packages: requires_python: '>=3.11' - pypi: ./ name: dirac-cwl - version: 1.2.1.dev8+g8317c9f76.d20260427 - sha256: 827f00c9f462c00995c99046a12618a97b94bd8085f0ea7fadb6faeaabb7c002 + version: 1.2.1.dev10+g98ccc37b9.d20260427 + sha256: e52448240772253ac6d1e1fda93951e71a3743146d125eac2c495619f14b3b5d requires_dist: - cwl-utils - cwlformat @@ -1651,7 +1651,7 @@ packages: - diracx-client>=0.0.8 - diracx-cli>=0.0.8 - lbprodrun - - lhcbdirac @ git+ssh://git@gitlab.cern.ch:7999/jlisalab/LHCbDIRAC.git@modules-to-cwl-migration + - lhcbdirac @ git+https://****@gitlab.cern.ch/jlisalab/LHCbDIRAC.git@modules-to-cwl-migration - pydantic - pyyaml - typer @@ -2668,7 +2668,7 @@ packages: requires_dist: - rapidfuzz>=3.9.0,<4.0.0 requires_python: '>=3.10' -- pypi: git+ssh://git@gitlab.cern.ch:7999/jlisalab/LHCbDIRAC.git?rev=modules-to-cwl-migration#c441175f3289d6d85abf5d5612c3ff964edd9a5c +- pypi: git+https://gitlab.cern.ch/jlisalab/LHCbDIRAC.git?rev=modules-to-cwl-migration#c441175f3289d6d85abf5d5612c3ff964edd9a5c name: lhcbdirac version: 0.1.dev20447+gc441175f3 requires_dist: diff --git a/pyproject.toml b/pyproject.toml index f31a72c..9cdbd79 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -31,7 +31,7 @@ dependencies = [ "diracx-client>=0.0.8", "diracx-cli>=0.0.8", "lbprodrun", - "LHCbDIRAC @ git+ssh://git@gitlab.cern.ch:7999/jlisalab/LHCbDIRAC.git@modules-to-cwl-migration", # Temporary fork dependency + "LHCbDIRAC @ git+https://git@gitlab.cern.ch/jlisalab/LHCbDIRAC.git@modules-to-cwl-migration", # Temporary fork dependency "pydantic", "pyyaml", "typer", From 4586f84efc520bf5f9034ee98760920050b11cee Mon Sep 17 00:00:00 2001 From: Jorge Lisa <64639359+AcquaDiGiorgio@users.noreply.github.com> Date: Tue, 28 Apr 2026 09:27:26 +0200 Subject: [PATCH 08/21] chore: remove all DIRAC import mypy type checking --- pixi.lock | 4 ++-- pyproject.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pixi.lock b/pixi.lock index 127cd49..8884ad2 100644 --- a/pixi.lock +++ b/pixi.lock @@ -1639,8 +1639,8 @@ packages: requires_python: '>=3.11' - pypi: ./ name: dirac-cwl - version: 1.2.1.dev10+g98ccc37b9.d20260427 - sha256: e52448240772253ac6d1e1fda93951e71a3743146d125eac2c495619f14b3b5d + version: 1.2.1.dev11+g1da58a2a5.d20260428 + sha256: 6b2880b8b3e1502d70cfb2bf1823439ef595fe963b873bb23ef101a9cae108f2 requires_dist: - cwl-utils - cwlformat diff --git a/pyproject.toml b/pyproject.toml index 9cdbd79..dbc0eb4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -79,7 +79,7 @@ allow_redefinition = true enable_error_code = ["import", "attr-defined"] [[tool.mypy.overrides]] -module = ["requests", "yaml"] +module = ["requests", "yaml", "DIRAC.*", "LHCbDIRAC.*", "DIRACCommon.*"] ignore_missing_imports = true [tool.pytest.ini_options] From 0ad8e0e484eff1cf2811f021864c64b73eb32124 Mon Sep 17 00:00:00 2001 From: Jorge Lisa <64639359+AcquaDiGiorgio@users.noreply.github.com> Date: Mon, 4 May 2026 11:17:31 +0200 Subject: [PATCH 09/21] feat: Migrate FailoverRequest command to cwl-dirac --- src/dirac_cwl/commands/__init__.py | 3 +- src/dirac_cwl/commands/failover_request.py | 112 ++++++++ src/dirac_cwl/commands/utils.py | 28 ++ test/test_commands.py | 285 ++++++++++++++++++++- 4 files changed, 425 insertions(+), 3 deletions(-) create mode 100644 src/dirac_cwl/commands/failover_request.py diff --git a/src/dirac_cwl/commands/__init__.py b/src/dirac_cwl/commands/__init__.py index 7367a47..1af50a8 100644 --- a/src/dirac_cwl/commands/__init__.py +++ b/src/dirac_cwl/commands/__init__.py @@ -2,6 +2,7 @@ from .bookkeeping_report import BookeepingReport from .core import PostProcessCommand, PreProcessCommand +from .failover_request import FailoverRequest from .upload_log_file import UploadLogFile -__all__ = ["PreProcessCommand", "PostProcessCommand", "UploadLogFile", "BookeepingReport"] +__all__ = ["PreProcessCommand", "PostProcessCommand", "UploadLogFile", "BookeepingReport", "FailoverRequest"] diff --git a/src/dirac_cwl/commands/failover_request.py b/src/dirac_cwl/commands/failover_request.py new file mode 100644 index 0000000..005db7a --- /dev/null +++ b/src/dirac_cwl/commands/failover_request.py @@ -0,0 +1,112 @@ +"""LHCb command for committing the status of the files in the file report. + +The status will be "Processed" if everything ended properly or "Unused" if it did not. +""" + +import json +import os + +from DIRAC.AccountingSystem.Client.DataStoreClient import DataStoreClient +from DIRAC.RequestManagementSystem.Client.Request import Request +from DIRAC.RequestManagementSystem.private.RequestValidator import RequestValidator +from DIRAC.TransformationSystem.Client.FileReport import FileReport +from DIRAC.WorkloadManagementSystem.Client.JobReport import JobReport +from LHCbDIRAC.Workflow.Modules.FailoverRequest import _prepareRequest + +from dirac_cwl.core.exceptions import WorkflowProcessingException + +from .core import PostProcessCommand +from .utils import prepare_lhcb_workflow_commons, save_workflow_commons + + +class FailoverRequest(PostProcessCommand): + """Commits the status of the files in the file report. + + The status will be "Processed" if everything ended properly or "Unused" if it did not. + """ + + def execute(self, job_path, **kwargs): + """Execute the command. + + :param job_path: Path to the job working directory. + :param kwargs: Additional keyword arguments. + """ + workflow_commons_path = kwargs.get("workflow-commons-path", os.path.join(job_path, "workflow_commons.json")) + + workflow_commons = prepare_lhcb_workflow_commons( + workflow_commons_path, + extra_mandatory_values=[], + extra_default_values={ + "request_dict": None, + "file_report_files_dict": {}, + "accounting_registers": {}, + }, + ) + + request = Request(workflow_commons["request_dict"]) + file_report = FileReport() + file_report.statusDict = workflow_commons["file_report_files_dict"] + + job_report = JobReport(workflow_commons["job_id"]) + + _prepareRequest(request, workflow_commons["job_id"]) + + filesInFileReport = file_report.getFiles() + + for lfn in workflow_commons["inputs"]: + if lfn not in filesInFileReport: + status = "Processed" if workflow_commons["step_status"]["OK"] else "Unused" + file_report.setFileStatus(int(workflow_commons["production_id"]), lfn, status) + + file_report.commit() + + if workflow_commons["step_status"]["OK"]: + if file_report.getFiles(): + result = file_report.generateForwardDISET() + if result["OK"] and result["Value"]: + request.addOperation(result["Value"]) + + job_report.setApplicationStatus("Job Finished Successfully", True) + + self.generateFailoverFile(job_report, request, workflow_commons) + + workflow_commons["request_dict"] = json.loads(request.toJSON()["Value"]) + save_workflow_commons(workflow_commons, workflow_commons_path) + + def generateFailoverFile(self, job_report, request, workflow_commons): + """Create a request.json file.""" + result = job_report.generateForwardDISET() + + if result["OK"]: + if result["Value"]: + request.addOperation(result["Value"]) + + if len(request): + # Try to optimize the request + try: + request.optimize() + except: # noqa: E722 + pass + + # Validate request + result = RequestValidator().validate(request) + if not result["OK"]: + raise WorkflowProcessingException( + "Failed to generate FailoverFile. Invalid request object", result["Message"] + ) + + # Get the request as a Json + result = request.toJSON() + if not result["OK"]: + raise WorkflowProcessingException(result["Message"]) + + # Write it + fname = f"{workflow_commons['production_id']}_{workflow_commons['prod_job_id']}_request.json" + with open(fname, "w", encoding="utf-8") as f: + json.dump(result["Value"], f) + + if workflow_commons["accounting_registers"]: + dsc = DataStoreClient() + for register in workflow_commons["accounting_registers"]: + dsc.addRegister(register) + dsc.commit() diff --git a/src/dirac_cwl/commands/utils.py b/src/dirac_cwl/commands/utils.py index 917a71e..30ed69e 100644 --- a/src/dirac_cwl/commands/utils.py +++ b/src/dirac_cwl/commands/utils.py @@ -2,6 +2,7 @@ import json import os +import shutil from DIRAC import siteName from DIRAC.Core.Utilities.ReturnValues import S_OK @@ -90,3 +91,30 @@ def prepare_lhcb_workflow_commons(workflow_commons_path, extra_mandatory_values= workflow_commons["site_name"] = siteName() return workflow_commons + + +def save_workflow_commons(wf_commons, wf_file_path): + """Update the workflow_commons file to accomodate for the new values. + + Ensures that no data is lost during the update by creating a backup. + """ + if not (os.path.exists(wf_file_path) and os.path.isfile(wf_file_path)): + raise WorkflowProcessingException("") + + wf_filename = os.path.basename(wf_file_path) + wf_backup = f"{wf_filename}.bak" + + shutil.move(wf_file_path, wf_backup) + + try: + with open(wf_file_path, "x", encoding="utf-8") as f: + json.dump(wf_commons, f) + except Exception: + os.unlink(wf_file_path) + shutil.copy2(wf_backup, wf_file_path) + return False + + finally: + os.unlink(wf_backup) + + return True diff --git a/test/test_commands.py b/test/test_commands.py index 2569c06..39f2c23 100644 --- a/test/test_commands.py +++ b/test/test_commands.py @@ -12,11 +12,42 @@ import LHCbDIRAC import pytest from DIRAC import siteName +from DIRAC.TransformationSystem.Client.FileReport import FileReport +from DIRAC.WorkloadManagementSystem.Client.JobReport import JobReport from DIRACCommon.Core.Utilities.ReturnValues import S_ERROR, S_OK from LHCbDIRAC.Core.Utilities.XMLSummaries import XMLSummary from pytest_mock import MockerFixture -from dirac_cwl.commands import BookeepingReport, UploadLogFile +from dirac_cwl.commands import BookeepingReport, FailoverRequest, UploadLogFile + +wf_commons = { + "job_id": 0, + "job_type": "merge", + "production_id": "123", + "prod_job_id": "00000456", + "event_type": "123456789", + "number_of_events": "100", + "config_name": "aConfigName", + "config_version": "aConfigVersion", + "application_name": "someApp", + "application_version": "v1r0", + "bk_step_id": "123", + "inputs": [], + "outputs": [], + "executable": "", + "command_id": "1", + "command_number": 1, +} + +number_of_processors = 1 +job_path = "." +xml_summary_file = os.path.join( + job_path, + f"summary{wf_commons['application_name']}_{wf_commons['production_id']}_{wf_commons['prod_job_id']}_{wf_commons['command_id']}.xml", +) +wf_commons_file = os.path.join(job_path, "workflow_commons.json") +bookkeeping_file = os.path.join(job_path, f"bookkeeping_{wf_commons['command_id']}.xml") +request_file = f"{wf_commons['production_id']}_{wf_commons['prod_job_id']}_request.json" def prepare_XMLSummary_file(xml_summary, content): @@ -735,7 +766,7 @@ def test_bk_report_prod_mcreconstruction_success(self, bk_report, wf_commons): assert simulation_condition is None, "SimulationCondition element should not be present." def test_bkreport_previousError_success(self, mocker, bk_report, wf_commons): - """.""" + """Test previous command failure.""" wf_commons["application_name"] = "Gauss" wf_commons["application_version"] = self.config_version wf_commons["job_type"] = "MCSimulation" @@ -747,3 +778,253 @@ def test_bkreport_previousError_success(self, mocker, bk_report, wf_commons): bk_report.execute(self.job_path) assert not os.path.exists(self.bookkeeping_file) + + +class TestFailoverRequest: + """Collection of tests for the FailoverRequest command.""" + + @pytest.fixture + def failover_request(self, mocker: MockerFixture): + """FailoverRequest mocked command. + + Cleans created files after execution. + """ + mocker.patch("dirac_cwl.commands.failover_request.RequestValidator") + + yield FailoverRequest() + + Path(request_file).unlink(missing_ok=True) + Path(wf_commons_file).unlink(missing_ok=True) + + def test_failoverRequest_success(self, mocker: MockerFixture, failover_request): + """Test successful execution of FailoverRequest module.""" + problematic_files = [ + "/lhcb/data/2010/EW.DST/00008380/0000/00008380_00000287_1.ew.dst", + ] + + mock_file_report = mocker.patch("dirac_cwl.commands.failover_request.FileReport") + mock_job_report = mocker.patch("dirac_cwl.commands.failover_request.JobReport") + + fr = FileReport() + mocker.patch.object(fr, "getFiles", side_effect=[problematic_files, []]) + mocker.patch.object(fr, "commit", return_value=S_OK("Anything")) + mocker.patch.object(fr, "setFileStatus") + mock_file_report.return_value = fr + + jr = JobReport(wf_commons["job_id"]) + mocker.patch.object(jr, "setApplicationStatus") + mock_job_report.return_value = jr + + wf_commons["inputs"] = [ + "/lhcb/data/2010/EW.DST/00008380/0000/00008380_00000281_1.ew.dst", + "/lhcb/data/2011/EW.DST/00008380/0000/00008380_00000281_1.ew.dst", + ] + problematic_files + + with open(wf_commons_file, "w", encoding="utf-8") as f: + json.dump(wf_commons, f) + + failover_request.execute(job_path) + + with open(wf_commons_file, "r", encoding="utf-8") as f: + updated_wf_commons = json.load(f) + + # Check the FileReport calls: the problematic file should not appear + # The input files should be set to "Processed" + assert fr.setFileStatus.call_count == 2 + args = fr.setFileStatus.call_args_list + assert args[0][0][0] == int(updated_wf_commons["production_id"]) + assert args[0][0][1] == updated_wf_commons["inputs"][0] + assert args[0][0][2] == "Processed" + + assert args[1][0][0] == int(updated_wf_commons["production_id"]) + assert args[1][0][1] == updated_wf_commons["inputs"][1] + assert args[1][0][2] == "Processed" + + # Make sure the appliction is successfully finished + assert jr.setApplicationStatus.call_count == 1 + assert jr.setApplicationStatus.call_args[0][0] == "Job Finished Successfully" + + print(updated_wf_commons) + # Make sure the forward DISET is not generated + operations = updated_wf_commons["request_dict"]["Operations"] + assert len(operations) == 0 + + # Make sure the request json does not exists + assert not Path(request_file).exists() + + def test_failoverRequest_commitFailure1(self, mocker: MockerFixture, failover_request): + """Test execution of FailoverRequest module when the fileReport.commit() fails. + + In this context, the second call to commit() will work, so the request should not be generated. + """ + problematic_files = [ + "/lhcb/data/2010/EW.DST/00008380/0000/00008380_00000287_1.ew.dst", + ] + # Both calla to getFiles() will return the problematic files because the commit did not work + mock_file_report = mocker.patch("dirac_cwl.commands.failover_request.FileReport") + mock_job_report = mocker.patch("dirac_cwl.commands.failover_request.JobReport") + + jr = JobReport(wf_commons["job_id"]) + mocker.patch.object(jr, "setApplicationStatus") + mock_job_report.return_value = jr + + fr = FileReport() + mocker.patch.object(fr, "getFiles", side_effect=[problematic_files, problematic_files]) + mocker.patch.object(fr, "commit", side_effect=[S_ERROR("Error"), S_OK(None)]) + mocker.patch.object(fr, "setFileStatus") + mock_file_report.return_value = fr + + wf_commons["inputs"] = [ + "/lhcb/data/2010/EW.DST/00008380/0000/00008380_00000281_1.ew.dst", + "/lhcb/data/2011/EW.DST/00008380/0000/00008380_00000281_1.ew.dst", + ] + problematic_files + + # Execute the module + with open(wf_commons_file, "w", encoding="utf-8") as f: + json.dump(wf_commons, f) + + failover_request.execute(job_path) + + with open(wf_commons_file, "r", encoding="utf-8") as f: + updated_wf_commons = json.load(f) + + # Check the FileReport calls: the problematic file should not appear + # The input files should be set to "Processed" + assert fr.setFileStatus.call_count == 2 + args = fr.setFileStatus.call_args_list + assert args[0][0][0] == int(updated_wf_commons["production_id"]) + assert args[0][0][1] == updated_wf_commons["inputs"][0] + assert args[0][0][2] == "Processed" + + assert args[1][0][0] == int(updated_wf_commons["production_id"]) + assert args[1][0][1] == updated_wf_commons["inputs"][1] + assert args[1][0][2] == "Processed" + + # Make sure the appliction is successfully finished + assert jr.setApplicationStatus.call_count == 1 + assert jr.setApplicationStatus.call_args[0][0] == "Job Finished Successfully" + + # Make sure the forward DISET is generated + operations = updated_wf_commons["request_dict"]["Operations"] + assert len(operations) == 0 + + # Make sure the request json does not exists + assert not Path(request_file).exists() + + def test_failoverRequest_commitFailure2(self, mocker: MockerFixture, failover_request): + """Test execution of FailoverRequest module when the fileReport.commit() fails. + + In this context, the second call to commit() will fail, so the request should be generated. + """ + problematic_files = [ + "/lhcb/data/2010/EW.DST/00008380/0000/00008380_00000287_1.ew.dst", + ] + # Both calla to getFiles() will return the problematic files because the commit did not work + mock_file_report = mocker.patch("dirac_cwl.commands.failover_request.FileReport") + mock_job_report = mocker.patch("dirac_cwl.commands.failover_request.JobReport") + + fr = FileReport() + mocker.patch.object(fr, "getFiles", side_effect=[problematic_files, problematic_files]) + mocker.patch.object(fr, "commit", side_effect=[S_ERROR("Error"), S_ERROR("Error")]) + mocker.patch.object(fr, "setFileStatus") + mock_file_report.return_value = fr + + jr = JobReport(wf_commons["job_id"]) + mocker.patch.object(jr, "setApplicationStatus") + mock_job_report.return_value = jr + + wf_commons["inputs"] = [ + "/lhcb/data/2010/EW.DST/00008380/0000/00008380_00000281_1.ew.dst", + "/lhcb/data/2011/EW.DST/00008380/0000/00008380_00000281_1.ew.dst", + ] + problematic_files + + with open(wf_commons_file, "w", encoding="utf-8") as f: + json.dump(wf_commons, f) + + # Execute the module + failover_request.execute(job_path) + + with open(wf_commons_file, "r", encoding="utf-8") as f: + updated_wf_commons = json.load(f) + + # Check the FileReport calls: the problematic file should not appear + # The input files should be set to "Processed" + assert fr.setFileStatus.call_count == 2 + args = fr.setFileStatus.call_args_list + assert args[0][0][0] == int(updated_wf_commons["production_id"]) + assert args[0][0][1] == updated_wf_commons["inputs"][0] + assert args[0][0][2] == "Processed" + + assert args[1][0][0] == int(updated_wf_commons["production_id"]) + assert args[1][0][1] == updated_wf_commons["inputs"][1] + assert args[1][0][2] == "Processed" + + # Make sure the appliction is successfully finished + assert jr.setApplicationStatus.call_count == 1 + assert jr.setApplicationStatus.call_args[0][0] == "Job Finished Successfully" + + # Make sure the forward DISET is generated + operations = updated_wf_commons["request_dict"]["Operations"] + + assert len(operations) == 1 + assert operations[0]["Type"] == "SetFileStatus" + + # Make sure the request json does not exists + assert Path(request_file).exists() + + def test_failoverRequest_previousError_fail(self, mocker: MockerFixture, failover_request): + """Test FailoverRequest with an intentional failure.""" + problematic_files = [ + "/lhcb/data/2010/EW.DST/00008380/0000/00008380_00000287_1.ew.dst", + ] + mock_file_report = mocker.patch("dirac_cwl.commands.failover_request.FileReport") + mock_job_report = mocker.patch("dirac_cwl.commands.failover_request.JobReport") + + fr = FileReport() + mocker.patch.object(fr, "getFiles", side_effect=[problematic_files, problematic_files]) + mocker.patch.object(fr, "commit", side_effect=[S_ERROR("Error"), S_ERROR("Error")]) + mocker.patch.object(fr, "setFileStatus") + mock_file_report.return_value = fr + + jr = JobReport(wf_commons["job_id"]) + mocker.patch.object(jr, "setApplicationStatus") + mock_job_report.return_value = jr + + wf_commons["inputs"] = [ + "/lhcb/data/2010/EW.DST/00008380/0000/00008380_00000281_1.ew.dst", + "/lhcb/data/2011/EW.DST/00008380/0000/00008380_00000281_1.ew.dst", + ] + problematic_files + + # Intentional error + wf_commons["step_status"] = S_ERROR() + + with open(wf_commons_file, "w", encoding="utf-8") as f: + json.dump(wf_commons, f) + + # Execute the module + failover_request.execute(job_path) + + with open(wf_commons_file, "r", encoding="utf-8") as f: + updated_wf_commons = json.load(f) + + # Check the FileReport calls: the problematic file should not appear + # The input files should be set to "Unused" + assert fr.setFileStatus.call_count == 2 + args = fr.setFileStatus.call_args_list + assert args[0][0][0] == int(updated_wf_commons["production_id"]) + assert args[0][0][1] == updated_wf_commons["inputs"][0] + assert args[0][0][2] == "Unused" + + assert args[1][0][0] == int(updated_wf_commons["production_id"]) + assert args[1][0][1] == updated_wf_commons["inputs"][1] + assert args[1][0][2] == "Unused" + + # Make sure the appliction is not reported as a success + assert jr.setApplicationStatus.call_count == 0 + + # Make sure the forward DISET is not generated + operations = updated_wf_commons["request_dict"]["Operations"] + assert len(operations) == 0 + + # Make sure the request json does not exists + assert not Path(request_file).exists() From bd285c36e57cc2a39f1e0f698536d5a1dd8b4301 Mon Sep 17 00:00:00 2001 From: Jorge Lisa <64639359+AcquaDiGiorgio@users.noreply.github.com> Date: Mon, 4 May 2026 12:21:30 +0200 Subject: [PATCH 10/21] chore(tests): improve command fixtures --- test/test_commands.py | 243 ++++++++++++++++++++---------------------- 1 file changed, 117 insertions(+), 126 deletions(-) diff --git a/test/test_commands.py b/test/test_commands.py index 39f2c23..50949a0 100644 --- a/test/test_commands.py +++ b/test/test_commands.py @@ -20,34 +20,58 @@ from dirac_cwl.commands import BookeepingReport, FailoverRequest, UploadLogFile -wf_commons = { - "job_id": 0, - "job_type": "merge", - "production_id": "123", - "prod_job_id": "00000456", - "event_type": "123456789", - "number_of_events": "100", - "config_name": "aConfigName", - "config_version": "aConfigVersion", - "application_name": "someApp", - "application_version": "v1r0", - "bk_step_id": "123", - "inputs": [], - "outputs": [], - "executable": "", - "command_id": "1", - "command_number": 1, -} - number_of_processors = 1 job_path = "." -xml_summary_file = os.path.join( - job_path, - f"summary{wf_commons['application_name']}_{wf_commons['production_id']}_{wf_commons['prod_job_id']}_{wf_commons['command_id']}.xml", -) -wf_commons_file = os.path.join(job_path, "workflow_commons.json") -bookkeeping_file = os.path.join(job_path, f"bookkeeping_{wf_commons['command_id']}.xml") -request_file = f"{wf_commons['production_id']}_{wf_commons['prod_job_id']}_request.json" + + +@pytest.fixture +def wf_commons(): + """Workflow commons dictionary fixture.""" + yield { + "job_id": 0, + "job_type": "merge", + "production_id": "123", + "prod_job_id": "00000456", + "event_type": "123456789", + "number_of_events": "100", + "config_name": "aConfigName", + "config_version": "aConfigVersion", + "application_name": "someApp", + "application_version": "v1r0", + "bk_step_id": "123", + "inputs": [], + "outputs": [], + "executable": "", + "command_id": "1", + "command_number": 1, + } + + +@pytest.fixture +def xml_summary_file(wf_commons): + """XMLSummaryFile file path fixture.""" + path = os.path.join( + job_path, + f"summary{wf_commons['application_name']}_{wf_commons['production_id']}_{wf_commons['prod_job_id']}_{wf_commons['command_id']}.xml", + ) + yield path + Path(path).unlink(missing_ok=True) + + +@pytest.fixture +def request_file(wf_commons): + """RequstDict file path fixture.""" + path = os.path.join(job_path, f"{wf_commons['production_id']}_{wf_commons['prod_job_id']}_request.json") + yield path + Path(path).unlink(missing_ok=True) + + +@pytest.fixture +def wf_commons_file(): + """Workflow commons file path fixture.""" + path = os.path.join(job_path, "workflow_commons.json") + yield path + Path(path).unlink(missing_ok=True) def prepare_XMLSummary_file(xml_summary, content): @@ -83,6 +107,7 @@ def get_output_file_details(output_file): return details +@pytest.mark.skip("Deprecated command implementation") class TestUploadLogFile: """Collection of tests for the UploadLogFile command.""" @@ -348,52 +373,14 @@ def test_failed_to_zip(self, basedir, mocker: MockerFixture): class TestBookkeepingReport: - """Collection of tests for the TestBookkeepingReport command.""" - - wms_job_id = 0 - job_type = "merge" - production_id = "123" - prod_job_id = "00000456" - event_type = "123456789" - number_of_events = "100" - config_name = "aConfigName" - config_version = "aConfigVersion" - application_name = "someApp" - application_version = "v1r0" - bk_step_id = "123" - command_id = "1" - number_of_processors = 1 - job_path = "." - - xml_summary_file = os.path.join( - job_path, f"summary{application_name}_{production_id}_{prod_job_id}_{command_id}.xml" - ) - wf_commons_file = os.path.join(job_path, "workflow_commons.json") - bookkeeping_file = os.path.join(job_path, f"bookkeeping_{command_id}.xml") + """Collection of tests for the BookkeepingReport command.""" @pytest.fixture - def wf_commons(self): - """Workflow Commons dictionary fixture.""" - content = { - "job_id": self.wms_job_id, - "job_type": self.job_type, - "production_id": self.production_id, - "prod_job_id": self.prod_job_id, - "event_type": self.event_type, - "number_of_events": self.number_of_events, - "config_name": self.config_name, - "config_version": self.config_version, - "application_name": self.application_name, - "application_version": self.application_version, - "bk_step_id": self.bk_step_id, - "inputs": [], - "outputs": [], - "executable": "", - "command_id": self.command_id, - "command_number": 1, - } - - yield content + def bookkeeping_file(self, wf_commons): + """Bookkeeping report file fixture.""" + path = os.path.join(job_path, f"bookkeeping_{wf_commons['command_id']}.xml") + yield path + Path(path).unlink(missing_ok=True) @pytest.fixture def bk_report(self, mocker): @@ -403,21 +390,18 @@ def bk_report(self, mocker): """ mock_get_n_procs = mocker.patch("dirac_cwl.commands.bookkeeping_report.getNumberOfProcessorsToUse") - mock_get_n_procs.return_value = self.number_of_processors + mock_get_n_procs.return_value = number_of_processors yield BookeepingReport() - Path(self.wf_commons_file).unlink(missing_ok=True) - Path(self.bookkeeping_file).unlink(missing_ok=True) - Path(self.xml_summary_file).unlink(missing_ok=True) - Path("00209455_00001537_1").unlink(missing_ok=True) Path("00209455_00001537_1.sim").unlink(missing_ok=True) - def test_bkreport_prod_mcsimulation_success(self, bk_report, wf_commons): + def test_bkreport_prod_mcsimulation_success( + self, bk_report, wf_commons, wf_commons_file, bookkeeping_file, xml_summary_file + ): """Test successful execution of BookkeepingReport module.""" wf_commons["application_name"] = "Gauss" - wf_commons["application_version"] = self.application_version wf_commons["job_type"] = "MCSimulation" wf_commons["bookkeeping_LFNs"] = [ @@ -467,16 +451,16 @@ def test_bkreport_prod_mcsimulation_success(self, bk_report, wf_commons): """) - wf_commons["xml_summary_path"] = self.xml_summary_file - xf_o = prepare_XMLSummary_file(self.xml_summary_file, xml_content) + wf_commons["xml_summary_path"] = xml_summary_file + xf_o = prepare_XMLSummary_file(xml_summary_file, xml_content) - with open(self.wf_commons_file, "w", encoding="utf-8") as f: + with open(wf_commons_file, "w", encoding="utf-8") as f: json.dump(wf_commons, f) # Execute the module - bk_report.execute(self.job_path) + bk_report.execute(job_path) - xml_path = self.bookkeeping_file + xml_path = bookkeeping_file assert Path(xml_path).exists(), "XML report file not created." # Validate the XML file @@ -485,15 +469,15 @@ def test_bkreport_prod_mcsimulation_success(self, bk_report, wf_commons): # Extract fields from the XML and perform further operations assert root.tag == "Job", "Root tag should be Job." - assert root.attrib["ConfigName"] == self.config_name - assert root.attrib["ConfigVersion"] == self.config_version + assert root.attrib["ConfigName"] == wf_commons["config_name"] + assert root.attrib["ConfigVersion"] == wf_commons["config_version"] assert root.attrib["Date"] assert root.attrib["Time"] assert get_typed_parameter_value("ProgramName", root) == wf_commons["application_name"] assert get_typed_parameter_value("ProgramVersion", root) == wf_commons["application_version"] assert get_typed_parameter_value("DiracVersion", root) == LHCbDIRAC.__version__ - assert get_typed_parameter_value("Name", root) == self.command_id + assert get_typed_parameter_value("Name", root) == wf_commons["command_id"] assert float(get_typed_parameter_value("ExecTime", root)) > 1000 assert get_typed_parameter_value("CPUTIME", root) == "0" @@ -501,8 +485,8 @@ def test_bkreport_prod_mcsimulation_success(self, bk_report, wf_commons): assert get_typed_parameter_value("StatisticsRequested", root) == str(wf_commons["number_of_events"]) assert get_typed_parameter_value("NumberOfEvents", root) == str(xf_o.outputEventsTotal) - assert get_typed_parameter_value("Production", root) == self.production_id - assert get_typed_parameter_value("DiracJobId", root) == str(self.wms_job_id) + assert get_typed_parameter_value("Production", root) == wf_commons["production_id"] + assert get_typed_parameter_value("DiracJobId", root) == str(wf_commons["job_id"]) assert get_typed_parameter_value("Location", root) == siteName() assert get_typed_parameter_value("JobStart", root) assert get_typed_parameter_value("JobEnd", root) @@ -514,7 +498,7 @@ def test_bkreport_prod_mcsimulation_success(self, bk_report, wf_commons): assert get_typed_parameter_value("WNMODEL", root) assert get_typed_parameter_value("WNCACHE", root) assert get_typed_parameter_value("WNCPUHS06", root) - assert get_typed_parameter_value("NumberOfProcessors", root) == str(self.number_of_processors) + assert get_typed_parameter_value("NumberOfProcessors", root) == str(number_of_processors) # Input should be empty input_file = root.find("InputFile") @@ -534,7 +518,9 @@ def test_bkreport_prod_mcsimulation_success(self, bk_report, wf_commons): assert len(output_files) == 1 - def test_bkreport_prod_mcsimulation_noinputoutput_success(self, bk_report, wf_commons): + def test_bkreport_prod_mcsimulation_noinputoutput_success( + self, bk_report, wf_commons, wf_commons_file, bookkeeping_file, xml_summary_file + ): """Test successful execution of BookkeepingReport module. * No input files because wf_commons["stepInputData is empty @@ -544,7 +530,6 @@ def test_bkreport_prod_mcsimulation_noinputoutput_success(self, bk_report, wf_co """ # Mock the BookkeepingReport module wf_commons["application_name"] = "Gauss" - wf_commons["application_version"] = self.application_version wf_commons["job_type"] = "MCSimulation" # This was obtained from a previous module (likely GaudiApplication) @@ -589,17 +574,17 @@ def test_bkreport_prod_mcsimulation_noinputoutput_success(self, bk_report, wf_co """) - wf_commons["xml_summary_path"] = self.xml_summary_file - xf_o = prepare_XMLSummary_file(self.xml_summary_file, xml_content) + wf_commons["xml_summary_path"] = xml_summary_file + xf_o = prepare_XMLSummary_file(xml_summary_file, xml_content) - with open(self.wf_commons_file, "w", encoding="utf-8") as f: + with open(wf_commons_file, "w", encoding="utf-8") as f: json.dump(wf_commons, f) # Execute the module - bk_report.execute(self.job_path) + bk_report.execute(job_path) # Check if the XML report file is created - xml_path = self.bookkeeping_file + xml_path = bookkeeping_file assert Path(xml_path).exists(), "XML report file not created." # Validate the XML file @@ -608,15 +593,15 @@ def test_bkreport_prod_mcsimulation_noinputoutput_success(self, bk_report, wf_co # Extract fields from the XML and perform further operations assert root.tag == "Job", "Root tag should be Job." - assert root.attrib["ConfigName"] == self.config_name - assert root.attrib["ConfigVersion"] == self.config_version + assert root.attrib["ConfigName"] == wf_commons["config_name"] + assert root.attrib["ConfigVersion"] == wf_commons["config_version"] assert root.attrib["Date"] assert root.attrib["Time"] assert get_typed_parameter_value("ProgramName", root) == wf_commons["application_name"] assert get_typed_parameter_value("ProgramVersion", root) == wf_commons["application_version"] assert get_typed_parameter_value("DiracVersion", root) == LHCbDIRAC.__version__ - assert get_typed_parameter_value("Name", root) == self.command_id + assert get_typed_parameter_value("Name", root) == wf_commons["command_id"] assert float(get_typed_parameter_value("ExecTime", root)) > 1000 assert get_typed_parameter_value("CPUTIME", root) == "0" @@ -624,8 +609,8 @@ def test_bkreport_prod_mcsimulation_noinputoutput_success(self, bk_report, wf_co assert get_typed_parameter_value("StatisticsRequested", root) == str(wf_commons["number_of_events"]) assert get_typed_parameter_value("NumberOfEvents", root) == str(xf_o.outputEventsTotal) - assert get_typed_parameter_value("Production", root) == self.production_id - assert get_typed_parameter_value("DiracJobId", root) == str(self.wms_job_id) + assert get_typed_parameter_value("Production", root) == wf_commons["production_id"] + assert get_typed_parameter_value("DiracJobId", root) == str(wf_commons["job_id"]) assert get_typed_parameter_value("Location", root) == siteName() assert get_typed_parameter_value("JobStart", root) assert get_typed_parameter_value("JobEnd", root) @@ -637,7 +622,7 @@ def test_bkreport_prod_mcsimulation_noinputoutput_success(self, bk_report, wf_co assert get_typed_parameter_value("WNMODEL", root) assert get_typed_parameter_value("WNCACHE", root) assert get_typed_parameter_value("WNCPUHS06", root) - assert get_typed_parameter_value("NumberOfProcessors", root) == str(self.number_of_processors) + assert get_typed_parameter_value("NumberOfProcessors", root) == str(number_of_processors) # Input should be empty input_file = root.find("InputFile") @@ -647,10 +632,11 @@ def test_bkreport_prod_mcsimulation_noinputoutput_success(self, bk_report, wf_co output_file = root.find("OutputFile") assert output_file is None, "OutputFile element should not be present." - def test_bk_report_prod_mcreconstruction_success(self, bk_report, wf_commons): + def test_bk_report_prod_mcreconstruction_success( + self, bk_report, wf_commons, wf_commons_file, bookkeeping_file, xml_summary_file + ): """Test successful execution of BookkeepingReport module.""" wf_commons["application_name"] = "Boole" - wf_commons["application_version"] = self.application_version wf_commons["job_type"] = "MCReconstruction" wf_commons["bookkeeping_LFNs"] = [ @@ -692,18 +678,18 @@ def test_bk_report_prod_mcreconstruction_success(self, bk_report, wf_commons): """) - wf_commons["xml_summary_path"] = self.xml_summary_file + wf_commons["xml_summary_path"] = xml_summary_file - xf_o = prepare_XMLSummary_file(self.xml_summary_file, xml_content) + xf_o = prepare_XMLSummary_file(xml_summary_file, xml_content) - with open(self.wf_commons_file, "w", encoding="utf-8") as f: + with open(wf_commons_file, "w", encoding="utf-8") as f: json.dump(wf_commons, f) # Execute the module - bk_report.execute(self.job_path) + bk_report.execute(job_path) # Check if the XML report file is created - xml_path = self.bookkeeping_file + xml_path = bookkeeping_file assert Path(xml_path).exists(), "XML report file not created." # Validate the XML file @@ -712,15 +698,15 @@ def test_bk_report_prod_mcreconstruction_success(self, bk_report, wf_commons): # Extract fields from the XML and perform further operations assert root.tag == "Job", "Root tag should be Job." - assert root.attrib["ConfigName"] == self.config_name - assert root.attrib["ConfigVersion"] == self.config_version + assert root.attrib["ConfigName"] == wf_commons["config_name"] + assert root.attrib["ConfigVersion"] == wf_commons["config_version"] assert root.attrib["Date"] assert root.attrib["Time"] assert get_typed_parameter_value("ProgramName", root) == wf_commons["application_name"] assert get_typed_parameter_value("ProgramVersion", root) == wf_commons["application_version"] assert get_typed_parameter_value("DiracVersion", root) == LHCbDIRAC.__version__ - assert get_typed_parameter_value("Name", root) == self.command_id + assert get_typed_parameter_value("Name", root) == wf_commons["command_id"] assert float(get_typed_parameter_value("ExecTime", root)) > 1000 assert get_typed_parameter_value("CPUTIME", root) == "0" @@ -728,8 +714,8 @@ def test_bk_report_prod_mcreconstruction_success(self, bk_report, wf_commons): assert get_typed_parameter_value("StatisticsRequested", root) == str(wf_commons["number_of_events"]) assert get_typed_parameter_value("NumberOfEvents", root) == str(xf_o.inputEventsTotal) - assert get_typed_parameter_value("Production", root) == self.production_id - assert get_typed_parameter_value("DiracJobId", root) == str(self.wms_job_id) + assert get_typed_parameter_value("Production", root) == wf_commons["production_id"] + assert get_typed_parameter_value("DiracJobId", root) == str(wf_commons["job_id"]) assert get_typed_parameter_value("Location", root) == siteName() assert get_typed_parameter_value("JobStart", root) assert get_typed_parameter_value("JobEnd", root) @@ -741,7 +727,7 @@ def test_bk_report_prod_mcreconstruction_success(self, bk_report, wf_commons): assert get_typed_parameter_value("WNMODEL", root) assert get_typed_parameter_value("WNCACHE", root) assert get_typed_parameter_value("WNCPUHS06", root) - assert get_typed_parameter_value("NumberOfProcessors", root) == str(self.number_of_processors) + assert get_typed_parameter_value("NumberOfProcessors", root) == str(number_of_processors) # Input should not be empty input_file = root.find("InputFile") @@ -765,19 +751,19 @@ def test_bk_report_prod_mcreconstruction_success(self, bk_report, wf_commons): simulation_condition = root.find("SimulationCondition") assert simulation_condition is None, "SimulationCondition element should not be present." - def test_bkreport_previousError_success(self, mocker, bk_report, wf_commons): + def test_bkreport_previousError_success(self, mocker, bk_report, wf_commons, wf_commons_file, bookkeeping_file): """Test previous command failure.""" wf_commons["application_name"] = "Gauss" - wf_commons["application_version"] = self.config_version + wf_commons["application_version"] = wf_commons["config_version"] wf_commons["job_type"] = "MCSimulation" wf_commons["step_status"] = S_ERROR() - with open(self.wf_commons_file, "w", encoding="utf-8") as f: + with open(wf_commons_file, "w", encoding="utf-8") as f: json.dump(wf_commons, f) - bk_report.execute(self.job_path) + bk_report.execute(job_path) - assert not os.path.exists(self.bookkeeping_file) + assert not os.path.exists(bookkeeping_file) class TestFailoverRequest: @@ -793,10 +779,9 @@ def failover_request(self, mocker: MockerFixture): yield FailoverRequest() - Path(request_file).unlink(missing_ok=True) - Path(wf_commons_file).unlink(missing_ok=True) - - def test_failoverRequest_success(self, mocker: MockerFixture, failover_request): + def test_failoverRequest_success( + self, mocker: MockerFixture, failover_request, wf_commons, wf_commons_file, request_file + ): """Test successful execution of FailoverRequest module.""" problematic_files = [ "/lhcb/data/2010/EW.DST/00008380/0000/00008380_00000287_1.ew.dst", @@ -852,7 +837,9 @@ def test_failoverRequest_success(self, mocker: MockerFixture, failover_request): # Make sure the request json does not exists assert not Path(request_file).exists() - def test_failoverRequest_commitFailure1(self, mocker: MockerFixture, failover_request): + def test_failoverRequest_commitFailure1( + self, mocker: MockerFixture, failover_request, wf_commons, wf_commons_file, request_file + ): """Test execution of FailoverRequest module when the fileReport.commit() fails. In this context, the second call to commit() will work, so the request should not be generated. @@ -911,7 +898,9 @@ def test_failoverRequest_commitFailure1(self, mocker: MockerFixture, failover_re # Make sure the request json does not exists assert not Path(request_file).exists() - def test_failoverRequest_commitFailure2(self, mocker: MockerFixture, failover_request): + def test_failoverRequest_commitFailure2( + self, mocker: MockerFixture, failover_request, wf_commons, wf_commons_file, request_file + ): """Test execution of FailoverRequest module when the fileReport.commit() fails. In this context, the second call to commit() will fail, so the request should be generated. @@ -972,7 +961,9 @@ def test_failoverRequest_commitFailure2(self, mocker: MockerFixture, failover_re # Make sure the request json does not exists assert Path(request_file).exists() - def test_failoverRequest_previousError_fail(self, mocker: MockerFixture, failover_request): + def test_failoverRequest_previousError_fail( + self, mocker: MockerFixture, failover_request, wf_commons, wf_commons_file, request_file + ): """Test FailoverRequest with an intentional failure.""" problematic_files = [ "/lhcb/data/2010/EW.DST/00008380/0000/00008380_00000287_1.ew.dst", From 26de911d303accc42c4d01e7754a5dfcd324ef13 Mon Sep 17 00:00:00 2001 From: Jorge Lisa <64639359+AcquaDiGiorgio@users.noreply.github.com> Date: Tue, 5 May 2026 15:08:32 +0200 Subject: [PATCH 11/21] feat: Migrate UploadOutputData command to cwl-dirac chore: Create proper wf_commons file update --- src/dirac_cwl/commands/__init__.py | 10 +- src/dirac_cwl/commands/bookkeeping_report.py | 259 ++--- src/dirac_cwl/commands/failover_request.py | 62 +- src/dirac_cwl/commands/upload_output_data.py | 190 ++++ src/dirac_cwl/commands/utils.py | 16 +- test/test_commands.py | 934 +++++++++++++++++-- 6 files changed, 1233 insertions(+), 238 deletions(-) create mode 100644 src/dirac_cwl/commands/upload_output_data.py diff --git a/src/dirac_cwl/commands/__init__.py b/src/dirac_cwl/commands/__init__.py index 1af50a8..a2b6380 100644 --- a/src/dirac_cwl/commands/__init__.py +++ b/src/dirac_cwl/commands/__init__.py @@ -4,5 +4,13 @@ from .core import PostProcessCommand, PreProcessCommand from .failover_request import FailoverRequest from .upload_log_file import UploadLogFile +from .upload_output_data import UploadOutputData -__all__ = ["PreProcessCommand", "PostProcessCommand", "UploadLogFile", "BookeepingReport", "FailoverRequest"] +__all__ = [ + "PreProcessCommand", + "PostProcessCommand", + "UploadLogFile", + "BookeepingReport", + "FailoverRequest", + "UploadOutputData", +] diff --git a/src/dirac_cwl/commands/bookkeeping_report.py b/src/dirac_cwl/commands/bookkeeping_report.py index 771d456..1573ad7 100644 --- a/src/dirac_cwl/commands/bookkeeping_report.py +++ b/src/dirac_cwl/commands/bookkeeping_report.py @@ -18,7 +18,7 @@ from dirac_cwl.core.exceptions import WorkflowProcessingException from .core import PostProcessCommand -from .utils import prepare_lhcb_workflow_commons +from .utils import prepare_lhcb_workflow_commons, save_workflow_commons class BookeepingReport(PostProcessCommand): @@ -30,130 +30,139 @@ def execute(self, job_path, **kwargs): :param job_path: Path to the job working directory. :param kwargs: Additional keyword arguments. """ - # Obtain Workflow Commons - workflow_commons_path = kwargs.get("workflow-commons-path", os.path.join(job_path, "workflow_commons.json")) - - workflow_commons = prepare_lhcb_workflow_commons( - workflow_commons_path, - extra_mandatory_values=[ - "bk_step_id", - ], - extra_default_values={ - "bookkeeping_LFNs": [], - "size": {}, - "md5": {}, - "guid": {}, - "sim_description": "NoSimConditions", - }, - ) - - if not workflow_commons["step_status"]["OK"]: - return - - # Setup variables - start_time = workflow_commons.get("start_time", None) - - cpu_times = {} - if start_time: - cpu_times["StartTime"] = start_time - if "start_stats" in workflow_commons: - cpu_times["StartStats"] = workflow_commons["start_stats"] - - exectime, cputime = getStepCPUTimes(cpu_times) - - number_of_processors = getNumberOfProcessorsToUse( - workflow_commons["job_id"], workflow_commons["max_number_of_processors"] - ) - - bk_client = BookkeepingClient() - - parameters = { - "PRODUCTION_ID": workflow_commons["production_id"], - "JOB_ID": workflow_commons["prod_job_id"], - "configVersion": workflow_commons["config_version"], - "outputList": workflow_commons["outputs"], - "configName": workflow_commons["config_name"], - "outputDataFileMask": workflow_commons["output_data_file_mask"], - } - - if "bookkeeping_LFNs" in workflow_commons and "production_output_data" in workflow_commons: - bk_lfns = workflow_commons["bookkeeping_LFNs"] - - if not isinstance(bk_lfns, list): - bk_lfns = [i.strip() for i in bk_lfns.split(";")] - - else: - result = constructProductionLFNs(parameters, bk_client) - if not result["OK"]: - raise WorkflowProcessingException("Could not create production LFNs") - - bk_lfns = result["Value"]["BookkeepingLFNs"] - - ldate, ltime, ldatestart, ltimestart = _process_time(start_time) - - # Obtain XMLSummary - if "xml_summary_path" in workflow_commons: - xf_o = XMLSummary(workflow_commons["xml_summary_path"]) - else: - xf_o = _generate_xml_object( - workflow_commons["cleaned_application_name"], - workflow_commons["production_id"], - workflow_commons["prod_job_id"], - workflow_commons["command_number"], + failed = False + try: + # Obtain Workflow Commons + workflow_commons_path = kwargs.get("workflow_commons_path", os.path.join(job_path, "workflow_commons.json")) + + workflow_commons = prepare_lhcb_workflow_commons( + workflow_commons_path, + extra_mandatory_values=[ + "bk_step_id", + ], + extra_default_values={ + "bookkeeping_LFNs": [], + "size": {}, + "md5": {}, + "guid": {}, + "sim_description": "NoSimConditions", + }, + ) + + if not workflow_commons["step_status"]["OK"]: + return + + # Setup variables + start_time = workflow_commons.get("start_time", None) + + cpu_times = {} + if start_time: + cpu_times["StartTime"] = start_time + if "start_stats" in workflow_commons: + cpu_times["StartStats"] = workflow_commons["start_stats"] + + exectime, cputime = getStepCPUTimes(cpu_times) + + number_of_processors = getNumberOfProcessorsToUse( + workflow_commons["job_id"], workflow_commons["max_number_of_processors"] + ) + + bk_client = BookkeepingClient() + + parameters = { + "PRODUCTION_ID": workflow_commons["production_id"], + "JOB_ID": workflow_commons["prod_job_id"], + "configVersion": workflow_commons["config_version"], + "outputList": workflow_commons["outputs"], + "configName": workflow_commons["config_name"], + "outputDataFileMask": workflow_commons["output_data_file_mask"], + } + + if "bookkeeping_LFNs" in workflow_commons and "production_output_data" in workflow_commons: + bk_lfns = workflow_commons["bookkeeping_LFNs"] + + if not isinstance(bk_lfns, list): + bk_lfns = [i.strip() for i in bk_lfns.split(";")] + + else: + result = constructProductionLFNs(parameters, bk_client) + if not result["OK"]: + raise WorkflowProcessingException("Could not create production LFNs") + + bk_lfns = result["Value"]["BookkeepingLFNs"] + + ldate, ltime, ldatestart, ltimestart = _process_time(start_time) + + # Obtain XMLSummary + if "xml_summary_path" in workflow_commons: + xf_o = XMLSummary(workflow_commons["xml_summary_path"]) + else: + xf_o = _generate_xml_object( + workflow_commons["cleaned_application_name"], + workflow_commons["production_id"], + workflow_commons["prod_job_id"], + workflow_commons["command_number"], + workflow_commons["command_id"], + ) + + info_dict = { + "exectime": exectime, + "cputime": cputime, + "numberOfProcessors": number_of_processors, + "production_id": workflow_commons["production_id"], + "jobID": workflow_commons["job_id"], + "siteName": workflow_commons["site_name"], + "jobType": workflow_commons["job_type"], + "applicationName": workflow_commons["application_name"], + "applicationVersion": workflow_commons["application_version"], + "numberOfEvents": workflow_commons["number_of_events"], + } + + # Generate job_info object + job_info = _prepare_job_info( + info_dict, + ldatestart, + ltimestart, + ldate, + ltime, + xf_o, + workflow_commons["inputs"], workflow_commons["command_id"], + workflow_commons["bk_step_id"], + bk_client, + workflow_commons["config_name"], + workflow_commons["config_version"], + ) + + # Add input files to job_info + _generateInputFiles(job_info, bk_lfns, workflow_commons["inputs"]) + + # Add output files to job_info + _generateOutputFiles( + job_info, + bk_lfns, + workflow_commons["event_type"], + workflow_commons["application_name"], + xf_o, + workflow_commons["outputs"], + workflow_commons["inputs"], ) - info_dict = { - "exectime": exectime, - "cputime": cputime, - "numberOfProcessors": number_of_processors, - "production_id": workflow_commons["production_id"], - "jobID": workflow_commons["job_id"], - "siteName": workflow_commons["site_name"], - "jobType": workflow_commons["job_type"], - "applicationName": workflow_commons["application_name"], - "applicationVersion": workflow_commons["application_version"], - "numberOfEvents": workflow_commons["number_of_events"], - } - - # Generate job_info object - job_info = _prepare_job_info( - info_dict, - ldatestart, - ltimestart, - ldate, - ltime, - xf_o, - workflow_commons["inputs"], - workflow_commons["command_id"], - workflow_commons["bk_step_id"], - bk_client, - workflow_commons["config_name"], - workflow_commons["config_version"], - ) - - # Add input files to job_info - _generateInputFiles(job_info, bk_lfns, workflow_commons["inputs"]) - - # Add output files to job_info - _generateOutputFiles( - job_info, - bk_lfns, - workflow_commons["event_type"], - workflow_commons["application_name"], - xf_o, - workflow_commons["outputs"], - workflow_commons["inputs"], - ) - - # Generate SimulationConditions - if workflow_commons["application_name"] == "Gauss": - job_info.simulation_condition = workflow_commons["sim_description"] - - # Convert job_info object to XML - doc = job_info.to_xml() - - # Write to file - bfilename = f"bookkeeping_{workflow_commons['command_id']}.xml" - with open(bfilename, "wb") as bfile: - bfile.write(doc) + # Generate SimulationConditions + if workflow_commons["application_name"] == "Gauss": + job_info.simulation_condition = workflow_commons["sim_description"] + + # Convert job_info object to XML + doc = job_info.to_xml() + + # Write to file + bfilename = f"bookkeeping_{workflow_commons['command_id']}.xml" + with open(bfilename, "wb") as bfile: + bfile.write(doc) + + except: + failed = True + raise + + finally: + save_workflow_commons(workflow_commons, workflow_commons_path, failed=failed) diff --git a/src/dirac_cwl/commands/failover_request.py b/src/dirac_cwl/commands/failover_request.py index 005db7a..a56119f 100644 --- a/src/dirac_cwl/commands/failover_request.py +++ b/src/dirac_cwl/commands/failover_request.py @@ -31,47 +31,49 @@ def execute(self, job_path, **kwargs): :param job_path: Path to the job working directory. :param kwargs: Additional keyword arguments. """ - workflow_commons_path = kwargs.get("workflow-commons-path", os.path.join(job_path, "workflow_commons.json")) + failed = False + try: + workflow_commons_path = kwargs.get("workflow_commons_path", os.path.join(job_path, "workflow_commons.json")) - workflow_commons = prepare_lhcb_workflow_commons( - workflow_commons_path, - extra_mandatory_values=[], - extra_default_values={ - "request_dict": None, - "file_report_files_dict": {}, - "accounting_registers": {}, - }, - ) + workflow_commons = prepare_lhcb_workflow_commons( + workflow_commons_path, + extra_mandatory_values=[], + extra_default_values={"accounting_registers": None}, + ) - request = Request(workflow_commons["request_dict"]) - file_report = FileReport() - file_report.statusDict = workflow_commons["file_report_files_dict"] + request = Request(workflow_commons["request_dict"]) + file_report = FileReport() + file_report.statusDict = workflow_commons["file_report_files_dict"] - job_report = JobReport(workflow_commons["job_id"]) + job_report = JobReport(workflow_commons["job_id"]) - _prepareRequest(request, workflow_commons["job_id"]) + _prepareRequest(request, workflow_commons["job_id"]) - filesInFileReport = file_report.getFiles() + filesInFileReport = file_report.getFiles() - for lfn in workflow_commons["inputs"]: - if lfn not in filesInFileReport: - status = "Processed" if workflow_commons["step_status"]["OK"] else "Unused" - file_report.setFileStatus(int(workflow_commons["production_id"]), lfn, status) + for lfn in workflow_commons["inputs"]: + if lfn not in filesInFileReport: + status = "Processed" if workflow_commons["step_status"]["OK"] else "Unused" + file_report.setFileStatus(int(workflow_commons["production_id"]), lfn, status) - file_report.commit() + file_report.commit() - if workflow_commons["step_status"]["OK"]: - if file_report.getFiles(): - result = file_report.generateForwardDISET() - if result["OK"] and result["Value"]: - request.addOperation(result["Value"]) + if workflow_commons["step_status"]["OK"]: + if file_report.getFiles(): + result = file_report.generateForwardDISET() + if result["OK"] and result["Value"]: + request.addOperation(result["Value"]) - job_report.setApplicationStatus("Job Finished Successfully", True) + job_report.setApplicationStatus("Job Finished Successfully", True) - self.generateFailoverFile(job_report, request, workflow_commons) + self.generateFailoverFile(job_report, request, workflow_commons) - workflow_commons["request_dict"] = json.loads(request.toJSON()["Value"]) - save_workflow_commons(workflow_commons, workflow_commons_path) + except: + failed = True + raise + + finally: + save_workflow_commons(workflow_commons, workflow_commons_path, request=request, failed=failed) def generateFailoverFile(self, job_report, request, workflow_commons): """Create a request.json file.""" diff --git a/src/dirac_cwl/commands/upload_output_data.py b/src/dirac_cwl/commands/upload_output_data.py new file mode 100644 index 0000000..03617bf --- /dev/null +++ b/src/dirac_cwl/commands/upload_output_data.py @@ -0,0 +1,190 @@ +"""LHCb command for registering the outputs generated to the corresponding SE or the FailoverSE in case of failure.""" + +import os +import random + +from DIRAC.DataManagementSystem.Client.DataManager import DataManager +from DIRAC.DataManagementSystem.Client.FailoverTransfer import FailoverTransfer +from DIRAC.RequestManagementSystem.Client.Request import Request +from DIRAC.TransformationSystem.Client.FileReport import FileReport +from DIRAC.WorkloadManagementSystem.Client.JobReport import JobReport +from LHCbDIRAC.BookkeepingSystem.Client.BookkeepingClient import BookkeepingClient +from LHCbDIRAC.Core.Utilities.ProductionData import constructProductionLFNs +from LHCbDIRAC.Core.Utilities.ResolveSE import getDestinationSEList +from LHCbDIRAC.DataManagementSystem.Client.ConsistencyChecks import getFileDescendents +from LHCbDIRAC.Workflow.Modules.UploadOutputData import ( + _createMetaDict, + _getBKFiles, + _getCleanRequest, + _getFileMetada, + _registerLFNs, + _resolveSEs, + _sendBKReport, +) + +from dirac_cwl.core.exceptions import WorkflowProcessingException + +from .core import PostProcessCommand +from .utils import prepare_lhcb_workflow_commons, save_workflow_commons + + +class UploadOutputData(PostProcessCommand): + """Registers every output generated to the corresponding SE and Catalog or to the FailoverSE in case of failure.""" + + def execute(self, job_path, **kwargs): + """Execute the command. + + :param job_path: Path to the job working directory. + :param kwargs: Additional keyword arguments. + """ + fail = False + try: + workflow_commons_path = kwargs.get("workflow_commons_path", os.path.join(job_path, "workflow_commons.json")) + + workflow_commons = prepare_lhcb_workflow_commons( + workflow_commons_path, + extra_mandatory_values=["output_data_step", "output_SEs"], + extra_default_values={ + "file_descendants": None, + "prod_output_LFNs": None, + "run_number": "Unknown", + "output_mode": "Any", + }, + ) + request = Request(workflow_commons["request_dict"]) + + if not workflow_commons["step_status"]["OK"]: + return + + bk_client = BookkeepingClient() + data_manager = DataManager() + + failover_se_list = getDestinationSEList("Tier1-Failover", workflow_commons["site_name"], outputmode="Any") + random.shuffle(failover_se_list) + + file_report = FileReport() + file_report.statusDict = workflow_commons["file_report_files_dict"] + + job_report = JobReport(workflow_commons["job_id"]) + + if not workflow_commons["prod_output_LFNs"]: + parameters = { + "PRODUCTION_ID": workflow_commons["production_id"], + "JOB_ID": workflow_commons["job_id"], + "configVersion": workflow_commons["config_version"], + "outputList": workflow_commons["outputs"], + "configName": workflow_commons["config_name"], + "outputDataFileMask": workflow_commons["output_data_file_mask"], + } + result = constructProductionLFNs(parameters, bk_client) + + if not result["OK"]: + raise WorkflowProcessingException("Unable to construsct production LFNs") + + workflow_commons["prod_output_LFNs"] = result["Value"]["ProductionOutputData"] + + file_metadata = _getFileMetada( + workflow_commons["outputs"], + workflow_commons["prod_output_LFNs"], + workflow_commons["output_data_file_mask"], + workflow_commons["output_data_step"], + workflow_commons["output_SEs"], + ) + + if not file_metadata: + return + + final = _resolveSEs( + file_metadata, + None, + workflow_commons["site_name"], + workflow_commons["output_mode"], + workflow_commons["run_number"], + ) + + if workflow_commons["inputs"]: + lfns_with_descendants = workflow_commons["file_descendants"] + + if not lfns_with_descendants: + lfns_with_descendants = getFileDescendents( + workflow_commons["production_id"], + workflow_commons["inputs"], + dm=data_manager, + bkClient=bk_client, + ) + + if lfns_with_descendants: + file_report.setFileStatus( + int(workflow_commons["production_id"]), lfns_with_descendants, "Processed" + ) + raise WorkflowProcessingException("Input Data Already Processed") + + bkFiles = _getBKFiles() + + for bkFile in bkFiles: + with open(bkFile) as fd: + bkXML = fd.read() + + result = _sendBKReport(bk_client, request, bkXML) + + failover_transfer = FailoverTransfer(request) + + perform_bk_registration = [] + + failover = {} + for file_name, metadata in final.items(): + targetSE = metadata["resolvedSE"] + file_meta_dict = _createMetaDict(metadata) + result = failover_transfer.transferAndRegisterFile( + fileName=file_name, + localPath=metadata["localpath"], + lfn=metadata["filedict"]["LFN"], + destinationSEList=targetSE, + fileMetaDict=file_meta_dict, + masterCatalogOnly=True, + ) + if not result["OK"]: + failover[file_name] = metadata + else: + perform_bk_registration.append(metadata) + + cleanUp = False + for file_name, metadata in failover.items(): + random.shuffle(failover_se_list) + targetSE = metadata["resolvedSE"][0] + metadata["resolvedSE"] = failover_se_list + + file_meta_dict = _createMetaDict(metadata) + result = failover_transfer.transferAndRegisterFileFailover( + fileName=file_name, + localPath=metadata["localpath"], + lfn=metadata["filedict"]["LFN"], + targetSE=targetSE, + failoverSEList=metadata["resolvedSE"], + fileMetaDict=file_meta_dict, + masterCatalogOnly=True, + ) + if not result["OK"]: + cleanUp = True + break + + request = failover_transfer.request + if cleanUp: + request = _getCleanRequest(request, final) + raise WorkflowProcessingException("Failed to upload output data") + + if final: + report = ", ".join(final) + job_report.setJobParameter("UploadedOutputData", report) + + if perform_bk_registration: + result = _registerLFNs(request, perform_bk_registration) + if not result["OK"]: + raise WorkflowProcessingException(result["Message"]) + + except: + fail = True + raise + + finally: + save_workflow_commons(workflow_commons, workflow_commons_path, request, failed=fail) diff --git a/src/dirac_cwl/commands/utils.py b/src/dirac_cwl/commands/utils.py index 30ed69e..43a7f88 100644 --- a/src/dirac_cwl/commands/utils.py +++ b/src/dirac_cwl/commands/utils.py @@ -5,7 +5,7 @@ import shutil from DIRAC import siteName -from DIRAC.Core.Utilities.ReturnValues import S_OK +from DIRAC.Core.Utilities.ReturnValues import S_ERROR, S_OK from dirac_cwl.core.exceptions import WorkflowProcessingException @@ -55,11 +55,9 @@ def prepare_lhcb_workflow_commons(workflow_commons_path, extra_mandatory_values= "output_data_file_mask": "", "run_metadata": {}, "log_target_path": "", - "output_mode": "", "production_output_data": [], "CPUe": 0, "max_number_of_events": "0", - "output_SEs": {}, "output_data_type": None, "application_log": "", "application_type": None, @@ -75,6 +73,8 @@ def prepare_lhcb_workflow_commons(workflow_commons_path, extra_mandatory_values= "step_status": S_OK(), "config_name": None, "config_version": None, + "request_dict": {}, + "file_report_files_dict": {}, } for k, v in extra_default_values.items(): @@ -93,19 +93,25 @@ def prepare_lhcb_workflow_commons(workflow_commons_path, extra_mandatory_values= return workflow_commons -def save_workflow_commons(wf_commons, wf_file_path): +def save_workflow_commons(wf_commons, wf_file_path, request=None, failed=False): """Update the workflow_commons file to accomodate for the new values. Ensures that no data is lost during the update by creating a backup. """ if not (os.path.exists(wf_file_path) and os.path.isfile(wf_file_path)): - raise WorkflowProcessingException("") + raise WorkflowProcessingException(f"Workflow Commons file '{wf_file_path}' not found") wf_filename = os.path.basename(wf_file_path) wf_backup = f"{wf_filename}.bak" shutil.move(wf_file_path, wf_backup) + if failed: + wf_commons["step_status"] = S_ERROR() + + if request: + wf_commons["request_dict"] = json.loads(request.toJSON()["Value"]) + try: with open(wf_file_path, "x", encoding="utf-8") as f: json.dump(wf_commons, f) diff --git a/test/test_commands.py b/test/test_commands.py index 50949a0..dfd6af7 100644 --- a/test/test_commands.py +++ b/test/test_commands.py @@ -12,13 +12,19 @@ import LHCbDIRAC import pytest from DIRAC import siteName +from DIRAC.DataManagementSystem.Client.FailoverTransfer import FailoverTransfer +from DIRAC.RequestManagementSystem.Client.File import File +from DIRAC.RequestManagementSystem.Client.Operation import Operation +from DIRAC.RequestManagementSystem.Client.Request import Request from DIRAC.TransformationSystem.Client.FileReport import FileReport from DIRAC.WorkloadManagementSystem.Client.JobReport import JobReport from DIRACCommon.Core.Utilities.ReturnValues import S_ERROR, S_OK +from LHCbDIRAC.BookkeepingSystem.Client.BookkeepingClient import BookkeepingClient from LHCbDIRAC.Core.Utilities.XMLSummaries import XMLSummary from pytest_mock import MockerFixture -from dirac_cwl.commands import BookeepingReport, FailoverRequest, UploadLogFile +from dirac_cwl.commands import BookeepingReport, FailoverRequest, UploadLogFile, UploadOutputData +from dirac_cwl.core.exceptions import WorkflowProcessingException number_of_processors = 1 job_path = "." @@ -46,6 +52,8 @@ def wf_commons(): "command_number": 1, } + Path(os.path.join(job_path, "workflow_commons.json")).unlink(missing_ok=True) + @pytest.fixture def xml_summary_file(wf_commons): @@ -66,14 +74,6 @@ def request_file(wf_commons): Path(path).unlink(missing_ok=True) -@pytest.fixture -def wf_commons_file(): - """Workflow commons file path fixture.""" - path = os.path.join(job_path, "workflow_commons.json") - yield path - Path(path).unlink(missing_ok=True) - - def prepare_XMLSummary_file(xml_summary, content): """Pepares a xml summary file and returns it as a class.""" with open(xml_summary, "w", encoding="utf-8") as f: @@ -107,6 +107,14 @@ def get_output_file_details(output_file): return details +def create_workflow_commons(wf_dict): + """Dump the content of wf_commons to a file.""" + path = os.path.join(job_path, "workflow_commons.json") + with open(path, "w", encoding="utf-8") as f: + json.dump(wf_dict, f) + return path + + @pytest.mark.skip("Deprecated command implementation") class TestUploadLogFile: """Collection of tests for the UploadLogFile command.""" @@ -397,9 +405,7 @@ def bk_report(self, mocker): Path("00209455_00001537_1").unlink(missing_ok=True) Path("00209455_00001537_1.sim").unlink(missing_ok=True) - def test_bkreport_prod_mcsimulation_success( - self, bk_report, wf_commons, wf_commons_file, bookkeeping_file, xml_summary_file - ): + def test_bkreport_prod_mcsimulation_success(self, bk_report, wf_commons, bookkeeping_file, xml_summary_file): """Test successful execution of BookkeepingReport module.""" wf_commons["application_name"] = "Gauss" wf_commons["job_type"] = "MCSimulation" @@ -454,12 +460,14 @@ def test_bkreport_prod_mcsimulation_success( wf_commons["xml_summary_path"] = xml_summary_file xf_o = prepare_XMLSummary_file(xml_summary_file, xml_content) - with open(wf_commons_file, "w", encoding="utf-8") as f: - json.dump(wf_commons, f) + wf_commons_path = create_workflow_commons(wf_commons) # Execute the module bk_report.execute(job_path) + with open(wf_commons_path, "r", encoding="utf-8") as f: + updated_wf_commons = json.load(f) + xml_path = bookkeeping_file assert Path(xml_path).exists(), "XML report file not created." @@ -469,28 +477,28 @@ def test_bkreport_prod_mcsimulation_success( # Extract fields from the XML and perform further operations assert root.tag == "Job", "Root tag should be Job." - assert root.attrib["ConfigName"] == wf_commons["config_name"] - assert root.attrib["ConfigVersion"] == wf_commons["config_version"] + assert root.attrib["ConfigName"] == updated_wf_commons["config_name"] + assert root.attrib["ConfigVersion"] == updated_wf_commons["config_version"] assert root.attrib["Date"] assert root.attrib["Time"] - assert get_typed_parameter_value("ProgramName", root) == wf_commons["application_name"] - assert get_typed_parameter_value("ProgramVersion", root) == wf_commons["application_version"] + assert get_typed_parameter_value("ProgramName", root) == updated_wf_commons["application_name"] + assert get_typed_parameter_value("ProgramVersion", root) == updated_wf_commons["application_version"] assert get_typed_parameter_value("DiracVersion", root) == LHCbDIRAC.__version__ - assert get_typed_parameter_value("Name", root) == wf_commons["command_id"] + assert get_typed_parameter_value("Name", root) == updated_wf_commons["command_id"] assert float(get_typed_parameter_value("ExecTime", root)) > 1000 assert get_typed_parameter_value("CPUTIME", root) == "0" assert get_typed_parameter_value("FirstEventNumber", root) == "1" - assert get_typed_parameter_value("StatisticsRequested", root) == str(wf_commons["number_of_events"]) + assert get_typed_parameter_value("StatisticsRequested", root) == str(updated_wf_commons["number_of_events"]) assert get_typed_parameter_value("NumberOfEvents", root) == str(xf_o.outputEventsTotal) - assert get_typed_parameter_value("Production", root) == wf_commons["production_id"] - assert get_typed_parameter_value("DiracJobId", root) == str(wf_commons["job_id"]) + assert get_typed_parameter_value("Production", root) == updated_wf_commons["production_id"] + assert get_typed_parameter_value("DiracJobId", root) == str(updated_wf_commons["job_id"]) assert get_typed_parameter_value("Location", root) == siteName() assert get_typed_parameter_value("JobStart", root) assert get_typed_parameter_value("JobEnd", root) - assert get_typed_parameter_value("JobType", root) == wf_commons["job_type"] + assert get_typed_parameter_value("JobType", root) == updated_wf_commons["job_type"] assert get_typed_parameter_value("WorkerNode", root) assert get_typed_parameter_value("WNMEMORY", root) @@ -509,7 +517,7 @@ def test_bkreport_prod_mcsimulation_success( assert output_files, "No OutputFile elements found." first_output_details = get_output_file_details(output_files[0]) - assert first_output_details["Name"] == wf_commons["production_output_data"][0] + assert first_output_details["Name"] == updated_wf_commons["production_output_data"][0] assert first_output_details["TypeName"] == "SIM" assert first_output_details["Parameters"]["FileSize"] == "0" assert "CreationDate" in first_output_details["Parameters"] @@ -519,7 +527,7 @@ def test_bkreport_prod_mcsimulation_success( assert len(output_files) == 1 def test_bkreport_prod_mcsimulation_noinputoutput_success( - self, bk_report, wf_commons, wf_commons_file, bookkeeping_file, xml_summary_file + self, bk_report, wf_commons, bookkeeping_file, xml_summary_file ): """Test successful execution of BookkeepingReport module. @@ -577,12 +585,14 @@ def test_bkreport_prod_mcsimulation_noinputoutput_success( wf_commons["xml_summary_path"] = xml_summary_file xf_o = prepare_XMLSummary_file(xml_summary_file, xml_content) - with open(wf_commons_file, "w", encoding="utf-8") as f: - json.dump(wf_commons, f) + wf_commons_path = create_workflow_commons(wf_commons) # Execute the module bk_report.execute(job_path) + with open(wf_commons_path, "r", encoding="utf-8") as f: + updated_wf_commons = json.load(f) + # Check if the XML report file is created xml_path = bookkeeping_file assert Path(xml_path).exists(), "XML report file not created." @@ -593,28 +603,28 @@ def test_bkreport_prod_mcsimulation_noinputoutput_success( # Extract fields from the XML and perform further operations assert root.tag == "Job", "Root tag should be Job." - assert root.attrib["ConfigName"] == wf_commons["config_name"] - assert root.attrib["ConfigVersion"] == wf_commons["config_version"] + assert root.attrib["ConfigName"] == updated_wf_commons["config_name"] + assert root.attrib["ConfigVersion"] == updated_wf_commons["config_version"] assert root.attrib["Date"] assert root.attrib["Time"] - assert get_typed_parameter_value("ProgramName", root) == wf_commons["application_name"] - assert get_typed_parameter_value("ProgramVersion", root) == wf_commons["application_version"] + assert get_typed_parameter_value("ProgramName", root) == updated_wf_commons["application_name"] + assert get_typed_parameter_value("ProgramVersion", root) == updated_wf_commons["application_version"] assert get_typed_parameter_value("DiracVersion", root) == LHCbDIRAC.__version__ - assert get_typed_parameter_value("Name", root) == wf_commons["command_id"] + assert get_typed_parameter_value("Name", root) == updated_wf_commons["command_id"] assert float(get_typed_parameter_value("ExecTime", root)) > 1000 assert get_typed_parameter_value("CPUTIME", root) == "0" assert get_typed_parameter_value("FirstEventNumber", root) == "1" - assert get_typed_parameter_value("StatisticsRequested", root) == str(wf_commons["number_of_events"]) + assert get_typed_parameter_value("StatisticsRequested", root) == str(updated_wf_commons["number_of_events"]) assert get_typed_parameter_value("NumberOfEvents", root) == str(xf_o.outputEventsTotal) - assert get_typed_parameter_value("Production", root) == wf_commons["production_id"] - assert get_typed_parameter_value("DiracJobId", root) == str(wf_commons["job_id"]) + assert get_typed_parameter_value("Production", root) == updated_wf_commons["production_id"] + assert get_typed_parameter_value("DiracJobId", root) == str(updated_wf_commons["job_id"]) assert get_typed_parameter_value("Location", root) == siteName() assert get_typed_parameter_value("JobStart", root) assert get_typed_parameter_value("JobEnd", root) - assert get_typed_parameter_value("JobType", root) == wf_commons["job_type"] + assert get_typed_parameter_value("JobType", root) == updated_wf_commons["job_type"] assert get_typed_parameter_value("WorkerNode", root) assert get_typed_parameter_value("WNMEMORY", root) @@ -632,9 +642,7 @@ def test_bkreport_prod_mcsimulation_noinputoutput_success( output_file = root.find("OutputFile") assert output_file is None, "OutputFile element should not be present." - def test_bk_report_prod_mcreconstruction_success( - self, bk_report, wf_commons, wf_commons_file, bookkeeping_file, xml_summary_file - ): + def test_bk_report_prod_mcreconstruction_success(self, bk_report, wf_commons, bookkeeping_file, xml_summary_file): """Test successful execution of BookkeepingReport module.""" wf_commons["application_name"] = "Boole" wf_commons["job_type"] = "MCReconstruction" @@ -682,12 +690,14 @@ def test_bk_report_prod_mcreconstruction_success( xf_o = prepare_XMLSummary_file(xml_summary_file, xml_content) - with open(wf_commons_file, "w", encoding="utf-8") as f: - json.dump(wf_commons, f) + wf_commons_path = create_workflow_commons(wf_commons) # Execute the module bk_report.execute(job_path) + with open(wf_commons_path, "r", encoding="utf-8") as f: + updated_wf_commons = json.load(f) + # Check if the XML report file is created xml_path = bookkeeping_file assert Path(xml_path).exists(), "XML report file not created." @@ -698,28 +708,28 @@ def test_bk_report_prod_mcreconstruction_success( # Extract fields from the XML and perform further operations assert root.tag == "Job", "Root tag should be Job." - assert root.attrib["ConfigName"] == wf_commons["config_name"] - assert root.attrib["ConfigVersion"] == wf_commons["config_version"] + assert root.attrib["ConfigName"] == updated_wf_commons["config_name"] + assert root.attrib["ConfigVersion"] == updated_wf_commons["config_version"] assert root.attrib["Date"] assert root.attrib["Time"] - assert get_typed_parameter_value("ProgramName", root) == wf_commons["application_name"] - assert get_typed_parameter_value("ProgramVersion", root) == wf_commons["application_version"] + assert get_typed_parameter_value("ProgramName", root) == updated_wf_commons["application_name"] + assert get_typed_parameter_value("ProgramVersion", root) == updated_wf_commons["application_version"] assert get_typed_parameter_value("DiracVersion", root) == LHCbDIRAC.__version__ - assert get_typed_parameter_value("Name", root) == wf_commons["command_id"] + assert get_typed_parameter_value("Name", root) == updated_wf_commons["command_id"] assert float(get_typed_parameter_value("ExecTime", root)) > 1000 assert get_typed_parameter_value("CPUTIME", root) == "0" assert get_typed_parameter_value("FirstEventNumber", root) == "1" - assert get_typed_parameter_value("StatisticsRequested", root) == str(wf_commons["number_of_events"]) + assert get_typed_parameter_value("StatisticsRequested", root) == str(updated_wf_commons["number_of_events"]) assert get_typed_parameter_value("NumberOfEvents", root) == str(xf_o.inputEventsTotal) - assert get_typed_parameter_value("Production", root) == wf_commons["production_id"] - assert get_typed_parameter_value("DiracJobId", root) == str(wf_commons["job_id"]) + assert get_typed_parameter_value("Production", root) == updated_wf_commons["production_id"] + assert get_typed_parameter_value("DiracJobId", root) == str(updated_wf_commons["job_id"]) assert get_typed_parameter_value("Location", root) == siteName() assert get_typed_parameter_value("JobStart", root) assert get_typed_parameter_value("JobEnd", root) - assert get_typed_parameter_value("JobType", root) == wf_commons["job_type"] + assert get_typed_parameter_value("JobType", root) == updated_wf_commons["job_type"] assert get_typed_parameter_value("WorkerNode", root) assert get_typed_parameter_value("WNMEMORY", root) @@ -738,7 +748,7 @@ def test_bk_report_prod_mcreconstruction_success( assert output_files, "No OutputFile elements found." first_output_details = get_output_file_details(output_files[0]) - assert first_output_details["Name"] == wf_commons["production_output_data"][0] + assert first_output_details["Name"] == updated_wf_commons["production_output_data"][0] assert first_output_details["TypeName"] == "DIGI" assert first_output_details["Parameters"]["FileSize"] == "0" assert "CreationDate" in first_output_details["Parameters"] @@ -751,15 +761,14 @@ def test_bk_report_prod_mcreconstruction_success( simulation_condition = root.find("SimulationCondition") assert simulation_condition is None, "SimulationCondition element should not be present." - def test_bkreport_previousError_success(self, mocker, bk_report, wf_commons, wf_commons_file, bookkeeping_file): + def test_bkreport_previousError_success(self, mocker, bk_report, wf_commons, bookkeeping_file): """Test previous command failure.""" wf_commons["application_name"] = "Gauss" wf_commons["application_version"] = wf_commons["config_version"] wf_commons["job_type"] = "MCSimulation" wf_commons["step_status"] = S_ERROR() - with open(wf_commons_file, "w", encoding="utf-8") as f: - json.dump(wf_commons, f) + create_workflow_commons(wf_commons) bk_report.execute(job_path) @@ -779,9 +788,7 @@ def failover_request(self, mocker: MockerFixture): yield FailoverRequest() - def test_failoverRequest_success( - self, mocker: MockerFixture, failover_request, wf_commons, wf_commons_file, request_file - ): + def test_failoverRequest_success(self, mocker: MockerFixture, failover_request, wf_commons, request_file): """Test successful execution of FailoverRequest module.""" problematic_files = [ "/lhcb/data/2010/EW.DST/00008380/0000/00008380_00000287_1.ew.dst", @@ -805,12 +812,11 @@ def test_failoverRequest_success( "/lhcb/data/2011/EW.DST/00008380/0000/00008380_00000281_1.ew.dst", ] + problematic_files - with open(wf_commons_file, "w", encoding="utf-8") as f: - json.dump(wf_commons, f) + wf_commons_path = create_workflow_commons(wf_commons) failover_request.execute(job_path) - with open(wf_commons_file, "r", encoding="utf-8") as f: + with open(wf_commons_path, "r", encoding="utf-8") as f: updated_wf_commons = json.load(f) # Check the FileReport calls: the problematic file should not appear @@ -829,7 +835,6 @@ def test_failoverRequest_success( assert jr.setApplicationStatus.call_count == 1 assert jr.setApplicationStatus.call_args[0][0] == "Job Finished Successfully" - print(updated_wf_commons) # Make sure the forward DISET is not generated operations = updated_wf_commons["request_dict"]["Operations"] assert len(operations) == 0 @@ -837,9 +842,7 @@ def test_failoverRequest_success( # Make sure the request json does not exists assert not Path(request_file).exists() - def test_failoverRequest_commitFailure1( - self, mocker: MockerFixture, failover_request, wf_commons, wf_commons_file, request_file - ): + def test_failoverRequest_commitFailure1(self, mocker: MockerFixture, failover_request, wf_commons, request_file): """Test execution of FailoverRequest module when the fileReport.commit() fails. In this context, the second call to commit() will work, so the request should not be generated. @@ -867,12 +870,11 @@ def test_failoverRequest_commitFailure1( ] + problematic_files # Execute the module - with open(wf_commons_file, "w", encoding="utf-8") as f: - json.dump(wf_commons, f) + wf_commons_path = create_workflow_commons(wf_commons) failover_request.execute(job_path) - with open(wf_commons_file, "r", encoding="utf-8") as f: + with open(wf_commons_path, "r", encoding="utf-8") as f: updated_wf_commons = json.load(f) # Check the FileReport calls: the problematic file should not appear @@ -898,9 +900,7 @@ def test_failoverRequest_commitFailure1( # Make sure the request json does not exists assert not Path(request_file).exists() - def test_failoverRequest_commitFailure2( - self, mocker: MockerFixture, failover_request, wf_commons, wf_commons_file, request_file - ): + def test_failoverRequest_commitFailure2(self, mocker: MockerFixture, failover_request, wf_commons, request_file): """Test execution of FailoverRequest module when the fileReport.commit() fails. In this context, the second call to commit() will fail, so the request should be generated. @@ -927,13 +927,12 @@ def test_failoverRequest_commitFailure2( "/lhcb/data/2011/EW.DST/00008380/0000/00008380_00000281_1.ew.dst", ] + problematic_files - with open(wf_commons_file, "w", encoding="utf-8") as f: - json.dump(wf_commons, f) + wf_commons_path = create_workflow_commons(wf_commons) # Execute the module failover_request.execute(job_path) - with open(wf_commons_file, "r", encoding="utf-8") as f: + with open(wf_commons_path, "r", encoding="utf-8") as f: updated_wf_commons = json.load(f) # Check the FileReport calls: the problematic file should not appear @@ -962,7 +961,7 @@ def test_failoverRequest_commitFailure2( assert Path(request_file).exists() def test_failoverRequest_previousError_fail( - self, mocker: MockerFixture, failover_request, wf_commons, wf_commons_file, request_file + self, mocker: MockerFixture, failover_request, wf_commons, request_file ): """Test FailoverRequest with an intentional failure.""" problematic_files = [ @@ -989,13 +988,12 @@ def test_failoverRequest_previousError_fail( # Intentional error wf_commons["step_status"] = S_ERROR() - with open(wf_commons_file, "w", encoding="utf-8") as f: - json.dump(wf_commons, f) + wf_commons_path = create_workflow_commons(wf_commons) # Execute the module failover_request.execute(job_path) - with open(wf_commons_file, "r", encoding="utf-8") as f: + with open(wf_commons_path, "r", encoding="utf-8") as f: updated_wf_commons = json.load(f) # Check the FileReport calls: the problematic file should not appear @@ -1019,3 +1017,785 @@ def test_failoverRequest_previousError_fail( # Make sure the request json does not exists assert not Path(request_file).exists() + + +class TestUploadOutputDataFile: + """Collection of tests for the UploadOutputData command.""" + + OUTPUT_DATA_STEP = "1" + + @pytest.fixture + def sim_file(self, wf_commons): + """Sim result file fixture.""" + path = f"{wf_commons['production_id']}_{wf_commons['prod_job_id']}_{self.OUTPUT_DATA_STEP}.sim" + with open(path, "w") as f: + f.write("Bookkeeping file content") + yield path + Path(path).unlink(missing_ok=True) + + @pytest.fixture + def bk_file(self, wf_commons): + """Bookkeeping file fixture.""" + path = os.path.join(job_path, f"bookkeeping_{wf_commons['production_id']}_{wf_commons['prod_job_id']}.xml") + with open(path, "w") as f: + f.write("Sim file content") + yield path + Path(path).unlink(missing_ok=True) + + @pytest.fixture + def watchdog_file(self, wf_commons): + """Watchdog file fixture.""" + path = os.path.join(job_path, "DISABLE_WATCHDOG_CPU_WALLCLOCK_CHECK") + yield path + Path(path).unlink(missing_ok=True) + + @pytest.fixture + def upload_output(self, mocker, wf_commons): + """Fixture for UploadOutputData module.""" + mocker.patch("dirac_cwl.commands.upload_output_data.getDestinationSEList", return_value=["CERN", "CNAF"]) + mocker.patch("LHCbDIRAC.Workflow.Modules.UploadOutputData.getDestinationSEList", return_value=["CERN", "CNAF"]) + + # Mock FileCatalog + mocker.patch("DIRAC.Resources.Catalog.FileCatalog.FileCatalog.__init__", return_value=None) + mocker.patch("DIRAC.Resources.Catalog.FileCatalog.FileCatalog.__getattr__", return_value=lambda x: S_OK({})) + + if "ProductionOutputData" in wf_commons: + wf_commons.pop("ProductionOutputData") + + upload_output = UploadOutputData() + + yield upload_output + + # Test Scenarios + def test_uploadOutputData_success(self, mocker, upload_output, wf_commons, sim_file, bk_file): + """Test successful execution of UploadOutputData module. + + * The output should be uploaded and registered in the bookkeeping system. + * The bookkeeping report should be sent and the job parameter updated. + """ + mock_file_report = mocker.patch("dirac_cwl.commands.upload_output_data.FileReport") + mock_job_report = mocker.patch("dirac_cwl.commands.upload_output_data.JobReport") + mock_request = mocker.patch("dirac_cwl.commands.upload_output_data.Request") + mock_failover = mocker.patch("dirac_cwl.commands.upload_output_data.FailoverTransfer") + mock_bk_client = mocker.patch("dirac_cwl.commands.upload_output_data.BookkeepingClient") + + fr = FileReport() + mocker.patch.object(fr, "setFileStatus") + mock_file_report.return_value = fr + + jr = JobReport(wf_commons["job_id"]) + mocker.patch.object(jr, "setJobParameter") + mock_job_report.return_value = jr + + req = Request() + mock_request.return_value = req + + failover = FailoverTransfer(req) + mocker.patch.object( + failover, "transferAndRegisterFile", return_value=S_OK({"uploadedSE": "CERN", "lfn": sim_file}) + ) + mocker.patch.object(failover, "transferAndRegisterFileFailover") + mock_failover.return_value = failover + + bkClient = BookkeepingClient() + mocker.patch.object(bkClient, "sendXMLBookkeepingReport", return_value=S_OK()) + mock_bk_client.return_value = bkClient + + wf_commons["outputs"] = [ + {"outputDataName": sim_file, "outputDataType": "sim", "outputBKType": "SIM", "stepName": "Gauss_1"} + ] + wf_commons["output_SEs"] = { + "SIM": "Tier1-Buffer", + } + wf_commons["output_data_step"] = self.OUTPUT_DATA_STEP + + wf_commons_path = create_workflow_commons(wf_commons) + + # Execute module + upload_output.execute(job_path) + + with open(wf_commons_path, "r", encoding="utf-8") as f: + updated_wf_commons = json.load(f) + + assert fr.setFileStatus.call_count == 0 + assert bkClient.sendXMLBookkeepingReport.call_count == 1 + + assert failover.transferAndRegisterFile.call_count == 1 + assert failover.transferAndRegisterFile.call_args[1]["fileName"] == sim_file + + assert failover.transferAndRegisterFileFailover.call_count == 0 + + assert jr.setJobParameter.call_count == 1 + assert jr.setJobParameter.call_args[0][0] == "UploadedOutputData" + assert jr.setJobParameter.call_args[0][1] == sim_file + + # Make sure the forward DISET is not generated + operations = updated_wf_commons["request_dict"]["Operations"] + assert len(operations) == 0 + + def test_uploadOutputData_failedBKRegistration(self, mocker, upload_output, wf_commons, sim_file, bk_file): + """Test execution of UploadOutputData module when the BK registation fails. + + * The output should be uploaded but not registered in the bookkeeping system now. + """ + mock_file_report = mocker.patch("dirac_cwl.commands.upload_output_data.FileReport") + mock_job_report = mocker.patch("dirac_cwl.commands.upload_output_data.JobReport") + mock_request = mocker.patch("dirac_cwl.commands.upload_output_data.Request") + mock_failover = mocker.patch("dirac_cwl.commands.upload_output_data.FailoverTransfer") + mock_bk_client = mocker.patch("dirac_cwl.commands.upload_output_data.BookkeepingClient") + + fr = FileReport() + mocker.patch.object(fr, "setFileStatus") + mock_file_report.return_value = fr + + jr = JobReport(wf_commons["job_id"]) + mocker.patch.object(jr, "setJobParameter") + mock_job_report.return_value = jr + + req = Request() + mock_request.return_value = req + + failover = FailoverTransfer(req) + mocker.patch.object( + failover, "transferAndRegisterFile", return_value=S_OK({"uploadedSE": "CERN", "lfn": sim_file}) + ) + mocker.patch.object(failover, "transferAndRegisterFileFailover") + mock_failover.return_value = failover + + bkClient = BookkeepingClient() + mocker.patch.object(bkClient, "sendXMLBookkeepingReport", return_value=S_OK()) + mock_bk_client.return_value = bkClient + + # BK registration failure + mocker.patch( + "DIRAC.Resources.Catalog.FileCatalog.FileCatalog.__getattr__", + return_value=lambda x: S_OK( + { + "Failed": { + f"/lhcb/{wf_commons['config_name']}/{wf_commons['config_version']}/" + f"SIM/00000{wf_commons['production_id']}/0000/{sim_file}": "error" + } + } + ), + ) + + wf_commons["outputs"] = [ + {"outputDataName": sim_file, "outputDataType": "sim", "outputBKType": "SIM", "stepName": "Gauss_1"} + ] + wf_commons["output_SEs"] = { + "SIM": "Tier1-Buffer", + } + wf_commons["output_data_step"] = self.OUTPUT_DATA_STEP + + wf_commons_path = create_workflow_commons(wf_commons) + + # Execute module + upload_output.execute(job_path) + + with open(wf_commons_path, "r", encoding="utf-8") as f: + updated_wf_commons = json.load(f) + + assert fr.setFileStatus.call_count == 0 + assert bkClient.sendXMLBookkeepingReport.call_count == 1 + + assert failover.transferAndRegisterFile.call_count == 1 + assert failover.transferAndRegisterFile.call_args[1]["fileName"] == sim_file + + assert failover.transferAndRegisterFileFailover.call_count == 0 + + assert jr.setJobParameter.call_count == 1 + assert jr.setJobParameter.call_args[0][0] == "UploadedOutputData" + assert jr.setJobParameter.call_args[0][1] == sim_file + + # Make sure the request is generated + operations = updated_wf_commons["request_dict"]["Operations"] + assert len(operations) == 1 + + assert operations[0]["Type"] == "RegisterFile" + assert operations[0]["Catalog"] == "BookkeepingDB" + assert sim_file in operations[0]["Files"][0]["LFN"] + + def test_uploadOutputData_postponeBKRegistration(self, mocker, upload_output, wf_commons, sim_file, bk_file): + """Test execution of UploadOutputData module when there is already a RegisterFile operation on the output. + + * The output should be uploaded but not registered in the bookkeeping system now. + """ + mock_file_report = mocker.patch("dirac_cwl.commands.upload_output_data.FileReport") + mock_job_report = mocker.patch("dirac_cwl.commands.upload_output_data.JobReport") + mock_request = mocker.patch("dirac_cwl.commands.upload_output_data.Request") + mock_failover = mocker.patch("dirac_cwl.commands.upload_output_data.FailoverTransfer") + mock_bk_client = mocker.patch("dirac_cwl.commands.upload_output_data.BookkeepingClient") + + fr = FileReport() + mocker.patch.object(fr, "setFileStatus") + mock_file_report.return_value = fr + + jr = JobReport(wf_commons["job_id"]) + mocker.patch.object(jr, "setJobParameter") + mock_job_report.return_value = jr + + # Mock a previous failover request: the BK registration should be postponed and added to the request + req = Request() + file1 = File() + file1.LFN = ( + f"/lhcb/{wf_commons['config_name']}/{wf_commons['config_version']}" + f"/SIM/00000{wf_commons['production_id']}/0000/{sim_file}" + ) + o1 = Operation() + o1.Type = "RegisterFile" + o1.addFile(file1) + req.addOperation(o1) + mock_request.return_value = req + + failover = FailoverTransfer(req) + mocker.patch.object( + failover, "transferAndRegisterFile", return_value=S_OK({"uploadedSE": "CERN", "lfn": sim_file}) + ) + mocker.patch.object(failover, "transferAndRegisterFileFailover") + mock_failover.return_value = failover + + bkClient = BookkeepingClient() + mocker.patch.object(bkClient, "sendXMLBookkeepingReport", return_value=S_OK()) + mock_bk_client.return_value = bkClient + + wf_commons["outputs"] = [ + {"outputDataName": sim_file, "outputDataType": "sim", "outputBKType": "SIM", "stepName": "Gauss_1"} + ] + wf_commons["output_SEs"] = { + "SIM": "Tier1-Buffer", + } + wf_commons["output_data_step"] = self.OUTPUT_DATA_STEP + + wf_commons_path = create_workflow_commons(wf_commons) + + # Execute module + upload_output.execute(job_path) + + with open(wf_commons_path, "r", encoding="utf-8") as f: + updated_wf_commons = json.load(f) + + assert fr.setFileStatus.call_count == 0 + assert bkClient.sendXMLBookkeepingReport.call_count == 1 + + assert failover.transferAndRegisterFile.call_count == 1 + assert failover.transferAndRegisterFile.call_args[1]["fileName"] == sim_file + + assert failover.transferAndRegisterFileFailover.call_count == 0 + + assert jr.setJobParameter.call_count == 1 + assert jr.setJobParameter.call_args[0][0] == "UploadedOutputData" + assert jr.setJobParameter.call_args[0][1] == sim_file + + # Make sure the request is generated + operations = updated_wf_commons["request_dict"]["Operations"] + assert len(operations) == 2 + + assert operations[0]["Type"] == "RegisterFile" + assert operations[0]["Catalog"] is None + assert sim_file in operations[0]["Files"][0]["LFN"] + + assert operations[1]["Type"] == "RegisterFile" + assert operations[1]["Catalog"] == "BookkeepingDB" + assert sim_file in operations[1]["Files"][0]["LFN"] + + def test_uploadOutputData_errorBKRegistration(self, mocker, upload_output, wf_commons, sim_file, bk_file): + """Test execution of UploadOutputData module when an error occurs during the BK registation. + + * The output should be uploaded but not registered in the bookkeeping system at all. + """ + mock_file_report = mocker.patch("dirac_cwl.commands.upload_output_data.FileReport") + mock_job_report = mocker.patch("dirac_cwl.commands.upload_output_data.JobReport") + mock_request = mocker.patch("dirac_cwl.commands.upload_output_data.Request") + mock_failover = mocker.patch("dirac_cwl.commands.upload_output_data.FailoverTransfer") + mock_bk_client = mocker.patch("dirac_cwl.commands.upload_output_data.BookkeepingClient") + + fr = FileReport() + mocker.patch.object(fr, "setFileStatus") + mock_file_report.return_value = fr + + jr = JobReport(wf_commons["job_id"]) + mocker.patch.object(jr, "setJobParameter") + mock_job_report.return_value = jr + + req = Request() + mock_request.return_value = req + + failover = FailoverTransfer(req) + mocker.patch.object( + failover, "transferAndRegisterFile", return_value=S_OK({"uploadedSE": "CERN", "lfn": sim_file}) + ) + mocker.patch.object(failover, "transferAndRegisterFileFailover") + mock_failover.return_value = failover + + bkClient = BookkeepingClient() + mocker.patch.object(bkClient, "sendXMLBookkeepingReport", return_value=S_OK()) + mock_bk_client.return_value = bkClient + + # BK registration failure + mocker.patch( + "DIRAC.Resources.Catalog.FileCatalog.FileCatalog.__getattr__", + return_value=lambda x: S_ERROR("Error registering file"), + ) + + wf_commons["outputs"] = [ + {"outputDataName": sim_file, "outputDataType": "sim", "outputBKType": "SIM", "stepName": "Gauss_1"} + ] + wf_commons["output_SEs"] = { + "SIM": "Tier1-Buffer", + } + wf_commons["output_data_step"] = self.OUTPUT_DATA_STEP + + # BK registration failure + mocker.patch( + "DIRAC.Resources.Catalog.FileCatalog.FileCatalog.__getattr__", + return_value=lambda x: S_ERROR("Error registering file"), + ) + + wf_commons_path = create_workflow_commons(wf_commons) + + # Execute module + with pytest.raises(WorkflowProcessingException, match="Could Not Perform BK Registration"): + upload_output.execute(job_path) + + with open(wf_commons_path, "r", encoding="utf-8") as f: + updated_wf_commons = json.load(f) + + assert fr.setFileStatus.call_count == 0 + assert bkClient.sendXMLBookkeepingReport.call_count == 1 + + assert failover.transferAndRegisterFile.call_count == 1 + assert failover.transferAndRegisterFile.call_args[1]["fileName"] == sim_file + + assert failover.transferAndRegisterFileFailover.call_count == 0 + + assert jr.setJobParameter.call_count == 1 + assert jr.setJobParameter.call_args[0][0] == "UploadedOutputData" + assert jr.setJobParameter.call_args[0][1] == sim_file + + # Make sure the request is generated + operations = updated_wf_commons["request_dict"]["Operations"] + assert len(operations) == 0 + + def test_uploadOutputData_failUpload1(self, mocker, upload_output, wf_commons, sim_file, bk_file): + """Test execution of UploadOutputData module when there is a 1st failure to upload outputs. + + * The output should be uploaded correctly with the second method. + """ + mock_file_report = mocker.patch("dirac_cwl.commands.upload_output_data.FileReport") + mock_job_report = mocker.patch("dirac_cwl.commands.upload_output_data.JobReport") + mock_request = mocker.patch("dirac_cwl.commands.upload_output_data.Request") + mock_failover = mocker.patch("dirac_cwl.commands.upload_output_data.FailoverTransfer") + mock_bk_client = mocker.patch("dirac_cwl.commands.upload_output_data.BookkeepingClient") + + fr = FileReport() + mocker.patch.object(fr, "setFileStatus") + mock_file_report.return_value = fr + + jr = JobReport(wf_commons["job_id"]) + mocker.patch.object(jr, "setJobParameter") + mock_job_report.return_value = jr + + req = Request() + mock_request.return_value = req + + failover = FailoverTransfer(req) + mocker.patch.object(failover, "transferAndRegisterFile", return_value=S_ERROR("Error uploading file")) + mocker.patch.object(failover, "transferAndRegisterFileFailover", return_value=S_OK()) + mock_failover.return_value = failover + + bkClient = BookkeepingClient() + mocker.patch.object(bkClient, "sendXMLBookkeepingReport", return_value=S_OK()) + mock_bk_client.return_value = bkClient + + wf_commons["outputs"] = [ + {"outputDataName": sim_file, "outputDataType": "sim", "outputBKType": "SIM", "stepName": "Gauss_1"} + ] + wf_commons["output_SEs"] = { + "SIM": "Tier1-Buffer", + } + wf_commons["output_data_step"] = self.OUTPUT_DATA_STEP + + wf_commons_path = create_workflow_commons(wf_commons) + + # Execute module + upload_output.execute(job_path) + + with open(wf_commons_path, "r", encoding="utf-8") as f: + updated_wf_commons = json.load(f) + + assert fr.setFileStatus.call_count == 0 + assert bkClient.sendXMLBookkeepingReport.call_count == 1 + + assert failover.transferAndRegisterFile.call_count == 1 + assert failover.transferAndRegisterFile.call_args[1]["fileName"] == sim_file + + assert failover.transferAndRegisterFileFailover.call_count == 1 + assert failover.transferAndRegisterFileFailover.call_args[1]["fileName"] == sim_file + + assert jr.setJobParameter.call_count == 1 + assert jr.setJobParameter.call_args[0][0] == "UploadedOutputData" + assert jr.setJobParameter.call_args[0][1] == sim_file + + # Make sure the request is not generated + operations = updated_wf_commons["request_dict"]["Operations"] + assert len(operations) == 0 + + def test_uploadOutputData_failUpload2(self, mocker, upload_output, wf_commons, sim_file, bk_file): + """Test execution of UploadOutputData module when there is a 2 failures to upload outputs. + + * A request should be generated to upload outputs later. + """ + mock_file_report = mocker.patch("dirac_cwl.commands.upload_output_data.FileReport") + mock_job_report = mocker.patch("dirac_cwl.commands.upload_output_data.JobReport") + mock_request = mocker.patch("dirac_cwl.commands.upload_output_data.Request") + mock_failover = mocker.patch("dirac_cwl.commands.upload_output_data.FailoverTransfer") + mock_bk_client = mocker.patch("dirac_cwl.commands.upload_output_data.BookkeepingClient") + + fr = FileReport() + mocker.patch.object(fr, "setFileStatus") + mock_file_report.return_value = fr + + jr = JobReport(wf_commons["job_id"]) + mocker.patch.object(jr, "setJobParameter") + mock_job_report.return_value = jr + + # Mock a previous failover request: + # Add the end of the execution, o1 should be removed + req = Request() + + file1 = File() + file1.LFN = ( + f"/lhcb/{wf_commons['config_name']}/{wf_commons['config_version']}" + f"/SIM/00000{wf_commons['production_id']}/0000/{sim_file}" + ) + file2 = File() + file2.LFN = "/another/file.txt" + + o1 = Operation() + o1.Type = "RegisterFile" + o1.addFile(file1) + o2 = Operation() + o2.Type = "RegisterFile" + o2.addFile(file2) + + req.addOperation(o1) + req.addOperation(o2) + + mock_request.return_value = req + + failover = FailoverTransfer(req) + mocker.patch.object(failover, "transferAndRegisterFile", return_value=S_ERROR("Error uploading file")) + mocker.patch.object(failover, "transferAndRegisterFileFailover", return_value=S_ERROR("Error uploading file")) + mock_failover.return_value = failover + + bkClient = BookkeepingClient() + mocker.patch.object(bkClient, "sendXMLBookkeepingReport", return_value=S_OK()) + mock_bk_client.return_value = bkClient + + wf_commons["outputs"] = [ + {"outputDataName": sim_file, "outputDataType": "sim", "outputBKType": "SIM", "stepName": "Gauss_1"} + ] + wf_commons["output_SEs"] = { + "SIM": "Tier1-Buffer", + } + wf_commons["output_data_step"] = self.OUTPUT_DATA_STEP + + wf_commons_path = create_workflow_commons(wf_commons) + + # Execute module + with pytest.raises(WorkflowProcessingException, match="Failed to upload output data"): + upload_output.execute(job_path) + + with open(wf_commons_path, "r", encoding="utf-8") as f: + updated_wf_commons = json.load(f) + + assert fr.setFileStatus.call_count == 0 + assert bkClient.sendXMLBookkeepingReport.call_count == 1 + + assert failover.transferAndRegisterFile.call_count == 1 + assert failover.transferAndRegisterFile.call_args[1]["fileName"] == sim_file + + assert failover.transferAndRegisterFileFailover.call_count == 1 + assert failover.transferAndRegisterFileFailover.call_args[1]["fileName"] == sim_file + + assert jr.setJobParameter.call_count == 0 + + # Make sure the request is generated + + operations = updated_wf_commons["request_dict"]["Operations"] + assert len(operations) == 2 + + assert operations[0]["Type"] == "RegisterFile" + assert operations[0]["TargetSE"] is None + assert operations[0]["SourceSE"] is None + assert sim_file not in operations[0]["Files"][0]["LFN"] + + assert operations[1]["Type"] == "RemoveFile" + assert operations[1]["TargetSE"] is None + assert operations[1]["SourceSE"] is None + assert sim_file in operations[1]["Files"][0]["LFN"] + + def test_uploadOutputData_BKReportError(self, mocker, upload_output, wf_commons, sim_file, bk_file): + """Test execution of UploadOutputData module when the BK report cannot be sent. + + * The output should be uploaded and registered in the bookkeeping system. + * The bookkeeping report should be added to a failover request. + """ + mock_file_report = mocker.patch("dirac_cwl.commands.upload_output_data.FileReport") + mock_job_report = mocker.patch("dirac_cwl.commands.upload_output_data.JobReport") + mock_request = mocker.patch("dirac_cwl.commands.upload_output_data.Request") + mock_failover = mocker.patch("dirac_cwl.commands.upload_output_data.FailoverTransfer") + mock_bk_client = mocker.patch("dirac_cwl.commands.upload_output_data.BookkeepingClient") + + fr = FileReport() + mocker.patch.object(fr, "setFileStatus") + mock_file_report.return_value = fr + + jr = JobReport(wf_commons["job_id"]) + mocker.patch.object(jr, "setJobParameter") + mock_job_report.return_value = jr + + req = Request() + mock_request.return_value = req + + failover = FailoverTransfer(req) + mocker.patch.object( + failover, "transferAndRegisterFile", return_value=S_OK({"uploadedSE": "CERN", "lfn": sim_file}) + ) + mocker.patch.object(failover, "transferAndRegisterFileFailover", return_value=S_ERROR("Error uploading file")) + mock_failover.return_value = failover + + bkClient = BookkeepingClient() + # Mock the sendXMLBookkeepingReport method + mocker.patch.object( + bkClient, + "sendXMLBookkeepingReport", + return_value={"OK": False, "rpcStub": "Error", "Message": "Error sending BK report"}, + ) + mock_bk_client.return_value = bkClient + + wf_commons["outputs"] = [ + {"outputDataName": sim_file, "outputDataType": "sim", "outputBKType": "SIM", "stepName": "Gauss_1"} + ] + wf_commons["output_SEs"] = { + "SIM": "Tier1-Buffer", + } + wf_commons["output_data_step"] = self.OUTPUT_DATA_STEP + + wf_commons_path = create_workflow_commons(wf_commons) + + # Execute module + upload_output.execute(job_path) + + with open(wf_commons_path, "r", encoding="utf-8") as f: + updated_wf_commons = json.load(f) + + assert fr.setFileStatus.call_count == 0 + assert bkClient.sendXMLBookkeepingReport.call_count == 1 + + assert failover.transferAndRegisterFile.call_count == 1 + assert failover.transferAndRegisterFile.call_args[1]["fileName"] == sim_file + + assert failover.transferAndRegisterFileFailover.call_count == 0 + + assert jr.setJobParameter.call_count == 1 + assert jr.setJobParameter.call_args[0][0] == "UploadedOutputData" + assert jr.setJobParameter.call_args[0][1] == sim_file + + # Make sure the request is not generated + operations = updated_wf_commons["request_dict"]["Operations"] + assert len(operations) == 1 + + assert operations[0]["Type"] == "ForwardDISET" + + def test_uploadOutputData_withDescendents(self, mocker, upload_output, wf_commons, sim_file, bk_file): + """Test execution of UploadOutputData module when there is already file descendants. + + It means that the input data has already been processed. + * The output should not be uploaded and registered in the bookkeeping system. + * The bookkeeping report should not be sent. + """ + mock_file_report = mocker.patch("dirac_cwl.commands.upload_output_data.FileReport") + mock_job_report = mocker.patch("dirac_cwl.commands.upload_output_data.JobReport") + mock_request = mocker.patch("dirac_cwl.commands.upload_output_data.Request") + mock_failover = mocker.patch("dirac_cwl.commands.upload_output_data.FailoverTransfer") + mock_bk_client = mocker.patch("dirac_cwl.commands.upload_output_data.BookkeepingClient") + + mocker.patch( + "dirac_cwl.commands.upload_output_data.getFileDescendents", return_value=S_OK(["/path/to/other/file.txt"]) + ) + + fr = FileReport() + mocker.patch.object(fr, "setFileStatus") + mock_file_report.return_value = fr + + jr = JobReport(wf_commons["job_id"]) + mocker.patch.object(jr, "setJobParameter") + mock_job_report.return_value = jr + + req = Request() + mock_request.return_value = req + + failover = FailoverTransfer(req) + mocker.patch.object( + failover, "transferAndRegisterFile", return_value=S_OK({"uploadedSE": "CERN", "lfn": sim_file}) + ) + mocker.patch.object(failover, "transferAndRegisterFileFailover") + mock_failover.return_value = failover + + bkClient = BookkeepingClient() + mocker.patch.object(bkClient, "sendXMLBookkeepingReport") + mock_bk_client.return_value = bkClient + + wf_commons["outputs"] = [ + {"outputDataName": sim_file, "outputDataType": "sim", "outputBKType": "SIM", "stepName": "Gauss_1"} + ] + wf_commons["output_SEs"] = { + "SIM": "Tier1-Buffer", + } + wf_commons["inputs"] = ["AnyInputFile1"] + wf_commons["output_data_step"] = self.OUTPUT_DATA_STEP + + wf_commons_path = create_workflow_commons(wf_commons) + + # Execute module + with pytest.raises(WorkflowProcessingException): + upload_output.execute(job_path) + + with open(wf_commons_path, "r", encoding="utf-8") as f: + updated_wf_commons = json.load(f) + + assert fr.setFileStatus.call_count == 1 + assert fr.setFileStatus.call_args[0][0] == int(wf_commons["production_id"]) + assert bkClient.sendXMLBookkeepingReport.call_count == 0 + + assert failover.transferAndRegisterFile.call_count == 0 + assert failover.transferAndRegisterFileFailover.call_count == 0 + + assert jr.setJobParameter.call_count == 0 + + # Make sure the request is not generated + operations = updated_wf_commons["request_dict"]["Operations"] + assert len(operations) == 0 + + def test_uploadOutputData_noOutput(self, mocker, upload_output, wf_commons, sim_file): + """Test UploadOutputData with no output data.""" + mock_file_report = mocker.patch("dirac_cwl.commands.upload_output_data.FileReport") + mock_job_report = mocker.patch("dirac_cwl.commands.upload_output_data.JobReport") + mock_request = mocker.patch("dirac_cwl.commands.upload_output_data.Request") + mock_failover = mocker.patch("dirac_cwl.commands.upload_output_data.FailoverTransfer") + mock_bk_client = mocker.patch("dirac_cwl.commands.upload_output_data.BookkeepingClient") + + fr = FileReport() + mocker.patch.object(fr, "setFileStatus") + mock_file_report.return_value = fr + + jr = JobReport(wf_commons["job_id"]) + mocker.patch.object(jr, "setJobParameter") + mock_job_report.return_value = jr + + req = Request() + mock_request.return_value = req + + failover = FailoverTransfer(req) + mocker.patch.object( + failover, "transferAndRegisterFile", return_value=S_OK({"uploadedSE": "CERN", "lfn": sim_file}) + ) + mocker.patch.object(failover, "transferAndRegisterFileFailover") + mock_failover.return_value = failover + + bkClient = BookkeepingClient() + mocker.patch.object(bkClient, "sendXMLBookkeepingReport") + mock_bk_client.return_value = bkClient + + wf_commons["outputs"] = [ + {"outputDataName": sim_file, "outputDataType": "sim", "outputBKType": "SIM", "stepName": "Gauss_1"} + ] + wf_commons["output_SEs"] = { + "SIM": "Tier1-Buffer", + } + wf_commons["output_data_step"] = self.OUTPUT_DATA_STEP + + # Remove the output + Path(sim_file).unlink(missing_ok=True) + + wf_commons_path = create_workflow_commons(wf_commons) + + # Execute module + with pytest.raises(OSError, match="Output data not found"): + upload_output.execute(job_path) + + with open(wf_commons_path, "r", encoding="utf-8") as f: + updated_wf_commons = json.load(f) + + assert fr.setFileStatus.call_count == 0 + assert bkClient.sendXMLBookkeepingReport.call_count == 0 + + assert failover.transferAndRegisterFile.call_count == 0 + assert failover.transferAndRegisterFileFailover.call_count == 0 + + assert jr.setJobParameter.call_count == 0 + + # Make sure the request is not generated + print(updated_wf_commons) + operations = updated_wf_commons["request_dict"]["Operations"] + assert len(operations) == 0 + + def test_uploadOutputData_previousError_fail(self, mocker, upload_output, wf_commons, sim_file): + """Test UploadOutputData with an intentional failure.""" + mock_file_report = mocker.patch("dirac_cwl.commands.upload_output_data.FileReport") + mock_job_report = mocker.patch("dirac_cwl.commands.upload_output_data.JobReport") + mock_request = mocker.patch("dirac_cwl.commands.upload_output_data.Request") + mock_failover = mocker.patch("dirac_cwl.commands.upload_output_data.FailoverTransfer") + mock_bk_client = mocker.patch("dirac_cwl.commands.upload_output_data.BookkeepingClient") + + fr = FileReport() + mocker.patch.object(fr, "setFileStatus") + mock_file_report.return_value = fr + + jr = JobReport(wf_commons["job_id"]) + mocker.patch.object(jr, "setJobParameter") + mock_job_report.return_value = jr + + req = Request() + mock_request.return_value = req + + failover = FailoverTransfer(req) + mocker.patch.object(failover, "transferAndRegisterFile") + mocker.patch.object(failover, "transferAndRegisterFileFailover") + mock_failover.return_value = failover + + bkClient = BookkeepingClient() + mocker.patch.object(bkClient, "sendXMLBookkeepingReport") + mock_bk_client.return_value = bkClient + + wf_commons["outputs"] = [ + {"outputDataName": sim_file, "outputDataType": "sim", "outputBKType": "SIM", "stepName": "Gauss_1"} + ] + wf_commons["output_SEs"] = { + "SIM": "Tier1-Buffer", + } + wf_commons["output_data_step"] = self.OUTPUT_DATA_STEP + + wf_commons["step_status"] = S_ERROR() + + Path(sim_file).unlink(missing_ok=True) + + wf_commons_path = create_workflow_commons(wf_commons) + + upload_output.execute(job_path) + + with open(wf_commons_path, "r", encoding="utf-8") as f: + updated_wf_commons = json.load(f) + + assert fr.setFileStatus.call_count == 0 + assert bkClient.sendXMLBookkeepingReport.call_count == 0 + + assert failover.transferAndRegisterFile.call_count == 0 + assert failover.transferAndRegisterFileFailover.call_count == 0 + + assert jr.setJobParameter.call_count == 0 + + # Make sure the request is not generated + operations = updated_wf_commons["request_dict"]["Operations"] + assert len(operations) == 0 From b87c180e9fb0faf6019d059903454eab378e7689 Mon Sep 17 00:00:00 2001 From: Jorge Lisa <64639359+AcquaDiGiorgio@users.noreply.github.com> Date: Wed, 6 May 2026 11:44:21 +0200 Subject: [PATCH 12/21] feat: Migrate AnalyseXmlSummary command to cwl-dirac --- src/dirac_cwl/commands/__init__.py | 2 + src/dirac_cwl/commands/analyze_xml_summary.py | 84 +++ test/test_commands.py | 573 +++++++++++++++++- 3 files changed, 658 insertions(+), 1 deletion(-) create mode 100644 src/dirac_cwl/commands/analyze_xml_summary.py diff --git a/src/dirac_cwl/commands/__init__.py b/src/dirac_cwl/commands/__init__.py index a2b6380..cd73a09 100644 --- a/src/dirac_cwl/commands/__init__.py +++ b/src/dirac_cwl/commands/__init__.py @@ -1,5 +1,6 @@ """Command classes for workflow pre/post-processing operations.""" +from .analyze_xml_summary import AnalyseXmlSummary from .bookkeeping_report import BookeepingReport from .core import PostProcessCommand, PreProcessCommand from .failover_request import FailoverRequest @@ -7,6 +8,7 @@ from .upload_output_data import UploadOutputData __all__ = [ + "AnalyseXmlSummary", "PreProcessCommand", "PostProcessCommand", "UploadLogFile", diff --git a/src/dirac_cwl/commands/analyze_xml_summary.py b/src/dirac_cwl/commands/analyze_xml_summary.py new file mode 100644 index 0000000..ecb1543 --- /dev/null +++ b/src/dirac_cwl/commands/analyze_xml_summary.py @@ -0,0 +1,84 @@ +"""LHCb command for checking the XMLSummary output to ensure that the execution was done correctly.""" + +import os + +from DIRAC.TransformationSystem.Client.FileReport import FileReport +from DIRAC.WorkloadManagementSystem.Client.JobReport import JobReport +from LHCbDIRAC.Core.Utilities.XMLSummaries import XMLSummary +from LHCbDIRAC.Workflow.Modules.AnalyseXMLSummary import _areInputsOK, _isXMLSummaryOK +from LHCbDIRAC.Workflow.Modules.BookkeepingReport import _generate_xml_object + +from dirac_cwl.core.exceptions import WorkflowProcessingException + +from .core import PostProcessCommand +from .utils import prepare_lhcb_workflow_commons, save_workflow_commons + + +class AnalyseXmlSummary(PostProcessCommand): + """Performs a series of checks on the XMLSummary output to make sure the execution was done correctly.""" + + def execute(self, job_path, **kwargs): + """Execute the command. + + :param job_path: Path to the job working directory. + :param kwargs: Additional keyword arguments. + """ + failed = False + try: + workflow_commons_path = kwargs.get("workflow_commons_path", os.path.join(job_path, "workflow_commons.json")) + + workflow_commons = prepare_lhcb_workflow_commons( + workflow_commons_path, + extra_mandatory_values=[ + "bk_step_id", + ], + extra_default_values={ + "bookkeeping_LFNs": [], + "size": {}, + "md5": {}, + "guid": {}, + "sim_description": "NoSimConditions", + }, + ) + + if not workflow_commons["step_status"]["OK"]: + return + + if "xml_summary_path" in workflow_commons: + xf_o = XMLSummary(workflow_commons["xml_summary_path"]) + else: + xf_o = _generate_xml_object( + workflow_commons["cleaned_application_name"], + workflow_commons["production_id"], + workflow_commons["prod_job_id"], + workflow_commons["command_number"], + workflow_commons["command_id"], + ) + + file_report = FileReport() + job_report = JobReport(workflow_commons["job_id"]) + + file_report.statusDict = workflow_commons["file_report_files_dict"] + + jobOk = _isXMLSummaryOK(xf_o) + + if jobOk: + jobOk = _areInputsOK( + xf_o, + workflow_commons["inputs"], + workflow_commons["number_of_events"], + workflow_commons["production_id"], + file_report, + ) + if not jobOk: + job_report.setApplicationStatus("XMLSummary reports error") + raise WorkflowProcessingException("XMLSummary reports error") + + job_report.setApplicationStatus(f"{workflow_commons['application_name']} Step OK") + + except: + failed = True + raise + + finally: + save_workflow_commons(workflow_commons, workflow_commons_path, failed=failed) diff --git a/test/test_commands.py b/test/test_commands.py index dfd6af7..d70639b 100644 --- a/test/test_commands.py +++ b/test/test_commands.py @@ -23,7 +23,7 @@ from LHCbDIRAC.Core.Utilities.XMLSummaries import XMLSummary from pytest_mock import MockerFixture -from dirac_cwl.commands import BookeepingReport, FailoverRequest, UploadLogFile, UploadOutputData +from dirac_cwl.commands import AnalyseXmlSummary, BookeepingReport, FailoverRequest, UploadLogFile, UploadOutputData from dirac_cwl.core.exceptions import WorkflowProcessingException number_of_processors = 1 @@ -1799,3 +1799,574 @@ def test_uploadOutputData_previousError_fail(self, mocker, upload_output, wf_com # Make sure the request is not generated operations = updated_wf_commons["request_dict"]["Operations"] assert len(operations) == 0 + + +class TestAnalyseXmlSummary: + """Collection of tests for the AnalyseXmlSummary command.""" + + @pytest.fixture + def axlf(self, mocker): + """Fixture for AnalyseXmlSummary module.""" + mocker.patch("LHCbDIRAC.Workflow.Modules.ModuleBase.RequestValidator") + + axlf = AnalyseXmlSummary() + + yield axlf + + # Test scenarios + def test_analyseXMLSummary_basic_success(self, mocker, axlf, wf_commons, xml_summary_file): + """Test basic success scenario.""" + mock_file_report = mocker.patch("dirac_cwl.commands.analyze_xml_summary.FileReport") + mock_job_report = mocker.patch("dirac_cwl.commands.analyze_xml_summary.JobReport") + + fr = FileReport() + + jr = JobReport(wf_commons["job_id"]) + mocker.patch.object(jr, "setApplicationStatus") + jr.setApplicationStatus.return_value = S_OK() + + mock_file_report.return_value = fr + mock_job_report.return_value = jr + + xml_content = dedent(""" + + True + finalize + + 866104.0 + + + 200 + + + 200 + + + """) + + xf_o = prepare_XMLSummary_file(xml_summary_file, xml_content) + wf_commons["xml_summary_path"] = xml_summary_file + wf_commons["number_of_events"] = -1 + + assert xf_o.success == "True" + assert xf_o.step == "finalize" + assert xf_o._outputsOK() + assert not xf_o.inputFileStats["mult"] + assert not xf_o.inputFileStats["other"] + + create_workflow_commons(wf_commons) + axlf.execute(job_path) + + jr.setApplicationStatus.assert_called_once() + assert fr.statusDict == {} + + def test_analyseXMLSummary_previousError_success(self, mocker, axlf, wf_commons, xml_summary_file): + """Test success scenario with previous error: stepStatus = S_ERROR().""" + mock_file_report = mocker.patch("dirac_cwl.commands.analyze_xml_summary.FileReport") + mock_job_report = mocker.patch("dirac_cwl.commands.analyze_xml_summary.JobReport") + + fr = FileReport() + + jr = JobReport(wf_commons["job_id"]) + mocker.patch.object(jr, "setApplicationStatus") + jr.setApplicationStatus.return_value = S_OK() + + mock_file_report.return_value = fr + mock_job_report.return_value = jr + + xml_content = dedent(""" + + True + finalize + + 866104.0 + + + 200 + + + 200 + + + """) + + xf_o = prepare_XMLSummary_file(xml_summary_file, xml_content) + wf_commons["xml_summary_path"] = xml_summary_file + wf_commons["step_status"] = S_ERROR() + wf_commons["number_of_events"] = -1 + + assert xf_o.success == "True" + assert xf_o.step == "finalize" + assert xf_o._outputsOK() + assert not xf_o.inputFileStats["mult"] + assert not xf_o.inputFileStats["other"] + + create_workflow_commons(wf_commons) + axlf.execute(job_path) + + jr.setApplicationStatus.assert_not_called() + assert fr.statusDict == {} + + def test_analyseXMLSummary_badInput_success(self, mocker, axlf, wf_commons, xml_summary_file): + """Test success scenario with part and fail input not part of the input data list.""" + mock_file_report = mocker.patch("dirac_cwl.commands.analyze_xml_summary.FileReport") + mock_job_report = mocker.patch("dirac_cwl.commands.analyze_xml_summary.JobReport") + + fr = FileReport() + + jr = JobReport(wf_commons["job_id"]) + mocker.patch.object(jr, "setApplicationStatus") + jr.setApplicationStatus.return_value = S_OK() + + mock_file_report.return_value = fr + mock_job_report.return_value = jr + + xml_content = dedent(""" + + True + finalize + + 866104.0 + + + 200 + 200 + + + 200 + + + """) + + xf_o = prepare_XMLSummary_file(xml_summary_file, xml_content) + wf_commons["xml_summary_path"] = xml_summary_file + wf_commons["number_of_events"] = -1 + + assert xf_o.success == "True" + assert xf_o.step == "finalize" + assert xf_o._outputsOK() + assert not xf_o.inputFileStats["mult"] + assert not xf_o.inputFileStats["other"] + + create_workflow_commons(wf_commons) + axlf.execute(job_path) + + jr.setApplicationStatus.assert_called_once() + assert fr.statusDict == {} + + def test_analyseXMLSummary_partInput_success(self, mocker, axlf, wf_commons, xml_summary_file): + """Test success scenario with part input part of the input data list.""" + # Input is 'part' and is part of the input data list but the number of events is not -1 + mock_file_report = mocker.patch("dirac_cwl.commands.analyze_xml_summary.FileReport") + mock_job_report = mocker.patch("dirac_cwl.commands.analyze_xml_summary.JobReport") + + fr = FileReport() + + jr = JobReport(wf_commons["job_id"]) + mocker.patch.object(jr, "setApplicationStatus") + jr.setApplicationStatus.return_value = S_OK() + + mock_file_report.return_value = fr + mock_job_report.return_value = jr + + xml_content = dedent(""" + + True + finalize + + 866104.0 + + + 200 + + + 200 + + + """) + xf_o = prepare_XMLSummary_file(xml_summary_file, xml_content) + wf_commons["xml_summary_path"] = xml_summary_file + wf_commons["inputs"] = ["00012478_00000532_1.sim"] + wf_commons["number_of_events"] = 1 + + assert xf_o.success == "True" + assert xf_o.step == "finalize" + assert xf_o._outputsOK() + assert not xf_o.inputFileStats["mult"] + assert not xf_o.inputFileStats["other"] + + create_workflow_commons(wf_commons) + axlf.execute(job_path) + + jr.setApplicationStatus.assert_called_once() + assert fr.statusDict == {} + + def test_analyseXMLSummary_notSuccess_fail(self, mocker, axlf, wf_commons, xml_summary_file): + """Test failure scenario with success=False.""" + mock_file_report = mocker.patch("dirac_cwl.commands.analyze_xml_summary.FileReport") + mock_job_report = mocker.patch("dirac_cwl.commands.analyze_xml_summary.JobReport") + + fr = FileReport() + + jr = JobReport(wf_commons["job_id"]) + mocker.patch.object(jr, "setApplicationStatus") + jr.setApplicationStatus.return_value = S_OK() + + mock_file_report.return_value = fr + mock_job_report.return_value = jr + + xml_content = dedent(""" + + False + finalize + + 866104.0 + + + 200 + + + 200 + + + """) + + xf_o = prepare_XMLSummary_file(xml_summary_file, xml_content) + wf_commons["xml_summary_path"] = xml_summary_file + wf_commons["number_of_events"] = -1 + + assert xf_o.success == "False" + assert xf_o.step == "finalize" + assert xf_o._outputsOK() + assert not xf_o.inputFileStats["mult"] + assert not xf_o.inputFileStats["other"] + + create_workflow_commons(wf_commons) + with pytest.raises(WorkflowProcessingException): + axlf.execute(job_path) + + jr.setApplicationStatus.assert_called_once() + assert fr.statusDict == {} + + def test_analyseXMLSummary_badStep_fail(self, mocker, axlf, wf_commons, xml_summary_file): + """Test failure scenario with step != finalize.""" + mock_file_report = mocker.patch("dirac_cwl.commands.analyze_xml_summary.FileReport") + mock_job_report = mocker.patch("dirac_cwl.commands.analyze_xml_summary.JobReport") + + fr = FileReport() + + jr = JobReport(wf_commons["job_id"]) + mocker.patch.object(jr, "setApplicationStatus") + jr.setApplicationStatus.return_value = S_OK() + + mock_file_report.return_value = fr + mock_job_report.return_value = jr + + xml_content = dedent(""" + + True + execute + + 866104.0 + + + 200 + + + 200 + + + """) + + xf_o = prepare_XMLSummary_file(xml_summary_file, xml_content) + wf_commons["xml_summary_path"] = xml_summary_file + wf_commons["number_of_events"] = -1 + + assert xf_o.success == "True" + assert xf_o.step == "execute" + assert xf_o._outputsOK() + assert not xf_o.inputFileStats["mult"] + assert not xf_o.inputFileStats["other"] + + create_workflow_commons(wf_commons) + with pytest.raises(WorkflowProcessingException): + axlf.execute(job_path) + + jr.setApplicationStatus.assert_called_once() + assert fr.statusDict == {} + + def test_analyseXMLSummary_badOutput_fail(self, mocker, axlf, wf_commons, xml_summary_file): + """Test failure scenario with output status != full.""" + mock_file_report = mocker.patch("dirac_cwl.commands.analyze_xml_summary.FileReport") + mock_job_report = mocker.patch("dirac_cwl.commands.analyze_xml_summary.JobReport") + + fr = FileReport() + + jr = JobReport(wf_commons["job_id"]) + mocker.patch.object(jr, "setApplicationStatus") + jr.setApplicationStatus.return_value = S_OK() + + mock_file_report.return_value = fr + mock_job_report.return_value = jr + + xml_content = dedent(""" + + True + finalize + + 866104.0 + + + 200 + + + 200 + + + """) + + xf_o = prepare_XMLSummary_file(xml_summary_file, xml_content) + wf_commons["xml_summary_path"] = xml_summary_file + wf_commons["number_of_events"] = -1 + + assert xf_o.success == "True" + assert xf_o.step == "finalize" + assert not xf_o._outputsOK() + assert not xf_o.inputFileStats["mult"] + assert not xf_o.inputFileStats["other"] + + create_workflow_commons(wf_commons) + with pytest.raises(WorkflowProcessingException): + axlf.execute(job_path) + + jr.setApplicationStatus.assert_called_once() + assert fr.statusDict == {} + + def test_analyseXMLSummary_badInput_fail(self, mocker, axlf, wf_commons, xml_summary_file): + """Test failure scenario with input status = mult.""" + mock_file_report = mocker.patch("dirac_cwl.commands.analyze_xml_summary.FileReport") + mock_job_report = mocker.patch("dirac_cwl.commands.analyze_xml_summary.JobReport") + + fr = FileReport() + + jr = JobReport(wf_commons["job_id"]) + mocker.patch.object(jr, "setApplicationStatus") + jr.setApplicationStatus.return_value = S_OK() + + mock_file_report.return_value = fr + mock_job_report.return_value = jr + + xml_content = dedent(""" + + True + finalize + + 866104.0 + + + 200 + + + 200 + + + """) + + xf_o = prepare_XMLSummary_file(xml_summary_file, xml_content) + wf_commons["xml_summary_path"] = xml_summary_file + wf_commons["number_of_events"] = -1 + + assert xf_o.success == "True" + assert xf_o.step == "finalize" + assert xf_o._outputsOK() + assert xf_o.inputFileStats["mult"] + assert not xf_o.inputFileStats["other"] + + create_workflow_commons(wf_commons) + with pytest.raises(WorkflowProcessingException): + axlf.execute(job_path) + + jr.setApplicationStatus.assert_called_once() + assert fr.statusDict == {} + + def test_analyseXMLSummary_badInput2_fail(self, mocker, axlf, wf_commons, xml_summary_file): + """Test failure scenario with an unknown input status (weoweo).""" + mock_file_report = mocker.patch("dirac_cwl.commands.analyze_xml_summary.FileReport") + mock_job_report = mocker.patch("dirac_cwl.commands.analyze_xml_summary.JobReport") + + fr = FileReport() + + jr = JobReport(wf_commons["job_id"]) + mocker.patch.object(jr, "setApplicationStatus") + jr.setApplicationStatus.return_value = S_OK() + + mock_file_report.return_value = fr + mock_job_report.return_value = jr + + xml_content = dedent(""" + + True + finalize + + 866104.0 + + + 200 + + + 200 + + + """) + + xf_o = prepare_XMLSummary_file(xml_summary_file, xml_content) + wf_commons["xml_summary_path"] = xml_summary_file + wf_commons["number_of_events"] = -1 + + assert xf_o.success == "True" + assert xf_o.step == "finalize" + assert xf_o._outputsOK() + assert not xf_o.inputFileStats["mult"] + assert xf_o.inputFileStats["other"] + + create_workflow_commons(wf_commons) + with pytest.raises(WorkflowProcessingException): + axlf.execute(job_path) + + jr.setApplicationStatus.assert_called_once() + assert fr.statusDict == {} + + def test_analyseXMLSummary_badInput3_fail(self, mocker, axlf, wf_commons, xml_summary_file): + """Test failure scenario with input status = fail.""" + mock_file_report = mocker.patch("dirac_cwl.commands.analyze_xml_summary.FileReport") + mock_job_report = mocker.patch("dirac_cwl.commands.analyze_xml_summary.JobReport") + + fr = FileReport() + + jr = JobReport(wf_commons["job_id"]) + mocker.patch.object(jr, "setApplicationStatus") + jr.setApplicationStatus.return_value = S_OK() + + mock_file_report.return_value = fr + mock_job_report.return_value = jr + + xml_content = dedent(""" + + True + finalize + + 866104.0 + + + 200 + 200 + + + 200 + + + """) + + xf_o = prepare_XMLSummary_file(xml_summary_file, xml_content) + wf_commons["xml_summary_path"] = xml_summary_file + wf_commons["inputs"] = ["00012478_00000532_1.sim"] + wf_commons["number_of_events"] = -1 + + assert xf_o.success == "True" + assert xf_o.step == "finalize" + assert xf_o._outputsOK() + assert not xf_o.inputFileStats["mult"] + assert not xf_o.inputFileStats["other"] + + create_workflow_commons(wf_commons) + with pytest.raises(WorkflowProcessingException): + axlf.execute(job_path) + + jr.setApplicationStatus.assert_called_once() + assert fr.statusDict == {"00012478_00000532_1.sim": "Problematic"} + + def test_analyseXMLSummary_badInput4_fail(self, mocker, axlf, wf_commons, xml_summary_file): + """Test failure scenario with input status = part.""" + # Input is 'part' and is part of the input data list but the number of events is -1 (by default) + mock_file_report = mocker.patch("dirac_cwl.commands.analyze_xml_summary.FileReport") + mock_job_report = mocker.patch("dirac_cwl.commands.analyze_xml_summary.JobReport") + + fr = FileReport() + + jr = JobReport(wf_commons["job_id"]) + mocker.patch.object(jr, "setApplicationStatus") + jr.setApplicationStatus.return_value = S_OK() + + mock_file_report.return_value = fr + mock_job_report.return_value = jr + + xml_content = dedent(""" + + True + finalize + + 866104.0 + + + 200 + 200 + + + 200 + + + """) + + xf_o = prepare_XMLSummary_file(xml_summary_file, xml_content) + wf_commons["xml_summary_path"] = xml_summary_file + wf_commons["inputs"] = ["00012478_00000532_1.sim"] + wf_commons["number_of_events"] = -1 + + assert xf_o.success == "True" + assert xf_o.step == "finalize" + assert xf_o._outputsOK() + assert not xf_o.inputFileStats["mult"] + assert not xf_o.inputFileStats["other"] + + create_workflow_commons(wf_commons) + with pytest.raises(WorkflowProcessingException): + axlf.execute(job_path) + + jr.setApplicationStatus.assert_called_once() + assert fr.statusDict == {"00012478_00000532_1.sim": "Problematic"} From 32e54b4413bb2f6f99d269ac6e9facf5455e435f Mon Sep 17 00:00:00 2001 From: Jorge Lisa <64639359+AcquaDiGiorgio@users.noreply.github.com> Date: Wed, 6 May 2026 13:13:39 +0200 Subject: [PATCH 13/21] feat: Migrate WorkflowAccounting command to cwl-dirac --- src/dirac_cwl/commands/__init__.py | 2 + src/dirac_cwl/commands/utils.py | 1 + src/dirac_cwl/commands/workflow_accounting.py | 108 ++++++++++ test/test_commands.py | 188 +++++++++++++++++- 4 files changed, 290 insertions(+), 9 deletions(-) create mode 100644 src/dirac_cwl/commands/workflow_accounting.py diff --git a/src/dirac_cwl/commands/__init__.py b/src/dirac_cwl/commands/__init__.py index cd73a09..f2446d6 100644 --- a/src/dirac_cwl/commands/__init__.py +++ b/src/dirac_cwl/commands/__init__.py @@ -6,6 +6,7 @@ from .failover_request import FailoverRequest from .upload_log_file import UploadLogFile from .upload_output_data import UploadOutputData +from .workflow_accounting import WorkflowAccounting __all__ = [ "AnalyseXmlSummary", @@ -15,4 +16,5 @@ "BookeepingReport", "FailoverRequest", "UploadOutputData", + "WorkflowAccounting", ] diff --git a/src/dirac_cwl/commands/utils.py b/src/dirac_cwl/commands/utils.py index 43a7f88..f910bd5 100644 --- a/src/dirac_cwl/commands/utils.py +++ b/src/dirac_cwl/commands/utils.py @@ -75,6 +75,7 @@ def prepare_lhcb_workflow_commons(workflow_commons_path, extra_mandatory_values= "config_version": None, "request_dict": {}, "file_report_files_dict": {}, + "number_of_processors": 1, } for k, v in extra_default_values.items(): diff --git a/src/dirac_cwl/commands/workflow_accounting.py b/src/dirac_cwl/commands/workflow_accounting.py new file mode 100644 index 0000000..0f69946 --- /dev/null +++ b/src/dirac_cwl/commands/workflow_accounting.py @@ -0,0 +1,108 @@ +"""LHCb command for preparing and sending accounting information to the DIRAC Accounting system. + +Formerly known as StepAccounting. +""" + +import os +from datetime import datetime + +from DIRAC import gConfig +from DIRAC.AccountingSystem.Client.DataStoreClient import DataStoreClient +from DIRAC.Workflow.Utilities.Utils import getStepCPUTimes +from LHCbDIRAC.AccountingSystem.Client.Types.JobStep import JobStep +from LHCbDIRAC.Core.Utilities.XMLSummaries import XMLSummary +from LHCbDIRAC.Workflow.Modules.BookkeepingReport import _generate_xml_object + +from dirac_cwl.core.exceptions import WorkflowProcessingException + +from .core import PostProcessCommand +from .utils import prepare_lhcb_workflow_commons, save_workflow_commons + + +class WorkflowAccounting(PostProcessCommand): + """Prepares and sends accounting information to the DIRAC Accounting system.""" + + def execute(self, job_path, **kwargs): + """Execute the command. + + :param job_path: Path to the job working directory. + :param kwargs: Additional keyword arguments. + """ + failed = False + try: + # Obtain Workflow Commons + workflow_commons_path = kwargs.get("workflow_commons_path", os.path.join(job_path, "workflow_commons.json")) + workflow_commons = {} + workflow_commons = prepare_lhcb_workflow_commons( + workflow_commons_path, + extra_mandatory_values=["bk_step_id", "step_proc_pass", "event_type"], + extra_default_values={ + "step_proc_pass": "", + "run_number": "Unknown", + }, + ) + + cpu_times = {} + if "start_time" in workflow_commons: + cpu_times["StartTime"] = workflow_commons["start_time"] + if "start_stats" in workflow_commons: + cpu_times["StartStats"] = workflow_commons["start_stats"] + + exec_time, cpu_time = getStepCPUTimes(cpu_times) + + cpuNormFactor = gConfig.getValue("/LocalSite/CPUNormalizationFactor", 0.0) + normCPU = cpu_time * cpuNormFactor + + jobStep = JobStep() + + if "xml_summary_path" in workflow_commons: + xf_o = XMLSummary(workflow_commons["xml_summary_path"]) + else: + xf_o = _generate_xml_object( + workflow_commons["cleaned_application_name"], + workflow_commons["production_id"], + workflow_commons["prod_job_id"], + workflow_commons["command_number"], + workflow_commons["command_id"], + ) + + now = datetime.utcnow() + jobStep.setStartTime(now) + jobStep.setEndTime(now) + + dataDict = { + "JobGroup": str(workflow_commons["production_id"]), + "RunNumber": workflow_commons["run_number"], + "EventType": workflow_commons["event_type"], + "ProcessingType": workflow_commons["step_proc_pass"], # this is the processing pass of the step + "ProcessingStep": workflow_commons["bk_step_id"], # the step ID + "Site": workflow_commons["site_name"], + "FinalStepState": workflow_commons["step_status"], + "CPUTime": cpu_time, + "NormCPUTime": normCPU, + "ExecTime": exec_time * workflow_commons["number_of_processors"], + "InputData": sum(xf_o.inputFileStats.values()), + "OutputData": sum(xf_o.outputFileStats.values()), + "InputEvents": xf_o.inputEventsTotal, + "OutputEvents": xf_o.outputEventsTotal, + } + + jobStep.setValuesFromDict(dataDict) + + res = jobStep.checkValues() + if not res["OK"]: + raise WorkflowProcessingException( + "Values for StepAccounting are wrong:", f"{res['Message']}. Here are the given data: {dataDict}" + ) + + dsc = DataStoreClient() + dsc.addRegister(jobStep) + workflow_commons["accounting_registers"] = dsc.__registersList + + except Exception as e: + failed = True + raise WorkflowProcessingException() from e + + finally: + if workflow_commons: + save_workflow_commons(workflow_commons, workflow_commons_path, failed=failed) diff --git a/test/test_commands.py b/test/test_commands.py index d70639b..a2db617 100644 --- a/test/test_commands.py +++ b/test/test_commands.py @@ -12,6 +12,7 @@ import LHCbDIRAC import pytest from DIRAC import siteName +from DIRAC.AccountingSystem.Client.DataStoreClient import DataStoreClient from DIRAC.DataManagementSystem.Client.FailoverTransfer import FailoverTransfer from DIRAC.RequestManagementSystem.Client.File import File from DIRAC.RequestManagementSystem.Client.Operation import Operation @@ -23,7 +24,14 @@ from LHCbDIRAC.Core.Utilities.XMLSummaries import XMLSummary from pytest_mock import MockerFixture -from dirac_cwl.commands import AnalyseXmlSummary, BookeepingReport, FailoverRequest, UploadLogFile, UploadOutputData +from dirac_cwl.commands import ( + AnalyseXmlSummary, + BookeepingReport, + FailoverRequest, + UploadLogFile, + UploadOutputData, + WorkflowAccounting, +) from dirac_cwl.core.exceptions import WorkflowProcessingException number_of_processors = 1 @@ -1062,9 +1070,7 @@ def upload_output(self, mocker, wf_commons): if "ProductionOutputData" in wf_commons: wf_commons.pop("ProductionOutputData") - upload_output = UploadOutputData() - - yield upload_output + yield UploadOutputData() # Test Scenarios def test_uploadOutputData_success(self, mocker, upload_output, wf_commons, sim_file, bk_file): @@ -1807,11 +1813,7 @@ class TestAnalyseXmlSummary: @pytest.fixture def axlf(self, mocker): """Fixture for AnalyseXmlSummary module.""" - mocker.patch("LHCbDIRAC.Workflow.Modules.ModuleBase.RequestValidator") - - axlf = AnalyseXmlSummary() - - yield axlf + yield AnalyseXmlSummary() # Test scenarios def test_analyseXMLSummary_basic_success(self, mocker, axlf, wf_commons, xml_summary_file): @@ -2370,3 +2372,171 @@ def test_analyseXMLSummary_badInput4_fail(self, mocker, axlf, wf_commons, xml_su jr.setApplicationStatus.assert_called_once() assert fr.statusDict == {"00012478_00000532_1.sim": "Problematic"} + + +class TestWorkflowAccounting: + """Collection of tests for the WorkflowAccounting command.""" + + @pytest.fixture + def accounting(self, mocker): + """Fixture for WorkflowAccounting module.""" + yield WorkflowAccounting() + + # Test Scenarios + def test_accounting_success(self, mocker, accounting, wf_commons, xml_summary_file): + """Test successful execution of WorkflowAccounting module.""" + mock_data_store = mocker.patch("dirac_cwl.commands.workflow_accounting.DataStoreClient") + dsc = DataStoreClient() + mocker.patch.object(dsc, "addRegister") + mock_data_store.return_value = dsc + + wf_commons["application_name"] = "Gauss" + xml_content = dedent(""" + + True + finalize + + 866104.0 + + + 200 + + + 200 + + + """) + + prepare_XMLSummary_file(xml_summary_file, xml_content) + + wf_commons["xml_summary_path"] = xml_summary_file + wf_commons["bk_step_id"] = "12345" + wf_commons["step_proc_pass"] = "Sim09m" + wf_commons["event_type"] = "23103003" + + create_workflow_commons(wf_commons) + + accounting.execute(job_path) + + # Make sure the dsc was called + dsc.addRegister.assert_called_once() + + def test_accounting_noApplicationName_fail(self, mocker, accounting, wf_commons, xml_summary_file): + """Test WorkflowAccounting when there is no application name in step commons.""" + mock_data_store = mocker.patch("dirac_cwl.commands.workflow_accounting.DataStoreClient") + dsc = DataStoreClient() + mocker.patch.object(dsc, "addRegister") + mock_data_store.return_value = dsc + + xml_content = dedent(""" + + True + finalize + + 866104.0 + + + 200 + + + 200 + + + """) + + prepare_XMLSummary_file(xml_summary_file, xml_content) + + wf_commons.pop("application_name") + wf_commons["xml_summary_path"] = xml_summary_file + + create_workflow_commons(wf_commons) + + with pytest.raises(WorkflowProcessingException): + accounting.execute(job_path) + + assert not dsc.addRegister.called, "No accounting data should be added." + + def test_accounting_incompleteData(self, mocker, accounting, wf_commons, xml_summary_file): + """Test successful execution of WorkflowAccounting module.""" + mock_data_store = mocker.patch("dirac_cwl.commands.workflow_accounting.DataStoreClient") + dsc = DataStoreClient() + mocker.patch.object(dsc, "addRegister") + mock_data_store.return_value = dsc + + xml_content = dedent(""" + + True + finalize + + 866104.0 + + + 200 + + + 200 + + + """) + + prepare_XMLSummary_file(xml_summary_file, xml_content) + + wf_commons["xml_summary_path"] = xml_summary_file + wf_commons["application_name"] = "Gauss" + + create_workflow_commons(wf_commons) + + with pytest.raises(WorkflowProcessingException): + accounting.execute(job_path) + + assert not dsc.addRegister.called, "No accounting data should be added." + + def test_accounting_previousError_fail(self, mocker, accounting, wf_commons, xml_summary_file): + """Test WorkflowAccounting with an intentional failure.""" + mock_data_store = mocker.patch("dirac_cwl.commands.workflow_accounting.DataStoreClient") + dsc = DataStoreClient() + mocker.patch.object(dsc, "addRegister") + mock_data_store.return_value = dsc + + xml_content = dedent(""" + + True + finalize + + 866104.0 + + + 200 + + + 200 + + + """) + + prepare_XMLSummary_file(xml_summary_file, xml_content) + + wf_commons["xml_summary_path"] = xml_summary_file + wf_commons["application_name"] = "Gauss" + wf_commons["bk_step_id"] = "12345" + wf_commons["step_proc_pass"] = "Sim09m" + wf_commons["event_type"] = "23103003" + wf_commons["step_status"] = S_ERROR() + + create_workflow_commons(wf_commons) + + accounting.execute(job_path) + + assert dsc.addRegister.called, "Accounting data should be added." From f02159a58b80ff2ae81f379da2d3866e8aebbb9a Mon Sep 17 00:00:00 2001 From: Jorge Lisa <64639359+AcquaDiGiorgio@users.noreply.github.com> Date: Wed, 6 May 2026 16:53:17 +0200 Subject: [PATCH 14/21] feat: Migrate UploadLogFile command to cwl-dirac --- src/dirac_cwl/commands/upload_log_file.py | 263 +++++---- test/test_commands.py | 623 ++++++++++++++-------- 2 files changed, 522 insertions(+), 364 deletions(-) diff --git a/src/dirac_cwl/commands/upload_log_file.py b/src/dirac_cwl/commands/upload_log_file.py index 3e8f0a9..19a5a7e 100644 --- a/src/dirac_cwl/commands/upload_log_file.py +++ b/src/dirac_cwl/commands/upload_log_file.py @@ -1,24 +1,32 @@ """Post-processing command for uploading logging information to a Storage Element.""" -import glob import os -import random -import stat -import time -import zipfile -from urllib.parse import urljoin +import shlex -from DIRAC import S_ERROR, S_OK, siteName from DIRAC.ConfigurationSystem.Client.Helpers.Operations import Operations -from DIRAC.Core.Utilities.Adler import fileAdler from DIRAC.Core.Utilities.ReturnValues import returnSingleResult +from DIRAC.Core.Utilities.Subprocess import systemCall from DIRAC.DataManagementSystem.Client.FailoverTransfer import FailoverTransfer -from DIRAC.DataManagementSystem.Utilities.ResolveSE import getDestinationSEList -from DIRAC.Resources.Catalog.PoolXMLFile import getGUID +from DIRAC.RequestManagementSystem.Client.Request import Request from DIRAC.Resources.Storage.StorageElement import StorageElement from DIRAC.WorkloadManagementSystem.Client.JobReport import JobReport +from LHCbDIRAC.BookkeepingSystem.Client.BookkeepingClient import BookkeepingClient +from LHCbDIRAC.Core.Utilities.ProductionData import getLogPath +from LHCbDIRAC.Workflow.Modules.FailoverRequest import _prepareRequest +from LHCbDIRAC.Workflow.Modules.UploadLogFile import ( + _createLogUploadRequest, + _determineRelevantFiles, + _get_log_url, + _populateLogDirectory, + _setLogFilePermissions, + _uploadLogToFailoverSE, + _zip_files, +) -from dirac_cwl.commands import PostProcessCommand +from dirac_cwl.core.exceptions import WorkflowProcessingException + +from .core import PostProcessCommand +from .utils import prepare_lhcb_workflow_commons, save_workflow_commons class UploadLogFile(PostProcessCommand): @@ -31,132 +39,111 @@ def execute(self, job_path, **kwargs): :param kwargs: Additional keyword arguments. """ # Obtain workflow information - job_id = kwargs.get("job_id", None) - production_id = kwargs.get("production_id", None) - namespace = kwargs.get("namespace", None) - config_version = kwargs.get("config_version", None) - - if not job_path or not production_id or not namespace or not config_version: - return S_ERROR("Not enough information to perform the log upload") - - ops = Operations() - log_extensions = ops.getValue("LogFiles/Extensions", []) - log_se = ops.getValue("LogStorage/LogSE", "LogSE") - - job_report = JobReport(job_id) - - output_files = self.obtain_output_files(job_path, log_extensions) - - if not output_files: - return S_OK("No files to upload") - - # Zip files - zip_name = job_id.zfill(8) + ".zip" - zip_path = os.path.join(job_path, zip_name) - + failed = False + workflow_commons = {} + request = None try: - self.zip_files(zip_path, output_files) - except (AttributeError, OSError, ValueError) as e: - job_report.setApplicationStatus("Failed to create zip of log files") - return S_OK(f"Failed to zip files: {repr(e)}") - - # Obtain the log destination - zip_lfn = self.get_zip_lfn(production_id, job_id, namespace, config_version) - - # Upload to the SE - result = returnSingleResult(StorageElement(log_se).putFile({zip_lfn: zip_path})) - - if not result["OK"]: # Failed to uplaod to the LogSE - result = self.generate_failover_transfer(zip_path, zip_name, zip_lfn) - + workflow_commons_path = kwargs.get("workflow_commons_path", os.path.join(job_path, "workflow_commons.json")) + + workflow_commons = prepare_lhcb_workflow_commons( + workflow_commons_path, + extra_mandatory_values=[], + extra_default_values={"log_target_path": None, "log_file_path": ""}, + ) + request = Request(workflow_commons["request_dict"]) + + if not workflow_commons["step_status"]["OK"]: + return + + log_lfn_path = workflow_commons["log_target_path"] + if not log_lfn_path: + parameters = { + "PRODUCTION_ID": workflow_commons["production_id"], + "JOB_ID": workflow_commons["job_id"], + "configName": workflow_commons["config_name"], + "configVersion": workflow_commons["config_version"], + } + result = getLogPath(parameters, BookkeepingClient()) + if not result["OK"]: + raise WorkflowProcessingException("Could not create LogFilePath", result["Message"]) + log_lfn_path = result["Value"]["LogTargetPath"][0] + + if not isinstance(log_lfn_path, str): + log_lfn_path = log_lfn_path[0] + + workflow_commons["log_lfn_path"] = log_lfn_path + + ops = Operations() + log_se = ops.getValue("LogStorage/LogSE", "LogSE") + log_extensions = ops.getValue("LogFiles/Extensions", []) + + _prepareRequest(request, workflow_commons["job_id"]) + failover_transfer = FailoverTransfer(request) + job_report = JobReport(workflow_commons["job_id"]) + + res = systemCall(0, shlex.split("ls -al")) + + workflow_commons["log_dir"] = os.path.realpath( + f"./job/log/{workflow_commons['production_id']}/{workflow_commons['prod_job_id']}" + ) + + ########################################## + # First determine the files which should be saved + res = _determineRelevantFiles(log_extensions) + if not res["OK"]: + return + selectedFiles = res["Value"] + + ######################################### + # Create a temporary directory containing these files + res = _populateLogDirectory(selectedFiles, workflow_commons["log_dir"]) + if not res["OK"]: + job_report.setApplicationStatus("Failed To Populate Log Dir") + return + + ######################################### + # Make sure all the files in the log directory have the correct permissions + result = _setLogFilePermissions(workflow_commons["log_dir"]) + + # zip all files + result = _zip_files(workflow_commons["prod_job_id"], selectedFiles) if not result["OK"]: - job_report.setApplicationStatus("Failed To Upload Logs") - return S_ERROR("Failed to upload to FailoverSE") - - # Set the Log URL parameter - result = returnSingleResult(StorageElement(log_se).getURL(zip_path, protocol="https")) - if not result["OK"]: - # The rule for interpreting what is to be deflated can be found in /eos/lhcb/grid/prod/lhcb/logSE/.htaccess - logHttpsURL = urljoin("https://lhcb-dirac-logse.web.cern.ch/lhcb-dirac-logse/", zip_lfn) - else: - logHttpsURL = result["Value"] - - logHttpsURL = logHttpsURL.replace(".zip", "/") - job_report.setJobParameter("Log URL", f'Log file directory') - - return S_OK("Log Files uploaded") - - def zip_files(self, outputFile, files=None, directory=None): - """Zip list of files.""" - with zipfile.ZipFile(outputFile, "w") as zipped: - for fileIn in files: - # ZIP does not support timestamps before 1980, so for those we simply "touch" - st = os.stat(fileIn) - mtime = time.localtime(st.st_mtime) - dateTime = mtime[0:6] - if dateTime[0] < 1980: - os.utime(fileIn, None) # same as "touch" - - zipped.write(fileIn) - - def obtain_output_files(self, job_path, extensions=[]): - """Obtain the files to be added to the log zip from the outputs.""" - log_file_extensions = extensions - - if not log_file_extensions: - log_file_extensions = [ - "*.txt", - "*.log", - "*.out", - "*.output", - "*.xml", - "*.sh", - "*.info", - "*.err", - "prodConf*.py", - "prodConf*.json", - ] - - files = [] - - for extension in log_file_extensions: - glob_list = glob.glob(extension, root_dir=job_path, recursive=True) - for check in glob_list: - path = os.path.join(job_path, check) - if os.path.isfile(path): - os.chmod(path, stat.S_IRWXU | stat.S_IRGRP | stat.S_IXGRP | stat.S_IROTH + stat.S_IXOTH) - files.append(path) - - return files - - def get_zip_lfn(self, production_id, job_id, namespace, config_version): - """Form a logical file name from certain information from the workflow.""" - production_id = str(production_id).zfill(8) - job_id = str(job_id).zfill(8) - jobindex = str(int(int(job_id) / 10000)).zfill(4) - - log_path = os.path.join("/lhcb", namespace, config_version, "LOG", production_id, jobindex, "") - path = os.path.join(log_path, f"{job_id}.zip") - return path - - def generate_failover_transfer(self, zip_path, zip_name, zip_lfn): - """Prepare a failover transfer .""" - failoverSEs = getDestinationSEList("Tier1-Failover", siteName()) - random.shuffle(failoverSEs) - - fileMetaDict = { - "Size": os.path.getsize(zip_path), - "LFN": zip_lfn, - "GUID": getGUID(zip_path), - "Checksum": fileAdler(zip_path), - "ChecksumType": "ADLER32", - } - - return FailoverTransfer().transferAndRegisterFile( - fileName=zip_name, - localPath=zip_path, - lfn=zip_lfn, - destinationSEList=failoverSEs, - fileMetaDict=fileMetaDict, - masterCatalogOnly=True, - ) + job_report.setApplicationStatus("Failed to create zip of log files") + return + + zip_file_name = result["Value"] + + # Instantiate the failover transfer client with the global request object + if not failover_transfer: + failover_transfer = FailoverTransfer(request) + + # logFilePath is something like /lhcb/MC/2016/LOG/00095376/0000/ + # the zipFileName should have the same name, e.g. 00000381.zip + zipPath = os.path.join(workflow_commons["log_file_path"], zip_file_name) + logHttpsURL = _get_log_url(log_se, zipPath) + + res = returnSingleResult(StorageElement(log_se).putFile({zipPath: zip_file_name})) + if not res["OK"]: + result = _uploadLogToFailoverSE( + failover_transfer, zip_file_name, log_lfn_path, workflow_commons["site_name"] + ) + + if not result["OK"]: + job_report.setApplicationStatus("Failed To Upload Logs") + else: + uploadedSE = result["Value"]["uploadedSE"] + request = failover_transfer.request + _createLogUploadRequest(request, log_se, log_lfn_path, uploadedSE) + + # While it's the zip file that is uploaded, we set in job parameters its directory, + # as the .zip is deflated automatically + job_report.setJobParameter( + "Log URL", f"Log file directory" + ) + + except Exception as e: + failed = True + raise WorkflowProcessingException(e) from e + + finally: + save_workflow_commons(workflow_commons, workflow_commons_path, request, failed=failed) diff --git a/test/test_commands.py b/test/test_commands.py index a2db617..51d18a6 100644 --- a/test/test_commands.py +++ b/test/test_commands.py @@ -1,13 +1,16 @@ -""".""" +"""Tests for the commands. + +This module tests the execution of the different commands. +""" import json import os -import tempfile +import shutil import time import xml.etree.ElementTree as ET +import zipfile from pathlib import Path from textwrap import dedent -from urllib.parse import urljoin import LHCbDIRAC import pytest @@ -123,269 +126,437 @@ def create_workflow_commons(wf_dict): return path -@pytest.mark.skip("Deprecated command implementation") class TestUploadLogFile: """Collection of tests for the UploadLogFile command.""" - FILENAMES = ["file.txt", "file.log", "file.err", "file.out", "file.extra"] - JOB_ID = "8042" - PRODUCTION_ID = "95376" - NAMESPACE = "MC" - CONFIG_VERSION = "2016" - @pytest.fixture - def basedir(self): - """Fixture to initialize the working directory.""" - with tempfile.TemporaryDirectory() as tmpdir: - for file in self.FILENAMES: - with open(os.path.join(tmpdir, file), "x") as f: - f.write("EMPTY") + def uplogfile(self, mocker, wf_commons): + """Fixture for UploadLogFile module.""" + uplogfile = UploadLogFile() + + yield uplogfile - yield tmpdir + Path(f"{wf_commons['prod_job_id']}.zip").unlink(missing_ok=True) + shutil.rmtree("unzipped", ignore_errors=True) - def test_correct_file_finding(self, basedir): - """Test output file finding.""" - files = UploadLogFile().obtain_output_files(basedir) - files_names = [os.path.basename(file_path) for file_path in files] + @pytest.fixture + def prodconf_json(self): + """prodconf.json file fixture.""" + filename = "prodConf_example.json" - assert set(self.FILENAMES).difference(files_names) == {"file.extra"} + with open(filename, "w") as f: + f.write('{"foo": "bar"}') - def test_correct_file_extension_finding(self, basedir): - """Test output file finding.""" - extensions = ["*.extra"] - files = UploadLogFile().obtain_output_files(basedir, extensions) - files_names = [os.path.basename(file_path) for file_path in files] + yield filename - assert set(self.FILENAMES).difference(files_names) == {"file.txt", "file.log", "file.err", "file.out"} + Path(filename).unlink(missing_ok=True) - def test_upload_ok(self, basedir, mocker: MockerFixture): - """Test a correct upload.""" - base_lfn = f"/lhcb/{self.NAMESPACE}/{self.CONFIG_VERSION}/LOG/{self.PRODUCTION_ID.zfill(8)}/0000/" - zip_name = self.JOB_ID.zfill(8) + ".zip" + @pytest.fixture + def prodconf_py(self): + """prodconf.py file fixture.""" + filename = "prodConf_example.py" - expected_lfn = os.path.join(base_lfn, zip_name) - expected_path = os.path.join(basedir, zip_name) + with open(filename, "w") as f: + f.write('foo = "bar"') - # Mock Operations - mock_ops = mocker.patch("dirac_cwl.commands.upload_log_file.Operations") - mock_ops.return_value.getValue = lambda value, default=None: default + yield filename - # Mock JobReport - mock_job_report = mocker.patch("dirac_cwl.commands.upload_log_file.JobReport") - mock_set_app_status = mocker.MagicMock() - mock_set_job_parameter = mocker.MagicMock() - mock_job_report.return_value.setApplicationStatus = mock_set_app_status - mock_job_report.return_value.setJobParameter = mock_set_job_parameter - - # Mock StorageElement - mock_se = mocker.patch("dirac_cwl.commands.upload_log_file.StorageElement") - mock_put_file = mocker.MagicMock() - mock_get_url = mocker.MagicMock() - mock_put_file.return_value = S_OK({"Successful": {expected_lfn: "Borked"}, "Failed": {}}) - mock_get_url.return_value = S_OK(urljoin("https://lhcb-dirac-logse.web.cern.ch/", expected_lfn)) - mock_se.return_value.putFile = mock_put_file - mock_se.return_value.getURL = mock_get_url - - command = UploadLogFile() - - # Mock failover - mock_failover = mocker.patch.object(command, "generate_failover_transfer") - mock_failover.return_value = S_OK() - - result = command.execute( - basedir, - job_id=self.JOB_ID, - production_id=self.PRODUCTION_ID, - namespace=self.NAMESPACE, - config_version=self.CONFIG_VERSION, + Path(filename).unlink(missing_ok=True) + + # Test Scenarios + def test_uploadLogFile_success(self, mocker, uplogfile, wf_commons, prodconf_json, prodconf_py): + """Test successful execution of UploadLogFile module.""" + log_url = "notImportant" + mockSEMethod = mocker.patch( + "DIRAC.Resources.Storage.StorageElement.StorageElementItem._StorageElementItem__executeMethod", + return_value=S_OK({"Failed": [], "Successful": {log_url: log_url}}), ) + mock_request = mocker.patch("dirac_cwl.commands.upload_log_file.Request") + mock_failover = mocker.patch("dirac_cwl.commands.upload_log_file.FailoverTransfer") + mock_job_report = mocker.patch("dirac_cwl.commands.upload_log_file.JobReport") - assert result["OK"] - mock_get_url.assert_called_once_with(expected_path, protocol="https") - mock_put_file.assert_called_once_with({expected_lfn: expected_path}) - mock_failover.assert_not_called() - mock_set_app_status.assert_not_called() - mock_set_job_parameter.assert_called_once() + req = Request() + mock_request.return_value = req - def test_upload_ok_to_failover(self, basedir, mocker: MockerFixture): - """Test a failure to upload to the LogSE but a correct one to the Failover.""" - base_lfn = f"/lhcb/{self.NAMESPACE}/{self.CONFIG_VERSION}/LOG/{self.PRODUCTION_ID.zfill(8)}/0000/" - zip_name = self.JOB_ID.zfill(8) + ".zip" + failover = FailoverTransfer(req) + mocker.patch.object(failover, "transferAndRegisterFile", return_value=S_OK()) + mock_failover.return_value = failover - expected_lfn = os.path.join(base_lfn, zip_name) - expected_path = os.path.join(basedir, zip_name) + jr = JobReport(wf_commons["job_id"]) + mocker.patch.object(jr, "setApplicationStatus") + mocker.patch.object(jr, "setJobParameter") + mock_job_report.return_value = jr - # Mock Operations - mock_ops = mocker.patch("dirac_cwl.commands.upload_log_file.Operations") - mock_ops.return_value.getValue = lambda value, default=None: default + uplogfile.request = Request() - # Mock JobReport - mock_job_report = mocker.patch("dirac_cwl.commands.upload_log_file.JobReport") - mock_set_app_status = mocker.MagicMock() - mock_set_job_parameter = mocker.MagicMock() - mock_job_report.return_value.setApplicationStatus = mock_set_app_status - mock_job_report.return_value.setJobParameter = mock_set_job_parameter - - # Mock StorageElement - mock_se = mocker.patch("dirac_cwl.commands.upload_log_file.StorageElement") - mock_put_file = mocker.MagicMock() - mock_get_url = mocker.MagicMock() - mock_put_file.return_value = S_OK({"Successful": {}, "Failed": {expected_lfn: "Borked"}}) - mock_get_url.return_value = S_OK(urljoin("https://lhcb-dirac-logse.web.cern.ch/", expected_lfn)) - mock_se.return_value.putFile = mock_put_file - mock_se.return_value.getURL = mock_get_url - - command = UploadLogFile() - - # Mock failover - mock_failover = mocker.patch.object(command, "generate_failover_transfer") - mock_failover.return_value = S_OK() - - result = command.execute( - basedir, - job_id=self.JOB_ID, - production_id=self.PRODUCTION_ID, - namespace=self.NAMESPACE, - config_version=self.CONFIG_VERSION, - ) + # Execute the module + wf_commons_path = create_workflow_commons(wf_commons) - assert result["OK"] - mock_get_url.assert_called_once_with(expected_path, protocol="https") - mock_put_file.assert_called_once_with({expected_lfn: expected_path}) - mock_failover.assert_called_once_with(expected_path, zip_name, expected_lfn) - mock_set_app_status.assert_not_called() - mock_set_job_parameter.assert_called_once() + uplogfile.execute(job_path) - def test_upload_fail(self, basedir, mocker: MockerFixture): - """Test both a failure to upload to the LogSE and the FailoverSE.""" - base_lfn = f"/lhcb/{self.NAMESPACE}/{self.CONFIG_VERSION}/LOG/{self.PRODUCTION_ID.zfill(8)}/0000/" - zip_name = self.JOB_ID.zfill(8) + ".zip" + with open(wf_commons_path, "r", encoding="utf-8") as f: + updated_wf_commons = json.load(f) - expected_lfn = os.path.join(base_lfn, zip_name) - expected_path = os.path.join(basedir, zip_name) + # Check the log directory + assert updated_wf_commons["log_dir"] != "" + log_dir = Path(updated_wf_commons["log_dir"]) + assert log_dir.exists() + assert log_dir.is_dir() + assert log_dir.joinpath(prodconf_json).exists() + assert log_dir.joinpath(prodconf_json).read_text() == '{"foo": "bar"}' + assert log_dir.joinpath(prodconf_py).exists() + assert log_dir.joinpath(prodconf_py).read_text() == 'foo = "bar"' + + for file in log_dir.iterdir(): + assert file.stat().st_mode & 0o777 == 0o755 + + # Check the generated zip file + zipFile = Path(f"{updated_wf_commons['prod_job_id']}.zip") + assert zipFile.exists() + + zipfile.ZipFile(zipFile, "r").extractall("unzipped") + unzipped = Path("unzipped").joinpath(updated_wf_commons["prod_job_id"]) + assert unzipped.joinpath(prodconf_json).exists() + assert unzipped.joinpath(prodconf_py).exists() + assert unzipped.joinpath(prodconf_json).read_text() == '{"foo": "bar"}' + assert unzipped.joinpath(prodconf_py).read_text() == 'foo = "bar"' + + # Make sure that StorageElement was called twice (getURL, putFile) + assert mockSEMethod.call_count == 2 + + # Make sure that the request was not created + assert failover.transferAndRegisterFile.call_count == 0 - # Mock JobReport - mock_job_report = mocker.patch("dirac_cwl.commands.upload_log_file.JobReport") - mock_set_app_status = mocker.MagicMock() - mock_set_job_parameter = mocker.MagicMock() - mock_job_report.return_value.setApplicationStatus = mock_set_app_status - mock_job_report.return_value.setJobParameter = mock_set_job_parameter - - # Mock StorageElement - mock_se = mocker.patch("dirac_cwl.commands.upload_log_file.StorageElement") - mock_put_file = mocker.MagicMock() - mock_get_url = mocker.MagicMock() - mock_put_file.return_value = S_OK({"Successful": {}, "Failed": {expected_lfn: "Borked"}}) - mock_get_url.return_value = S_OK(urljoin("https://lhcb-dirac-logse.web.cern.ch/", expected_lfn)) - mock_se.return_value.putFile = mock_put_file - mock_se.return_value.getURL = mock_get_url - - command = UploadLogFile() - - # Mock failover - mock_failover = mocker.patch.object(command, "generate_failover_transfer") - mock_failover.return_value = S_ERROR() - - result = command.execute( - basedir, - job_id=self.JOB_ID, - production_id=self.PRODUCTION_ID, - namespace=self.NAMESPACE, - config_version=self.CONFIG_VERSION, - ) + # Make sure the application status was not changed + assert jr.setApplicationStatus.call_count == 0 - assert not result["OK"] - mock_get_url.assert_not_called() - mock_put_file.assert_called_once_with({expected_lfn: expected_path}) - mock_failover.assert_called_once_with(expected_path, zip_name, expected_lfn) - mock_set_app_status.assert_called_once() - mock_set_job_parameter.assert_not_called() + # Check the jobReport.setParameter arguments + assert jr.setJobParameter.call_count == 1 + assert jr.setJobParameter.call_args_list + params = jr.setJobParameter.call_args_list[0][0] + assert params[0] == "Log URL" + assert params[1] == f'Log file directory' - def test_no_files_to_zip(self, basedir, mocker): - """Test execution when the job did not return any files.""" - import shutil + shutil.rmtree(updated_wf_commons["log_dir"], ignore_errors=True) - shutil.rmtree(basedir) + def test_uploadLogFile_noOutputFile(self, mocker, uplogfile, wf_commons): + """Test execution of UploadLogFile module when there is no output files. - # Mock JobReport - mock_job_report = mocker.patch("dirac_cwl.commands.upload_log_file.JobReport") - mock_set_app_status = mocker.MagicMock() - mock_set_job_parameter = mocker.MagicMock() - mock_job_report.return_value.setApplicationStatus = mock_set_app_status - mock_job_report.return_value.setJobParameter = mock_set_job_parameter - - result = UploadLogFile().execute( - basedir, - job_id=self.JOB_ID, - production_id=self.PRODUCTION_ID, - namespace=self.NAMESPACE, - config_version=self.CONFIG_VERSION, + * populateLogDirectory should return an error, because there is no "successful" files in log_dir. + """ + mockSEMethod = mocker.patch( + "DIRAC.Resources.Storage.StorageElement.StorageElementItem._StorageElementItem__executeMethod", + return_value=S_OK({"Failed": [], "Successful": {"notImportant": "notImportant"}}), ) + mock_request = mocker.patch("dirac_cwl.commands.upload_log_file.Request") + mock_failover = mocker.patch("dirac_cwl.commands.upload_log_file.FailoverTransfer") + mock_job_report = mocker.patch("dirac_cwl.commands.upload_log_file.JobReport") - assert result["OK"] - assert result["Value"] == "No files to upload" - mock_set_app_status.assert_not_called() + req = Request() + mock_request.return_value = req - def test_failed_to_zip(self, basedir, mocker: MockerFixture): - """Test failure while zipping.""" - command = UploadLogFile() + failover = FailoverTransfer(req) + mocker.patch.object(failover, "transferAndRegisterFile", return_value=S_OK()) + mock_failover.return_value = failover + + jr = JobReport(wf_commons["job_id"]) + mocker.patch.object(jr, "setApplicationStatus") + mocker.patch.object(jr, "setJobParameter") + mock_job_report.return_value = jr - # Mocker zip - mock_zip = mocker.patch.object(command, "zip_files") - mock_zip.side_effect = [AttributeError(), OSError(), ValueError()] + # Execute the module + wf_commons_path = create_workflow_commons(wf_commons) - # Mock JobReport + uplogfile.execute(job_path) + + with open(wf_commons_path, "r", encoding="utf-8") as f: + updated_wf_commons = json.load(f) + + # Check the log directory + assert updated_wf_commons["log_dir"] != "" + log_dir = Path(updated_wf_commons["log_dir"]) + assert log_dir.exists() + assert log_dir.is_dir() + # Make sure log_dir is an empty directory + assert not list(log_dir.iterdir()) + + # Check the generated zip file + zipFile = Path(f"{updated_wf_commons['prod_job_id']}.zip") + assert not zipFile.exists() + + # Make sure that StorageElement was called twice (getURL, putFile) + assert mockSEMethod.call_count == 0 + + # Make sure that the request was not created + assert failover.transferAndRegisterFile.call_count == 0 + + # Make sure the application status was changed + assert jr.setApplicationStatus.call_count == 1 + assert jr.setJobParameter.call_count == 0 + + shutil.rmtree(updated_wf_commons["log_dir"], ignore_errors=True) + + def test_uploadLogFile_zipException(self, mocker, uplogfile, wf_commons, prodconf_json, prodconf_py): + """Test execution of UploadLogFile module when an exception is raised when zipping files.""" + mocker.patch("LHCbDIRAC.Workflow.Modules.UploadLogFile.zipFiles", side_effect=OSError) + mockSEMethod = mocker.patch( + "DIRAC.Resources.Storage.StorageElement.StorageElementItem._StorageElementItem__executeMethod", + return_value=S_OK({"Failed": [], "Successful": {"notImportant": "notImportant"}}), + ) + mock_request = mocker.patch("dirac_cwl.commands.upload_log_file.Request") + mock_failover = mocker.patch("dirac_cwl.commands.upload_log_file.FailoverTransfer") mock_job_report = mocker.patch("dirac_cwl.commands.upload_log_file.JobReport") - mock_set_app_status = mocker.MagicMock() - mock_set_job_parameter = mocker.MagicMock() - mock_job_report.return_value.setApplicationStatus = mock_set_app_status - mock_job_report.return_value.setJobParameter = mock_set_job_parameter - - # Test raising AttributeError - result = command.execute( - basedir, - job_id=self.JOB_ID, - production_id=self.PRODUCTION_ID, - namespace=self.NAMESPACE, - config_version=self.CONFIG_VERSION, + + req = Request() + mock_request.return_value = req + + failover = FailoverTransfer(req) + mocker.patch.object(failover, "transferAndRegisterFile", return_value=S_OK()) + mock_failover.return_value = failover + + jr = JobReport(wf_commons["job_id"]) + mocker.patch.object(jr, "setApplicationStatus") + mock_job_report.return_value = jr + + # Execute the module + wf_commons_path = create_workflow_commons(wf_commons) + + uplogfile.execute(job_path) + + with open(wf_commons_path, "r", encoding="utf-8") as f: + updated_wf_commons = json.load(f) + + # Check the log directory + assert updated_wf_commons["log_dir"] != "" + log_dir = Path(updated_wf_commons["log_dir"]) + assert log_dir.exists() + assert log_dir.is_dir() + assert log_dir.joinpath(prodconf_json).exists() + assert log_dir.joinpath(prodconf_json).read_text() == '{"foo": "bar"}' + assert log_dir.joinpath(prodconf_py).exists() + assert log_dir.joinpath(prodconf_py).read_text() == 'foo = "bar"' + + for file in log_dir.iterdir(): + assert file.stat().st_mode & 0o777 == 0o755 + + # Check the generated zip file + zipFile = Path(f"{updated_wf_commons['prod_job_id']}.zip") + assert not zipFile.exists() + + # Make sure that StorageElement was called twice (getURL, putFile) + assert mockSEMethod.call_count == 0 + + # Make sure that the request was not created + assert failover.transferAndRegisterFile.call_count == 0 + + # Make sure the application status was changed + assert jr.setApplicationStatus.call_count == 1 + + shutil.rmtree(updated_wf_commons["log_dir"], ignore_errors=True) + + def test_uploadLogFile_zipError(self, mocker, uplogfile, wf_commons, prodconf_json, prodconf_py): + """Test execution of UploadLogFile module when an error is occurring when zipping files.""" + mocker.patch("LHCbDIRAC.Workflow.Modules.UploadLogFile.zipFiles", return_value=S_ERROR("Error")) + mockSEMethod = mocker.patch( + "DIRAC.Resources.Storage.StorageElement.StorageElementItem._StorageElementItem__executeMethod", + return_value=S_OK({"Failed": [], "Successful": {"notImportant": "notImportant"}}), ) + mock_request = mocker.patch("dirac_cwl.commands.upload_log_file.Request") + mock_failover = mocker.patch("dirac_cwl.commands.upload_log_file.FailoverTransfer") + mock_job_report = mocker.patch("dirac_cwl.commands.upload_log_file.JobReport") + + req = Request() + mock_request.return_value = req + + failover = FailoverTransfer(req) + mocker.patch.object(failover, "transferAndRegisterFile", return_value=S_OK()) + mock_failover.return_value = failover + + jr = JobReport(wf_commons["job_id"]) + mocker.patch.object(jr, "setApplicationStatus") + mock_job_report.return_value = jr + + # Execute the module + wf_commons_path = create_workflow_commons(wf_commons) + + uplogfile.execute(job_path) + + with open(wf_commons_path, "r", encoding="utf-8") as f: + updated_wf_commons = json.load(f) + + # Check the log directory + assert updated_wf_commons["log_dir"] != "" + log_dir = Path(updated_wf_commons["log_dir"]) + assert log_dir.exists() + assert log_dir.is_dir() + assert log_dir.joinpath(prodconf_json).exists() + assert log_dir.joinpath(prodconf_json).read_text() == '{"foo": "bar"}' + assert log_dir.joinpath(prodconf_py).exists() + assert log_dir.joinpath(prodconf_py).read_text() == 'foo = "bar"' + + for file in log_dir.iterdir(): + assert file.stat().st_mode & 0o777 == 0o755 + + # Check the generated zip file + zipFile = Path(f"{updated_wf_commons['prod_job_id']}.zip") + assert not zipFile.exists() - assert result["OK"] - assert "Failed to zip files" in result["Value"] - assert "AttributeError" in result["Value"] - mock_set_app_status.assert_called_once_with("Failed to create zip of log files") - mock_set_app_status.reset_mock() - - result = command.execute( - basedir, - job_id=self.JOB_ID, - production_id=self.PRODUCTION_ID, - namespace=self.NAMESPACE, - config_version=self.CONFIG_VERSION, + # Make sure that StorageElement was called twice (getURL, putFile) + assert mockSEMethod.call_count == 0 + + # Make sure that the request was not created + assert failover.transferAndRegisterFile.call_count == 0 + + # Make sure the application status was changed + assert jr.setApplicationStatus.call_count == 1 + + shutil.rmtree(updated_wf_commons["log_dir"], ignore_errors=True) + + def test_uploadLogFile_SEError(self, mocker, uplogfile, wf_commons, prodconf_json, prodconf_py): + """Test execution of UploadLogFile module when an error is occurring when calling StorageElement.""" + mocker.patch("LHCbDIRAC.Workflow.Modules.UploadLogFile.getDestinationSEList", return_value=["SE1", "SE2"]) + mockSEMethod = mocker.patch( + "DIRAC.Resources.Storage.StorageElement.StorageElementItem._StorageElementItem__executeMethod", + return_value=S_ERROR("Error"), ) + mock_request = mocker.patch("dirac_cwl.commands.upload_log_file.Request") + mock_failover = mocker.patch("dirac_cwl.commands.upload_log_file.FailoverTransfer") + mock_job_report = mocker.patch("dirac_cwl.commands.upload_log_file.JobReport") + + req = Request() + mock_request.return_value = req + + failover = FailoverTransfer(req) + mocker.patch.object(failover, "transferAndRegisterFile", return_value=S_OK({"uploadedSE": "SE1"})) + mock_failover.return_value = failover + + jr = JobReport(wf_commons["job_id"]) + mocker.patch.object(jr, "setApplicationStatus") + mock_job_report.return_value = jr + + # Execute the module + wf_commons_path = create_workflow_commons(wf_commons) - # Test raising OSError - assert result["OK"] - assert "Failed to zip files" in result["Value"] - assert "OSError" in result["Value"] - mock_set_app_status.assert_called_once_with("Failed to create zip of log files") - mock_set_app_status.reset_mock() - - result = command.execute( - basedir, - job_id=self.JOB_ID, - production_id=self.PRODUCTION_ID, - namespace=self.NAMESPACE, - config_version=self.CONFIG_VERSION, + uplogfile.execute(job_path) + + with open(wf_commons_path, "r", encoding="utf-8") as f: + updated_wf_commons = json.load(f) + + # Check the log directory + assert updated_wf_commons["log_dir"] != "" + log_dir = Path(updated_wf_commons["log_dir"]) + assert log_dir.exists() + assert log_dir.is_dir() + assert log_dir.joinpath(prodconf_json).exists() + assert log_dir.joinpath(prodconf_json).read_text() == '{"foo": "bar"}' + assert log_dir.joinpath(prodconf_py).exists() + assert log_dir.joinpath(prodconf_py).read_text() == 'foo = "bar"' + + for file in log_dir.iterdir(): + assert file.stat().st_mode & 0o777 == 0o755 + + # Check the generated zip file + zipFile = Path(f"{updated_wf_commons['prod_job_id']}.zip") + assert zipFile.exists() + + zipfile.ZipFile(zipFile, "r").extractall("unzipped") + unzipped = Path("unzipped").joinpath(updated_wf_commons["prod_job_id"]) + assert unzipped.joinpath(prodconf_json).exists() + assert unzipped.joinpath(prodconf_py).exists() + assert unzipped.joinpath(prodconf_json).read_text() == '{"foo": "bar"}' + assert unzipped.joinpath(prodconf_py).read_text() == 'foo = "bar"' + + # Make sure that StorageElement was called twice (getURL, putFile) + assert mockSEMethod.call_count == 2 + + # Make sure that the request was created + assert failover.transferAndRegisterFile.call_count == 1 + + operations = updated_wf_commons["request_dict"]["Operations"] + + assert len(operations) == 2 + assert operations[0]["Type"] == "LogUpload" + assert len(operations[0]["Files"]) == 1 + assert operations[0]["Files"][0]["LFN"] == updated_wf_commons["log_lfn_path"] + + assert operations[1]["Type"] == "RemoveFile" + assert len(operations[1]["Files"]) == 1 + assert operations[1]["Files"][0]["LFN"] == updated_wf_commons["log_lfn_path"] + + # Make sure the application status was not changed + assert jr.setApplicationStatus.call_count == 0 + + shutil.rmtree(updated_wf_commons["log_dir"], ignore_errors=True) + + def test_uploadLogFile_transferError(self, mocker, uplogfile, wf_commons, prodconf_json, prodconf_py): + """Test execution of UploadLogFile module when calling StorageElement and FailoverTransfer fail.""" + mocker.patch("LHCbDIRAC.Workflow.Modules.UploadLogFile.getDestinationSEList", return_value=["SE1", "SE2"]) + mockSEMethod = mocker.patch( + "DIRAC.Resources.Storage.StorageElement.StorageElementItem._StorageElementItem__executeMethod", + return_value=S_ERROR("Error"), ) + mock_request = mocker.patch("dirac_cwl.commands.upload_log_file.Request") + mock_failover = mocker.patch("dirac_cwl.commands.upload_log_file.FailoverTransfer") + mock_job_report = mocker.patch("dirac_cwl.commands.upload_log_file.JobReport") - # Test raising ValueError - assert result["OK"] - assert "Failed to zip files" in result["Value"] - assert "ValueError" in result["Value"] - mock_set_app_status.assert_called_once_with("Failed to create zip of log files") + req = Request() + mock_request.return_value = req + + failover = FailoverTransfer(req) + mocker.patch.object(failover, "transferAndRegisterFile", return_value=S_ERROR("Error")) + mock_failover.return_value = failover + + mock_job_report = mocker.patch("dirac_cwl.commands.upload_log_file.JobReport") + jr = JobReport(wf_commons["job_id"]) + mocker.patch.object(jr, "setApplicationStatus") + mock_job_report.return_value = jr + + # Execute the module + wf_commons_path = create_workflow_commons(wf_commons) + + uplogfile.execute(job_path) + + with open(wf_commons_path, "r", encoding="utf-8") as f: + updated_wf_commons = json.load(f) + + # Check the log directory + assert updated_wf_commons["log_dir"] != "" + log_dir = Path(updated_wf_commons["log_dir"]) + assert log_dir.exists() + assert log_dir.is_dir() + assert log_dir.joinpath(prodconf_json).exists() + assert log_dir.joinpath(prodconf_json).read_text() == '{"foo": "bar"}' + assert log_dir.joinpath(prodconf_py).exists() + assert log_dir.joinpath(prodconf_py).read_text() == 'foo = "bar"' + + for file in log_dir.iterdir(): + assert file.stat().st_mode & 0o777 == 0o755 + + # Check the generated zip file + zipFile = Path(f"{updated_wf_commons['prod_job_id']}.zip") + assert zipFile.exists() + + zipfile.ZipFile(zipFile, "r").extractall("unzipped") + unzipped = Path("unzipped").joinpath(updated_wf_commons["prod_job_id"]) + assert unzipped.joinpath(prodconf_json).exists() + assert unzipped.joinpath(prodconf_py).exists() + assert unzipped.joinpath(prodconf_json).read_text() == '{"foo": "bar"}' + assert unzipped.joinpath(prodconf_py).read_text() == 'foo = "bar"' + + # Make sure that StorageElement was called twice (getURL, putFile) + assert mockSEMethod.call_count == 2 + + # Make sure that the request was not created + assert failover.transferAndRegisterFile.call_count == 1 + + operations = updated_wf_commons["request_dict"]["Operations"] + + assert len(operations) == 0 + + # Make sure the application status was changed + assert jr.setApplicationStatus.call_count == 1 - mock_set_job_parameter.assert_not_called() + shutil.rmtree(updated_wf_commons["log_dir"], ignore_errors=True) class TestBookkeepingReport: From f4d2821c422aa0529c98f9bbf24287ccedf5249e Mon Sep 17 00:00:00 2001 From: Jorge Lisa <64639359+AcquaDiGiorgio@users.noreply.github.com> Date: Thu, 7 May 2026 09:29:36 +0200 Subject: [PATCH 15/21] chore: update pixi.lock --- pixi.lock | 46 +++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 41 insertions(+), 5 deletions(-) diff --git a/pixi.lock b/pixi.lock index 8884ad2..e843b45 100644 --- a/pixi.lock +++ b/pixi.lock @@ -187,7 +187,7 @@ environments: - pypi: https://files.pythonhosted.org/packages/6d/10/b37ac718c5903758fa9058a5182026a4f3b65443196b82c7840389ea0dbd/lbplatformutils-4.6.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/02/64/c86924898062e8217ed914a29458cfde9e4a9b80e4d4cbcca141983ba339/lbprodrun-1.12.4-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/29/ce/ed422816fb30ffa3bc11597b30d5deca06b4a1388707a04215da73c65b53/levenshtein-0.27.3-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl - - pypi: git+https://gitlab.cern.ch/jlisalab/LHCbDIRAC.git?rev=modules-to-cwl-migration#c441175f3289d6d85abf5d5612c3ff964edd9a5c + - pypi: git+https://gitlab.cern.ch/jlisalab/LHCbDIRAC.git?rev=modules-to-cwl-migration#bc5f8f1804107bc8807edcc98a97c346ef61c0e8 - pypi: https://files.pythonhosted.org/packages/7f/37/8ea3555769b6048b5e4ec162cc90fd32e761c0e381ffb3baf888cb0d8a71/lhcbdiracx_api-0.0.8-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/68/15/bfb0c717b8f23c16907f3e73e8f56010ccd72e9900a108209665b0d9ed4b/lhcbdiracx_cli-0.0.8-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/2d/88/67602dfa2d7ab5d0518af82db34ab4d70dc2c3029b3ca788299a3be4a96d/lhcbdiracx_client-0.0.8-py3-none-any.whl @@ -200,6 +200,7 @@ environments: - pypi: https://files.pythonhosted.org/packages/2f/40/dc34d1a8d5f1e51fc64640b62b191684da52ca469da9cd74e84936ffa4a6/msgpack-1.1.2-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - pypi: https://files.pythonhosted.org/packages/fe/3b/8ec5074bcfc450fe84273713b4b0a0dd47c0249358f5d82eb8104ffe2520/multidict-6.7.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - pypi: https://files.pythonhosted.org/packages/9e/c9/b2622292ea83fbb4ec318f5b9ab867d0a28ab43c5717bb85b0a5f6b3b0a4/networkx-3.6.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/76/3e/c0b690253f0b82d86e99949af13533363acfb5432ecb5d53dd5b3bce9c34/orjson-3.11.9-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - pypi: https://files.pythonhosted.org/packages/15/88/3cdd54fa279341afa10acf8d2b503556b1375245dccc9315659f795dd2e9/pandas-3.0.2-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl - pypi: https://files.pythonhosted.org/packages/a9/90/a744336f5af32c433bd09af7854599682a383b37cfd78f7de263de6ad6cb/paramiko-4.0.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/9e/c3/059298687310d527a58bb01f3b1965787ee3b40dce76752eda8b44e9a2c5/pexpect-4.9.0-py2.py3-none-any.whl @@ -233,6 +234,7 @@ environments: - pypi: https://files.pythonhosted.org/packages/89/d4/24a137517140fc8cc07f7423695b9296c993d6b6cbf2a7867d8f859de77f/schema_salad-8.9.20251102115403-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - pypi: https://files.pythonhosted.org/packages/70/98/d82f14ac7ffedbd38dfa2383f142b26d18d23ca6cf35a40f4af60df666bd/sh-2.2.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/e0/f9/0595336914c5619e5f28a1fb793285925a8cd4b432c9da0a987836c7f822/shellingham-1.5.4-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/59/25/68f81c50aeb3f30e01c20da0f56d14c1a779b57d9308c50e19c63dc8413f/signurlarity-0.2.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/04/be/d09147ad1ec7934636ad912901c5fd7667e1c858e19d355237db0d0cd5e4/smmap-5.0.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/46/2c/1462b1d0a634697ae9e55b3cecdcb64788e8b7d63f54d923fcd0bb140aed/soupsieve-2.8.3-py3-none-any.whl @@ -429,7 +431,7 @@ environments: - pypi: https://files.pythonhosted.org/packages/6d/10/b37ac718c5903758fa9058a5182026a4f3b65443196b82c7840389ea0dbd/lbplatformutils-4.6.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/02/64/c86924898062e8217ed914a29458cfde9e4a9b80e4d4cbcca141983ba339/lbprodrun-1.12.4-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/f3/e1/2f705da403f865a5fa3449b155738dc9c53021698fd6926253a9af03180b/levenshtein-0.27.3-cp314-cp314-macosx_10_15_x86_64.whl - - pypi: git+https://gitlab.cern.ch/jlisalab/LHCbDIRAC.git?rev=modules-to-cwl-migration#c441175f3289d6d85abf5d5612c3ff964edd9a5c + - pypi: git+https://gitlab.cern.ch/jlisalab/LHCbDIRAC.git?rev=modules-to-cwl-migration#bc5f8f1804107bc8807edcc98a97c346ef61c0e8 - pypi: https://files.pythonhosted.org/packages/7f/37/8ea3555769b6048b5e4ec162cc90fd32e761c0e381ffb3baf888cb0d8a71/lhcbdiracx_api-0.0.8-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/68/15/bfb0c717b8f23c16907f3e73e8f56010ccd72e9900a108209665b0d9ed4b/lhcbdiracx_cli-0.0.8-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/2d/88/67602dfa2d7ab5d0518af82db34ab4d70dc2c3029b3ca788299a3be4a96d/lhcbdiracx_client-0.0.8-py3-none-any.whl @@ -442,6 +444,7 @@ environments: - pypi: https://files.pythonhosted.org/packages/22/71/201105712d0a2ff07b7873ed3c220292fb2ea5120603c00c4b634bcdafb3/msgpack-1.1.2-cp314-cp314-macosx_10_13_x86_64.whl - pypi: https://files.pythonhosted.org/packages/d5/22/492f2246bb5b534abd44804292e81eeaf835388901f0c574bac4eeec73c5/multidict-6.7.1-cp314-cp314-macosx_10_15_x86_64.whl - pypi: https://files.pythonhosted.org/packages/9e/c9/b2622292ea83fbb4ec318f5b9ab867d0a28ab43c5717bb85b0a5f6b3b0a4/networkx-3.6.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/8e/eb/5da01e356015aee6ecfa1187ced87aef51364e306f5e695dd52719bf0e78/orjson-3.11.9-cp314-cp314-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl - pypi: https://files.pythonhosted.org/packages/bb/40/c6ea527147c73b24fc15c891c3fcffe9c019793119c5742b8784a062c7db/pandas-3.0.2-cp314-cp314-macosx_10_15_x86_64.whl - pypi: https://files.pythonhosted.org/packages/a9/90/a744336f5af32c433bd09af7854599682a383b37cfd78f7de263de6ad6cb/paramiko-4.0.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/9e/c3/059298687310d527a58bb01f3b1965787ee3b40dce76752eda8b44e9a2c5/pexpect-4.9.0-py2.py3-none-any.whl @@ -475,6 +478,7 @@ environments: - pypi: https://files.pythonhosted.org/packages/62/86/3915cb5a603e1b1d798e1ee1ce2a0a390a0f85d35da97e4b6d1c6a45421b/schema_salad-8.9.20251102115403-cp314-cp314-macosx_10_15_x86_64.whl - pypi: https://files.pythonhosted.org/packages/70/98/d82f14ac7ffedbd38dfa2383f142b26d18d23ca6cf35a40f4af60df666bd/sh-2.2.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/e0/f9/0595336914c5619e5f28a1fb793285925a8cd4b432c9da0a987836c7f822/shellingham-1.5.4-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/59/25/68f81c50aeb3f30e01c20da0f56d14c1a779b57d9308c50e19c63dc8413f/signurlarity-0.2.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/04/be/d09147ad1ec7934636ad912901c5fd7667e1c858e19d355237db0d0cd5e4/smmap-5.0.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/46/2c/1462b1d0a634697ae9e55b3cecdcb64788e8b7d63f54d923fcd0bb140aed/soupsieve-2.8.3-py3-none-any.whl @@ -670,7 +674,7 @@ environments: - pypi: https://files.pythonhosted.org/packages/6d/10/b37ac718c5903758fa9058a5182026a4f3b65443196b82c7840389ea0dbd/lbplatformutils-4.6.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/02/64/c86924898062e8217ed914a29458cfde9e4a9b80e4d4cbcca141983ba339/lbprodrun-1.12.4-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/76/2c/bb6ef359e007fe7b6b3195b68a94f4dd3ecd1885ee337ee8fbd4df55996f/levenshtein-0.27.3-cp314-cp314-macosx_11_0_arm64.whl - - pypi: git+https://gitlab.cern.ch/jlisalab/LHCbDIRAC.git?rev=modules-to-cwl-migration#c441175f3289d6d85abf5d5612c3ff964edd9a5c + - pypi: git+https://gitlab.cern.ch/jlisalab/LHCbDIRAC.git?rev=modules-to-cwl-migration#bc5f8f1804107bc8807edcc98a97c346ef61c0e8 - pypi: https://files.pythonhosted.org/packages/7f/37/8ea3555769b6048b5e4ec162cc90fd32e761c0e381ffb3baf888cb0d8a71/lhcbdiracx_api-0.0.8-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/68/15/bfb0c717b8f23c16907f3e73e8f56010ccd72e9900a108209665b0d9ed4b/lhcbdiracx_cli-0.0.8-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/2d/88/67602dfa2d7ab5d0518af82db34ab4d70dc2c3029b3ca788299a3be4a96d/lhcbdiracx_client-0.0.8-py3-none-any.whl @@ -683,6 +687,7 @@ environments: - pypi: https://files.pythonhosted.org/packages/1b/9f/38ff9e57a2eade7bf9dfee5eae17f39fc0e998658050279cbb14d97d36d9/msgpack-1.1.2-cp314-cp314-macosx_11_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/f1/4f/733c48f270565d78b4544f2baddc2fb2a245e5a8640254b12c36ac7ac68e/multidict-6.7.1-cp314-cp314-macosx_11_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/9e/c9/b2622292ea83fbb4ec318f5b9ab867d0a28ab43c5717bb85b0a5f6b3b0a4/networkx-3.6.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/8e/eb/5da01e356015aee6ecfa1187ced87aef51364e306f5e695dd52719bf0e78/orjson-3.11.9-cp314-cp314-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl - pypi: https://files.pythonhosted.org/packages/95/25/bdb9326c3b5455f8d4d3549fce7abcf967259de146fe2cf7a82368141948/pandas-3.0.2-cp314-cp314-macosx_11_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/a9/90/a744336f5af32c433bd09af7854599682a383b37cfd78f7de263de6ad6cb/paramiko-4.0.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/9e/c3/059298687310d527a58bb01f3b1965787ee3b40dce76752eda8b44e9a2c5/pexpect-4.9.0-py2.py3-none-any.whl @@ -716,6 +721,7 @@ environments: - pypi: https://files.pythonhosted.org/packages/71/3f/212e32937253312e102e152c954a5495df0379255719ce28e0288194748d/schema_salad-8.9.20251102115403-cp314-cp314-macosx_11_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/70/98/d82f14ac7ffedbd38dfa2383f142b26d18d23ca6cf35a40f4af60df666bd/sh-2.2.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/e0/f9/0595336914c5619e5f28a1fb793285925a8cd4b432c9da0a987836c7f822/shellingham-1.5.4-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/59/25/68f81c50aeb3f30e01c20da0f56d14c1a779b57d9308c50e19c63dc8413f/signurlarity-0.2.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/04/be/d09147ad1ec7934636ad912901c5fd7667e1c858e19d355237db0d0cd5e4/smmap-5.0.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/46/2c/1462b1d0a634697ae9e55b3cecdcb64788e8b7d63f54d923fcd0bb140aed/soupsieve-2.8.3-py3-none-any.whl @@ -2668,9 +2674,9 @@ packages: requires_dist: - rapidfuzz>=3.9.0,<4.0.0 requires_python: '>=3.10' -- pypi: git+https://gitlab.cern.ch/jlisalab/LHCbDIRAC.git?rev=modules-to-cwl-migration#c441175f3289d6d85abf5d5612c3ff964edd9a5c +- pypi: git+https://gitlab.cern.ch/jlisalab/LHCbDIRAC.git?rev=modules-to-cwl-migration#bc5f8f1804107bc8807edcc98a97c346ef61c0e8 name: lhcbdirac - version: 0.1.dev20447+gc441175f3 + version: 0.1.dev20470+gbc5f8f180 requires_dist: - dirac~=9.1 - lbplatformutils>=4.6.1 @@ -2694,6 +2700,7 @@ packages: - lhcbdiracx-client - lhcbdiracx-core - lhcbdiracx-cli + - signurlarity - oracledb ; extra == 'server' - dirac[server]~=9.1.0 ; extra == 'server' - psutil ; extra == 'server' @@ -4472,6 +4479,16 @@ packages: purls: [] size: 3104268 timestamp: 1769556384749 +- pypi: https://files.pythonhosted.org/packages/76/3e/c0b690253f0b82d86e99949af13533363acfb5432ecb5d53dd5b3bce9c34/orjson-3.11.9-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl + name: orjson + version: 3.11.9 + sha256: aaea64f3f467d22e70eeed68bdccb3bc4f83f650446c4a03c59f2cba28a108db + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/8e/eb/5da01e356015aee6ecfa1187ced87aef51364e306f5e695dd52719bf0e78/orjson-3.11.9-cp314-cp314-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl + name: orjson + version: 3.11.9 + sha256: b6ef1979adc4bc243523f1a2ba91418030a8e29b0a99cbe7e0e2d6807d4dce6e + requires_python: '>=3.10' - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda sha256: c1fc0f953048f743385d31c468b4a678b3ad20caffdeaa94bed85ba63049fd58 md5: b76541e68fea4d511b1ac46a28dcd2c6 @@ -5852,6 +5869,25 @@ packages: version: 1.5.4 sha256: 7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686 requires_python: '>=3.7' +- pypi: https://files.pythonhosted.org/packages/59/25/68f81c50aeb3f30e01c20da0f56d14c1a779b57d9308c50e19c63dc8413f/signurlarity-0.2.2-py3-none-any.whl + name: signurlarity + version: 0.2.2 + sha256: 0c8089ecac04ce105e525b60749d134b171410beefc962e167e0e64141d6e7a7 + requires_dist: + - cryptography>=41.0.0 + - httpx>=0.24.0 + - orjson + - aiobotocore>=2.15 ; extra == 'testing' + - botocore>=1.35 ; extra == 'testing' + - httpx ; extra == 'testing' + - moto[server] ; extra == 'testing' + - pytest ; extra == 'testing' + - pytest-asyncio ; extra == 'testing' + - pytest-benchmark ; extra == 'testing' + - pytest-xdist ; extra == 'testing' + - rich ; extra == 'testing' + - ty ; extra == 'testing' + requires_python: '>=3.11' - pypi: https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl name: six version: 1.17.0 From 028ca4fc5eac1072cb847cc00ea4de11edc503ea Mon Sep 17 00:00:00 2001 From: Jorge Lisa <64639359+AcquaDiGiorgio@users.noreply.github.com> Date: Mon, 11 May 2026 12:29:13 +0200 Subject: [PATCH 16/21] chore: fix BookkeepingReport typo --- src/dirac_cwl/commands/__init__.py | 4 ++-- src/dirac_cwl/commands/bookkeeping_report.py | 2 +- test/test_commands.py | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/dirac_cwl/commands/__init__.py b/src/dirac_cwl/commands/__init__.py index f2446d6..61aed97 100644 --- a/src/dirac_cwl/commands/__init__.py +++ b/src/dirac_cwl/commands/__init__.py @@ -1,7 +1,7 @@ """Command classes for workflow pre/post-processing operations.""" from .analyze_xml_summary import AnalyseXmlSummary -from .bookkeeping_report import BookeepingReport +from .bookkeeping_report import BookkeepingReport from .core import PostProcessCommand, PreProcessCommand from .failover_request import FailoverRequest from .upload_log_file import UploadLogFile @@ -13,7 +13,7 @@ "PreProcessCommand", "PostProcessCommand", "UploadLogFile", - "BookeepingReport", + "BookkeepingReport", "FailoverRequest", "UploadOutputData", "WorkflowAccounting", diff --git a/src/dirac_cwl/commands/bookkeeping_report.py b/src/dirac_cwl/commands/bookkeeping_report.py index 1573ad7..1b11cdd 100644 --- a/src/dirac_cwl/commands/bookkeeping_report.py +++ b/src/dirac_cwl/commands/bookkeeping_report.py @@ -21,7 +21,7 @@ from .utils import prepare_lhcb_workflow_commons, save_workflow_commons -class BookeepingReport(PostProcessCommand): +class BookkeepingReport(PostProcessCommand): """Generates a bookkeeping report file based on the XMLSummary and the pool XML catalog.""" def execute(self, job_path, **kwargs): diff --git a/test/test_commands.py b/test/test_commands.py index 51d18a6..04b689d 100644 --- a/test/test_commands.py +++ b/test/test_commands.py @@ -29,7 +29,7 @@ from dirac_cwl.commands import ( AnalyseXmlSummary, - BookeepingReport, + BookkeepingReport, FailoverRequest, UploadLogFile, UploadOutputData, @@ -579,7 +579,7 @@ def bk_report(self, mocker): mock_get_n_procs.return_value = number_of_processors - yield BookeepingReport() + yield BookkeepingReport() Path("00209455_00001537_1").unlink(missing_ok=True) Path("00209455_00001537_1.sim").unlink(missing_ok=True) From d9e24e97fbddda6dc6606a4f44e60558f3130dfb Mon Sep 17 00:00:00 2001 From: Jorge Lisa <64639359+AcquaDiGiorgio@users.noreply.github.com> Date: Mon, 11 May 2026 12:37:08 +0200 Subject: [PATCH 17/21] chore: fix possible None values while saving workflow_commons --- src/dirac_cwl/commands/analyze_xml_summary.py | 1 + src/dirac_cwl/commands/bookkeeping_report.py | 1 + src/dirac_cwl/commands/failover_request.py | 1 + src/dirac_cwl/commands/upload_output_data.py | 9 +++++---- src/dirac_cwl/commands/workflow_accounting.py | 3 ++- 5 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/dirac_cwl/commands/analyze_xml_summary.py b/src/dirac_cwl/commands/analyze_xml_summary.py index ecb1543..afd2c9d 100644 --- a/src/dirac_cwl/commands/analyze_xml_summary.py +++ b/src/dirac_cwl/commands/analyze_xml_summary.py @@ -24,6 +24,7 @@ def execute(self, job_path, **kwargs): :param kwargs: Additional keyword arguments. """ failed = False + workflow_commons = {} try: workflow_commons_path = kwargs.get("workflow_commons_path", os.path.join(job_path, "workflow_commons.json")) diff --git a/src/dirac_cwl/commands/bookkeeping_report.py b/src/dirac_cwl/commands/bookkeeping_report.py index 1b11cdd..a76c889 100644 --- a/src/dirac_cwl/commands/bookkeeping_report.py +++ b/src/dirac_cwl/commands/bookkeeping_report.py @@ -31,6 +31,7 @@ def execute(self, job_path, **kwargs): :param kwargs: Additional keyword arguments. """ failed = False + workflow_commons = {} try: # Obtain Workflow Commons workflow_commons_path = kwargs.get("workflow_commons_path", os.path.join(job_path, "workflow_commons.json")) diff --git a/src/dirac_cwl/commands/failover_request.py b/src/dirac_cwl/commands/failover_request.py index a56119f..65da097 100644 --- a/src/dirac_cwl/commands/failover_request.py +++ b/src/dirac_cwl/commands/failover_request.py @@ -32,6 +32,7 @@ def execute(self, job_path, **kwargs): :param kwargs: Additional keyword arguments. """ failed = False + workflow_commons = {} try: workflow_commons_path = kwargs.get("workflow_commons_path", os.path.join(job_path, "workflow_commons.json")) diff --git a/src/dirac_cwl/commands/upload_output_data.py b/src/dirac_cwl/commands/upload_output_data.py index 03617bf..f922db4 100644 --- a/src/dirac_cwl/commands/upload_output_data.py +++ b/src/dirac_cwl/commands/upload_output_data.py @@ -37,7 +37,9 @@ def execute(self, job_path, **kwargs): :param job_path: Path to the job working directory. :param kwargs: Additional keyword arguments. """ - fail = False + failed = False + workflow_commons = {} + request = None try: workflow_commons_path = kwargs.get("workflow_commons_path", os.path.join(job_path, "workflow_commons.json")) @@ -183,8 +185,7 @@ def execute(self, job_path, **kwargs): raise WorkflowProcessingException(result["Message"]) except: - fail = True - raise + failed = True finally: - save_workflow_commons(workflow_commons, workflow_commons_path, request, failed=fail) + save_workflow_commons(workflow_commons, workflow_commons_path, request=request, failed=failed) diff --git a/src/dirac_cwl/commands/workflow_accounting.py b/src/dirac_cwl/commands/workflow_accounting.py index 0f69946..8758f54 100644 --- a/src/dirac_cwl/commands/workflow_accounting.py +++ b/src/dirac_cwl/commands/workflow_accounting.py @@ -29,6 +29,7 @@ def execute(self, job_path, **kwargs): :param kwargs: Additional keyword arguments. """ failed = False + workflow_commons = {} try: # Obtain Workflow Commons workflow_commons_path = kwargs.get("workflow_commons_path", os.path.join(job_path, "workflow_commons.json")) @@ -101,7 +102,7 @@ def execute(self, job_path, **kwargs): except Exception as e: failed = True - raise WorkflowProcessingException() from e + raise WorkflowProcessingException(e) from e finally: if workflow_commons: From 69070217e73f86a1f7e83648dc32b11a373c9353 Mon Sep 17 00:00:00 2001 From: Jorge Lisa <64639359+AcquaDiGiorgio@users.noreply.github.com> Date: Mon, 11 May 2026 13:17:31 +0200 Subject: [PATCH 18/21] chore: set proper commands exception catching --- src/dirac_cwl/commands/analyze_xml_summary.py | 4 ++-- src/dirac_cwl/commands/bookkeeping_report.py | 4 ++-- src/dirac_cwl/commands/failover_request.py | 4 ++-- src/dirac_cwl/commands/upload_output_data.py | 3 ++- test/test_commands.py | 3 ++- 5 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/dirac_cwl/commands/analyze_xml_summary.py b/src/dirac_cwl/commands/analyze_xml_summary.py index afd2c9d..adf4222 100644 --- a/src/dirac_cwl/commands/analyze_xml_summary.py +++ b/src/dirac_cwl/commands/analyze_xml_summary.py @@ -77,9 +77,9 @@ def execute(self, job_path, **kwargs): job_report.setApplicationStatus(f"{workflow_commons['application_name']} Step OK") - except: + except Exception as e: failed = True - raise + raise WorkflowProcessingException(e) from e finally: save_workflow_commons(workflow_commons, workflow_commons_path, failed=failed) diff --git a/src/dirac_cwl/commands/bookkeeping_report.py b/src/dirac_cwl/commands/bookkeeping_report.py index a76c889..93aacc7 100644 --- a/src/dirac_cwl/commands/bookkeeping_report.py +++ b/src/dirac_cwl/commands/bookkeeping_report.py @@ -161,9 +161,9 @@ def execute(self, job_path, **kwargs): with open(bfilename, "wb") as bfile: bfile.write(doc) - except: + except Exception as e: failed = True - raise + raise WorkflowProcessingException(e) from e finally: save_workflow_commons(workflow_commons, workflow_commons_path, failed=failed) diff --git a/src/dirac_cwl/commands/failover_request.py b/src/dirac_cwl/commands/failover_request.py index 65da097..c578825 100644 --- a/src/dirac_cwl/commands/failover_request.py +++ b/src/dirac_cwl/commands/failover_request.py @@ -69,9 +69,9 @@ def execute(self, job_path, **kwargs): self.generateFailoverFile(job_report, request, workflow_commons) - except: + except Exception as e: failed = True - raise + raise WorkflowProcessingException(e) from e finally: save_workflow_commons(workflow_commons, workflow_commons_path, request=request, failed=failed) diff --git a/src/dirac_cwl/commands/upload_output_data.py b/src/dirac_cwl/commands/upload_output_data.py index f922db4..910e95b 100644 --- a/src/dirac_cwl/commands/upload_output_data.py +++ b/src/dirac_cwl/commands/upload_output_data.py @@ -184,8 +184,9 @@ def execute(self, job_path, **kwargs): if not result["OK"]: raise WorkflowProcessingException(result["Message"]) - except: + except Exception as e: failed = True + raise WorkflowProcessingException(e) from e finally: save_workflow_commons(workflow_commons, workflow_commons_path, request=request, failed=failed) diff --git a/test/test_commands.py b/test/test_commands.py index 04b689d..574f0bc 100644 --- a/test/test_commands.py +++ b/test/test_commands.py @@ -583,6 +583,7 @@ def bk_report(self, mocker): Path("00209455_00001537_1").unlink(missing_ok=True) Path("00209455_00001537_1.sim").unlink(missing_ok=True) + Path("application.log").unlink(missing_ok=True) def test_bkreport_prod_mcsimulation_success(self, bk_report, wf_commons, bookkeeping_file, xml_summary_file): """Test successful execution of BookkeepingReport module.""" @@ -1899,7 +1900,7 @@ def test_uploadOutputData_noOutput(self, mocker, upload_output, wf_commons, sim_ wf_commons_path = create_workflow_commons(wf_commons) # Execute module - with pytest.raises(OSError, match="Output data not found"): + with pytest.raises(WorkflowProcessingException, match="Output data not found"): upload_output.execute(job_path) with open(wf_commons_path, "r", encoding="utf-8") as f: From 19878445fe50f99b57f03849c31db94ed79ef449 Mon Sep 17 00:00:00 2001 From: Jorge Lisa <64639359+AcquaDiGiorgio@users.noreply.github.com> Date: Mon, 11 May 2026 14:43:15 +0200 Subject: [PATCH 19/21] chore: fix job path not being taken into account --- src/dirac_cwl/commands/upload_log_file.py | 4 +++- src/dirac_cwl/commands/utils.py | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/dirac_cwl/commands/upload_log_file.py b/src/dirac_cwl/commands/upload_log_file.py index 19a5a7e..f26e6db 100644 --- a/src/dirac_cwl/commands/upload_log_file.py +++ b/src/dirac_cwl/commands/upload_log_file.py @@ -84,7 +84,9 @@ def execute(self, job_path, **kwargs): res = systemCall(0, shlex.split("ls -al")) workflow_commons["log_dir"] = os.path.realpath( - f"./job/log/{workflow_commons['production_id']}/{workflow_commons['prod_job_id']}" + os.path.join( + job_path, f"./job/log/{workflow_commons['production_id']}/{workflow_commons['prod_job_id']}" + ) ) ########################################## diff --git a/src/dirac_cwl/commands/utils.py b/src/dirac_cwl/commands/utils.py index f910bd5..4521452 100644 --- a/src/dirac_cwl/commands/utils.py +++ b/src/dirac_cwl/commands/utils.py @@ -103,7 +103,8 @@ def save_workflow_commons(wf_commons, wf_file_path, request=None, failed=False): raise WorkflowProcessingException(f"Workflow Commons file '{wf_file_path}' not found") wf_filename = os.path.basename(wf_file_path) - wf_backup = f"{wf_filename}.bak" + wf_base_path = os.path.dirname(wf_file_path) + wf_backup = os.path.join(wf_base_path, f"{wf_filename}.bak") shutil.move(wf_file_path, wf_backup) From 947bc8ba0f7f6a72b560dadf312330c3e463e91c Mon Sep 17 00:00:00 2001 From: Jorge Lisa <64639359+AcquaDiGiorgio@users.noreply.github.com> Date: Fri, 15 May 2026 15:41:44 +0200 Subject: [PATCH 20/21] chore: change workflow commons from dict to a pydantic model --- pixi.lock | 11317 ++++++++-------- src/dirac_cwl/commands/analyze_xml_summary.py | 67 +- src/dirac_cwl/commands/bookkeeping_report.py | 125 +- src/dirac_cwl/commands/failover_request.py | 86 +- src/dirac_cwl/commands/upload_log_file.py | 73 +- src/dirac_cwl/commands/upload_output_data.py | 114 +- src/dirac_cwl/commands/utils.py | 128 - src/dirac_cwl/commands/workflow_accounting.py | 82 +- src/dirac_cwl/commands/workflow_commons.py | 221 + test/test_commands.py | 1382 +- 10 files changed, 6655 insertions(+), 6940 deletions(-) delete mode 100644 src/dirac_cwl/commands/utils.py create mode 100644 src/dirac_cwl/commands/workflow_commons.py diff --git a/pixi.lock b/pixi.lock index e843b45..0ad5576 100644 --- a/pixi.lock +++ b/pixi.lock @@ -1,4 +1,8 @@ -version: 6 +version: 7 +platforms: +- name: linux-64 +- name: osx-64 +- name: osx-arm64 environments: default: channels: @@ -9,32 +13,20 @@ environments: linux-64: - conda: https://conda.anaconda.org/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-2_gnu.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/noarch/attrs-25.4.0-pyhcf101f3_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/backports.asyncio.runner-1.2.0-pyh5ded981_2.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_8.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/c-ares-1.34.6-hb03c661_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.1.4-hbd8a1cb_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/cffi-2.0.0-py314h4a8dc5f_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/cfgv-3.5.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/cgsi-gsoap-1.3.12-h32d023c_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/cyrus-sasl-2.1.28-hd9c7081_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/davix-0.8.10-he574acc_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/dcap-2.47.14-h481617c_2.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/distlib-0.4.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/expat-2.7.3-hecca717_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/filelock-3.20.3-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/gct-6.2.1705709074-h6bbaf85_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/gfal2-2.23.5-h3ec3711_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/gsoap-2.8.123-h8dc497d_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/gtest-1.17.0-h84d6215_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/icu-78.2-h33c6efd_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/identify-2.6.16-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/json-c-0.18-h6688a6e_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-4.26.0-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-specifications-2025.9.1-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.3-hb9d3cd8_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/krb5-1.21.3-h659f571_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_101.conda @@ -74,676 +66,688 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/m2crypto-0.45.1-py314haf11619_2.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/mypy-1.19.1-py314h5bd0f2a_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/mypy_extensions-1.1.0-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/nodeenv-1.10.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/numpy-2.4.2-py314h2b28147_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/openldap-2.6.10-he970967_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.1-h35e630c_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pathspec-1.0.4-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/pcre2-10.47-haa7fec5_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/perl-5.32.1-7_hd590300_perl5.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.5.1-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pre-commit-4.5.1-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/psutil-7.2.2-py314h0f05182_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/pugixml-1.15-h3f63f65_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-asyncio-1.3.0-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-mock-3.15.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.14.3-h32b2ec7_100_cp314.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/python-gfal2-1.13.1-py314h1571e64_2.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/python-librt-0.7.8-py314h0f05182_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/pyyaml-6.0.3-py314h67df5f8_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/referencing-0.37.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/rpds-py-0.30.0-py314h2e6c369_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/ruff-0.15.0-h40fa522_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/scitokens-cpp-1.3.0-h096d96b_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-80.10.2-pyh332efcf_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/srm-ifce-1.24.6-h3b26d37_2.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.0-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/ukkonen-1.1.0-py314h9891dd4_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/virtualenv-20.36.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/voms-2.1.0rc3-h25bd2b9_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/xrootd-5.9.1-py314h75aeccf_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/yaml-0.2.5-h280c20c_3.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/zlib-1.3.1-hb9d3cd8_2.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda - - pypi: https://files.pythonhosted.org/packages/cd/22/4d16dca3bd1d6475a53063eb72150269cea1a0a201b55288b3402f61f119/aiobotocore-3.1.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/0f/15/5bf3b99495fb160b63f95972b81750f18f7f4e02ad051373b669d17d44f2/aiohappyeyeballs-2.6.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e3/d1/e30e537a15f53485b61f5be525f2157da719819e8377298502aebac45536/aiohttp-3.13.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/10/a1/510b0a7fadc6f43a6ce50152e69dbd86415240835868bb0bd9b5b88b1e06/aioitertools-0.13.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/38/0e/27be9fdef66e72d64c0cdc3cc2823101b80585f8119b5c112c2e8f5f7dab/anyio-4.12.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/74/f5/9373290775639cb67a2fce7f629a1c240dce9f12fe927bc32b2736e16dfc/argcomplete-3.6.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ed/c9/d7977eaacb9df673210491da99e6a247e93df98c715fc43fd136ce1d3d33/arrow-1.4.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/54/51/321e821856452f7386c4e9df866f196720b1ad0c5ea1623ea7399969ae3b/authlib-1.6.6-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/77/39/4d8414260c3d83f22029a39e51553c173611b378d62ca391e5ca68e65cfa/awkward-2.9.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ca/aa/ab2d6d68c3ee50f6dedbbc91a31cd38f9fede9258d54e7aca29bfca4ebc1/awkward_cpp-52-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/fc/d8/b8fcba9464f02b121f39de2db2bf57f0b216fe11d014513d666e8634380d/azure_core-1.38.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/24/b4/11f8a31d8b67cca3371e046db49baa7c0594d71eb40ac8121e2fc0888db0/bcrypt-5.0.0-cp39-abi3-manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/1a/39/47f9197bdd44df24d67ac8893641e16f386c984a0619ef2ee4c51fbbc019/beautifulsoup4-4.14.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/5e/0a/3966f239e1d9da93cb755dc0213835ce4e9ed93645192878d0a055ecdc31/boto3-1.42.42-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e6/51/aac7e419521d5519e13087a7198623655648c939822bd7f4bdc9ccbe07f9/botocore-1.42.42-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ef/79/c45f2d53efe6ada1110cf6f9fca095e4ff47a0454444aefdde6ac4789179/cachecontrol-0.14.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/28/df/2dd32cce20cbcf6f2ec456b58d44368161ad28320729f64e5e1d5d7bd0ae/cachetools-7.0.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e6/ad/3cc14f097111b4de0040c83a525973216457bbeeb63739ef1ed275c1c021/certifi-2026.1.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/67/ff/f6b948ca32e4f2a4576aa129d8bed61f2e0543bf9f5f2b7fc3758ed005c9/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/98/78/01c019cdb5d6498122777c1a43056ebb3ebfeef2076d9d026bfe15583b2b/click-8.3.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a7/06/3d6badcf13db419e25b07041d9c7b4a2c331d3f4e7134445ec5df57714cd/coloredlogs-15.0.1-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/19/0f/f6121b90b86b9093c066889274d26a1de3f29969d45c2ed1ecbe2033cb78/cramjam-2.11.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/2b/08/f83e2e0814248b844265802d081f2fac2f1cbe6cd258e72ba14ff006823a/cryptography-46.0.4-cp311-abi3-manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/db/2b/1239938a2629c29363e07724d7bd4c87a8b566947ecee2afb5f5ac34e1bb/cwl_upgrader-1.2.14-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/63/4b/ccab2a5ca9e0b6553810b85c06387e60fc9443cec3c987e3a062705bd225/cwl_utils-0.40-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/3b/56/99a7cf6ca8533695874cf804369221d03bf5e869a7e0b38acbf4dbe8deeb/cwlformat-2022.2.18-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/65/ee/a7aba2b112c5ae879d5cfb231c75189a7fd2a5e84b6af7e07dd71fb2bb35/cwltool-3.1.20260108082145-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/5a/36/17015b7bae2783f7bbde50a8bafdeb702802c080322204f1bfcae25b9e02/DB12-1.0.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/4e/8c/f3147f5c4b73e7550fe5f9352eaa956ae838d5c51eb58e7a25b9f3e2643b/decorator-5.2.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/84/d0/205d54408c08b13550c733c4b85429e7ead111c7f0014309637425520a9a/deprecated-1.3.1-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/d0/d0/9e71fdc3394ffc632f35946c572e60fcc2a5452ba0a23c52493f23d60672/dirac-9.1.6-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/9f/90/279f55fff9481f9e0424c3c97b24dc10004ec8d8f98ddf5afd07a7b79194/diraccfg-1.0.1-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/f8/b2/ad8e7e63fdf5add3ceb7a0805d700e9fd7cb7d5743f765a4994b4ec286d7/diraccommon-9.1.6-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ab/7e/5f02b757bb825e5cdc65f6f7a12c209963bec877d61497393bea8f41f9ce/diracx_api-0.0.8-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b0/28/87e78ff0d6041f40431d88b8aa3b645be7476a420d8dcbf7197f5b394c5c/diracx_cli-0.0.8-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/f2/61/0c78d9778bffd844863d3173a5fefb506d7131ceebecee523a9e27024aa1/diracx_client-0.0.8-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b2/c9/459da97eb93fad89738951972671d44be197610242b8da88a0384791ea7e/diracx_core-0.0.8-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ba/5a/18ad964b0086c6e62e2e7500f7edc89e3faa45033c71c1893d34eed2b2de/dnspython-2.8.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/dc/80/12235e5b75bb2c586733280854f131b86051e0bbdfb55349ff70d0f72cf9/dogpile_cache-1.5.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/58/19/0380af745f151a1648657bbcef0fb49ac28bf09083d94498163ffd9b32dc/dominate-2.9.1-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/de/15/545e2b6cf2e3be84bc1ed85613edd75b8aea69807a71c26f4ca6a9258e82/email_validator-2.3.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/37/f9/f8497ef8b873a8bb2a750ee2a6c5f0fc22258e1acb6245fd237042a6c279/fabric-3.2.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a7/b2/fabede9fafd976b991e9f1b9c8c873ed86f202889b864756f240ce6dd855/frozenlist-1.8.0-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/d5/1f/5f4a3cd9e4440e9d9bc78ad0a91a1c8d46b4d429d5239ebe6793c9fe5c41/fsspec-2026.3.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/73/90/a2c51050d9254bd9134e6368b3f94f92f0eb2c34ed0ca19ec449ce2fc288/fsspec_xrootd-0.5.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/5f/e8/2e6301567e6debaad6abae0e217428471651ce877537b7095b6a8e7d8cd2/fts3-3.14.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a0/61/5c78b91c3143ed5c14207f463aecfc8f9dbb5092fb2869baf37c273b2705/gitdb-4.0.12-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b0/57/dea471da24ceac6de8c3dc5d37e4ddde57a5c340d6bac90010898734de34/gitlint_core-0.19.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/6a/09/e21df6aef1e1ffc0c816f0522ddc3f6dcded766c3261813131c78a704470/gitpython-3.1.46-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/80/38/9d42d60dffb04b45f03dbab9430898352dba277758640751dc5cc316c521/greenlet-3.3.1-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/f0/0f/310fb31e39e2d734ccaa2c0fb981ee41f7bd5056ce9bc29b2248bd569169/humanfriendly-10.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/d0/23/49cf8ea1d129637941f06fb78f5f66077bf362762c5f6c01712c4cd0e87f/hyperscan-0.8.2-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/fa/5e/f8e9a1d23b9c20a551a8a02ea3637b4642e22c2626e3a13a9a29cdea99eb/importlib_metadata-8.7.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a4/ed/1f1afb2e9e7f38a545d628f864d562a5ae64fe6f7a10e28ffb9b185b4e89/importlib_resources-6.5.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/32/4b/b99e37f88336009971405cbb7630610322ed6fbfa31e1d7ab3fbf3049a2d/invoke-2.2.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/15/aa/0aca39a37d3c7eb941ba736ede56d689e7be91cab5d9ca846bde3999eba6/isodate-0.7.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/14/2f/967ba146e6d58cf6a652da73885f52fc68001525b4197effc174321d70b4/jmespath-1.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a1/01/9674cc6d478406ae61d910cb16ca8b5699a8a9e6a2019987ebe5a5957d1d/joserfc-1.6.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ba/24/c65fe1aef4e0681cb17ca136eb0f3e20a47d3941a306bc9d636938029ca5/lb_telemetry-0.5.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/87/a4/afc9dddc6b14fb3d52a900cd9b4c77770128edc4b07e576034bbd0ffd290/LbCondaWrappers-0.5.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/d7/4c/f3b97c7d6008b3a895bbadb2deb44ad3446ae5fe204c72cd540dc222e57d/lbenv-2.4.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/6d/10/b37ac718c5903758fa9058a5182026a4f3b65443196b82c7840389ea0dbd/lbplatformutils-4.6.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/02/64/c86924898062e8217ed914a29458cfde9e4a9b80e4d4cbcca141983ba339/lbprodrun-1.12.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/29/ce/ed422816fb30ffa3bc11597b30d5deca06b4a1388707a04215da73c65b53/levenshtein-0.27.3-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl - - pypi: git+https://gitlab.cern.ch/jlisalab/LHCbDIRAC.git?rev=modules-to-cwl-migration#bc5f8f1804107bc8807edcc98a97c346ef61c0e8 - - pypi: https://files.pythonhosted.org/packages/7f/37/8ea3555769b6048b5e4ec162cc90fd32e761c0e381ffb3baf888cb0d8a71/lhcbdiracx_api-0.0.8-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/68/15/bfb0c717b8f23c16907f3e73e8f56010ccd72e9900a108209665b0d9ed4b/lhcbdiracx_cli-0.0.8-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/2d/88/67602dfa2d7ab5d0518af82db34ab4d70dc2c3029b3ca788299a3be4a96d/lhcbdiracx_client-0.0.8-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/34/8f/6105afdd8f4e1f3b198d09e4b2622622923d9fa9e077aed852c0bb035a3a/lhcbdiracx_core-0.0.8-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b3/68/aa714515d65090fcbcc9a1f3debd5a644b14aad11e59238f42f00bd4b298/logzero-1.7.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/29/9c/47293c58cc91769130fbf85531280e8cc7868f7fbb6d92f4670071b9cb3e/lxml-6.0.2-cp314-cp314-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/94/54/e7d793b573f298e1c9013b8c4dade17d481164aa517d1d7148619c2cedbf/markdown_it_py-4.0.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/7a/f0/8282d9641415e9e33df173516226b404d367a0fc55e1a60424a152913abc/mistune-3.1.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/2f/40/dc34d1a8d5f1e51fc64640b62b191684da52ca469da9cd74e84936ffa4a6/msgpack-1.1.2-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/fe/3b/8ec5074bcfc450fe84273713b4b0a0dd47c0249358f5d82eb8104ffe2520/multidict-6.7.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/9e/c9/b2622292ea83fbb4ec318f5b9ab867d0a28ab43c5717bb85b0a5f6b3b0a4/networkx-3.6.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/76/3e/c0b690253f0b82d86e99949af13533363acfb5432ecb5d53dd5b3bce9c34/orjson-3.11.9-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/15/88/3cdd54fa279341afa10acf8d2b503556b1375245dccc9315659f795dd2e9/pandas-3.0.2-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/a9/90/a744336f5af32c433bd09af7854599682a383b37cfd78f7de263de6ad6cb/paramiko-4.0.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/9e/c3/059298687310d527a58bb01f3b1965787ee3b40dce76752eda8b44e9a2c5/pexpect-4.9.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/84/03/0d3ce49e2505ae70cf43bc5bb3033955d2fc9f932163e84dc0779cc47f48/prompt_toolkit-3.0.52-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b2/f2/889ad4b2408f72fe1a4f6a19491177b30ea7bf1a0fd5f17050ca08cfc882/propcache-0.4.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/8e/fb/2c4c618185be2bda327f9dacd16b3122cc938809f19df7be840595d0e584/prov-1.5.1-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/22/a6/858897256d0deac81a172289110f31629fc4cee19b6f01283303e18c8db3/ptyprocess-0.7.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/44/b5/a96872e5184f354da9c84ae119971a0a4c221fe9b27a4d94bd43f2596727/pyasn1-0.6.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/47/8d/d529b5d697919ba8c11ad626e835d4039be708a35b0d22de83a269a6682c/pyasn1_modules-0.4.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/5a/87/b70ad306ebb6f9b585f114d0ac2137d792b48be34d732d60e597c2f8465a/pydantic-2.12.5-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/4c/d2/ef2074dc020dd6e109611a8be4449b98cd25e1b9b8a303c2f0fca2f2bcf7/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/c1/60/5d4751ba3f4a40a6891f24eec885f51afd78d208498268c734e256fb13c4/pydantic_settings-2.12.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/7e/32/a7125fb28c4261a627f999d5fb4afff25b523800faed2c30979949d6facd/pydot-4.0.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/6f/01/c26ce75ba460d5cd503da9e13b21a33804d38c2165dec7b716d06b13010c/pyjwt-2.11.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/3e/d0/f301f83ac8dbe53442c5a43f6a39016f94f754d7a9815a875b65e218a307/pynacl-1.6.2-cp38-abi3-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/10/bd/c038d7cc38edc1aa5bf91ab8068b63d4308c66c4c8bb3cbba7dfbc049f9c/pyparsing-3.3.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/14/1b/a298b06749107c305e1fe0f814c6c74aea7b2f1e10989cb30f544a1b3253/python_dotenv-1.2.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/38/ee/a61bb562bdf6f0bc6c51cdcf80ab5503cbb4b2f5053fa4b054cc0a56e48a/python_gitlab-8.2.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/81/c4/34e93fe5f5429d7570ec1fa436f1986fb1f00c3e0f43a589fe2bbcd22c3f/pytz-2025.2-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c8/85/9535df0b78ba51f478c9ce7eb6d1f85535cc31fe356773b48fd9d3e563ca/rapidfuzz-3.14.5-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/b9/20/35d2baebacf357b562bd081936b66cd845775442973cb033a377fd639a84/rdflib-7.5.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/1e/db/4254e3eabe8020b458f1a747140d32277ec7a271daf1d235b70dc0b4e6e3/requests-2.32.5-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/3f/51/d4db610ef29373b879047326cbf6fa98b6c1969d6f6dc423279de2b1be2c/requests_toolbelt-1.0.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ef/45/615f5babd880b4bd7d405cc0dc348234c5ffb6ed1ea33e152ede08b2072d/rich-14.3.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/04/80/97b6f357ac458d9ad9872cc3183ca09ef7439ac89e030ea43053ba1294b6/rich_argparse-1.7.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/af/fe/b6045c782f1fd1ae317d2a6ca1884857ce5c20f59befe6ab25a8603c43a7/ruamel_yaml-0.18.17-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a1/5c/8b56b08db91e569d0a4fbfa3e492ed2026081bdd7e892f63ba1c88a2f548/ruamel_yaml_clib-0.2.15-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/5c/48/ccd6c49477674389d55b5b5520e47d1290f4c29686c36f5674f4a7aced00/rucio_clients-39.2.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/fc/51/727abb13f44c1fcf6d145979e1535a35794db0f6e450a0cb46aa24732fe2/s3transfer-0.16.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/89/d4/24a137517140fc8cc07f7423695b9296c993d6b6cbf2a7867d8f859de77f/schema_salad-8.9.20251102115403-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/70/98/d82f14ac7ffedbd38dfa2383f142b26d18d23ca6cf35a40f4af60df666bd/sh-2.2.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e0/f9/0595336914c5619e5f28a1fb793285925a8cd4b432c9da0a987836c7f822/shellingham-1.5.4-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/59/25/68f81c50aeb3f30e01c20da0f56d14c1a779b57d9308c50e19c63dc8413f/signurlarity-0.2.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/04/be/d09147ad1ec7934636ad912901c5fd7667e1c858e19d355237db0d0cd5e4/smmap-5.0.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/46/2c/1462b1d0a634697ae9e55b3cecdcb64788e8b7d63f54d923fcd0bb140aed/soupsieve-2.8.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/f9/38/8b6fc7a8153cb49eb3a9a13acfa9eeb6cc476e37888781e593e6f02ac05e/spython-0.3.14-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/05/45/1256fb597bb83b58a01ddb600c59fe6fdf0e5afe333f0456ed75c0f8d7bd/sqlalchemy-2.0.46-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/f4/40/8561ce06dc46fd17242c7724ab25b257a2ac1b35f4ebf551b40ce6105cfa/stevedore-5.6.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/40/44/4a5f08c96eb108af5cb50b41f76142f0afa346dfa99d5296fe7202a11854/tabulate-0.9.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a0/1d/d9257dd49ff2ca23ea5f132edf1281a0c4f9de8a762b9ae399b670a59235/typer-0.21.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/dc/9b/47798a6c91d8bdb567fe2698fe81e0c6b7cb7ef4d13da4114b41d239f65d/typing_inspection-0.4.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c7/b0/003792df09decd6849a5e39c28b513c06e84436a54440380862b5aeff25d/tzdata-2025.3-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c4/55/85e2732345dd8b66437cddedac4ee7ef2d9c25bf8792830b095f2ee658f3/uproot-5.7.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/39/08/aaaad47bc4e9dc8c725e68f9d04865dbcb2052843ff09c97b08904852d84/urllib3-2.6.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/3c/c1/d73f12f8cdb1891334a2ccf7389eed244d3941e74d80dd220badb937f3fb/wcwidth-0.5.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/db/56/073989deb4b5d7d6e7ea424476a4ae4bda02140f2dbeaafb14ba4864dd60/wrapt-2.1.1-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/1c/1c/ab905d19a1349e847e37e02933316d17adfd1dd70b64d366885ab0bd959d/xattr-1.3.0-cp314-cp314-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/ca/6d/b1a49f9712a910acdcb8dc5765e57d60c2be9fe9b001a21b6a98a1d85adb/xenv-0.0.6-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/38/34/98a2f52245f4d47be93b580dae5f9861ef58977d73a79eb47c58f1ad1f3a/xmltodict-1.0.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ed/ba/603ce3961e339413543d8cd44f21f2c80e2a7c5cfe692a7b1f2cccf58f3c/xxhash-3.6.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/f5/e7/d8c5a7752fef68205296201f8ec2bf718f5c805a7a7e9880576c67600658/yarl-1.22.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/2e/54/647ade08bf0db230bfea292f893923872fd20be6ac6f53b2b936ba839d75/zipp-3.23.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/31/dc/cc50210e11e465c975462439a492516a73300ab8caa8f5e0902544fd748b/zstandard-0.25.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - - pypi: ./ - osx-64: - - conda: https://conda.anaconda.org/conda-forge/osx-64/_openmp_mutex-4.5-7_kmp_llvm.conda - conda: https://conda.anaconda.org/conda-forge/noarch/attrs-25.4.0-pyhcf101f3_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/backports.asyncio.runner-1.2.0-pyh5ded981_2.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/bzip2-1.0.8-h500dc9f_8.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/c-ares-1.34.6-hb5e19a0_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.1.4-hbd8a1cb_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/cffi-2.0.0-py314h8ca4d5a_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/cfgv-3.5.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/cyrus-sasl-2.1.28-h610c526_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/davix-0.8.10-h35d429b_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/dcap-2.47.14-hf4fbb18_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/distlib-0.4.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/filelock-3.20.3-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/gct-6.2.1705709074-h8d8e280_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/gfal2-2.23.5-h6ef8084_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/gsoap-2.8.123-h21ae599_0.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/osx-64/gtest-1.17.0-h9275861_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/icu-78.2-h14c5de8_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/identify-2.6.16-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/json-c-0.18-hc62ec3d_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-4.26.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-specifications-2025.9.1-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/krb5-1.21.3-h37d8d59_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libblas-3.11.0-5_he492b99_openblas.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libboost-1.88.0-h5950822_7.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libboost-python-1.88.0-py314hee2ba4e_7.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libcblas-3.11.0-5_h9b27e0a_openblas.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libcurl-8.18.0-h9348e2b_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libcxx-21.1.8-h4fb565c_2.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libedit-3.1.20250104-pl5321ha958ccf_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libev-4.33-h10d778d_2.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libexpat-2.7.3-heffb93a_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libffi-3.5.2-hd1f9c09_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libgcc-15.2.0-h08519bb_17.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libgfortran-15.2.0-h7e5c614_17.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libgfortran5-15.2.0-hd16e46c_17.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libglib-2.86.3-hf241ffe_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libiconv-1.18-h57a12c2_2.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libintl-0.25.1-h3184127_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/liblapack-3.11.0-5_h859234e_openblas.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libltdl-2.4.3a-h240833e_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/liblzma-5.8.2-h11316ed_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libmpdec-4.0.0-hf3981d6_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libnghttp2-1.67.0-h3338091_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libntlm-1.8-h6e16a3a_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libopenblas-0.3.30-openmp_h6006d49_4.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libsqlite-3.51.2-hb99441e_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libssh2-1.11.1-hed3591d_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libtool-2.5.4-h240833e_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libuuid-2.41.3-h3fe7000_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libxcrypt-4.4.36-h10d778d_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libxml2-16-2.15.1-he456531_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libxml2-2.15.1-h24ca049_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libxml2-devel-2.15.1-h24ca049_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libzlib-1.3.1-hd23fc13_2.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/llvm-openmp-21.1.8-h472b3d1_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/m2crypto-0.45.1-py314h90001a5_2.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/mypy-1.19.1-py314h6482030_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mypy_extensions-1.1.0-pyha770c72_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/ncurses-6.5-h0622a9a_3.conda - conda: https://conda.anaconda.org/conda-forge/noarch/nodeenv-1.10.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/numpy-2.4.2-py314hfc4c462_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/openldap-2.6.10-hd8a590d_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/openssl-3.6.1-hb6871ef_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pathspec-1.0.4-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/pcre2-10.47-h13923f0_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/perl-5.32.1-7_h10d778d_perl5.conda - conda: https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.5.1-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pre-commit-4.5.1-pyha770c72_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/psutil-7.2.2-py314hd330473_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/pugixml-1.15-h46091d4_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-asyncio-1.3.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-mock-3.15.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/python-3.14.3-h4f44bb5_100_cp314.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/python-gfal2-1.13.1-py314hd08135f_2.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/python-librt-0.7.8-py314hd330473_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/pyyaml-6.0.3-py314h10d0514_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/readline-8.3-h68b038d_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/referencing-0.37.0-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/rpds-py-0.30.0-py314ha7b6dee_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/ruff-0.15.0-h5930b28_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/scitokens-cpp-1.3.0-hcb75e18_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-80.10.2-pyh332efcf_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/srm-ifce-1.24.6-h73c9bdb_2.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/tk-8.6.13-h7142dee_3.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/ukkonen-1.1.0-py314h473ef84_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/virtualenv-20.36.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/xrootd-5.9.1-py314hb36820e_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/yaml-0.2.5-h4132b18_3.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/zlib-1.3.1-hd23fc13_2.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/zstd-1.5.7-h3eecb57_6.conda - - pypi: https://files.pythonhosted.org/packages/cd/22/4d16dca3bd1d6475a53063eb72150269cea1a0a201b55288b3402f61f119/aiobotocore-3.1.2-py3-none-any.whl + - pypi: . + - pypi: git+https://gitlab.cern.ch/jlisalab/LHCbDIRAC.git?rev=modules-to-cwl-migration#bc5f8f1804107bc8807edcc98a97c346ef61c0e8 + - pypi: https://files.pythonhosted.org/packages/02/64/c86924898062e8217ed914a29458cfde9e4a9b80e4d4cbcca141983ba339/lbprodrun-1.12.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/04/80/97b6f357ac458d9ad9872cc3183ca09ef7439ac89e030ea43053ba1294b6/rich_argparse-1.7.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/04/be/d09147ad1ec7934636ad912901c5fd7667e1c858e19d355237db0d0cd5e4/smmap-5.0.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/05/45/1256fb597bb83b58a01ddb600c59fe6fdf0e5afe333f0456ed75c0f8d7bd/sqlalchemy-2.0.46-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/0f/15/5bf3b99495fb160b63f95972b81750f18f7f4e02ad051373b669d17d44f2/aiohappyeyeballs-2.6.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/f7/49/459327f0d5bcd8c6c9ca69e60fdeebc3622861e696490d8674a6d0cb90a6/aiohttp-3.13.3-cp314-cp314-macosx_10_13_x86_64.whl - pypi: https://files.pythonhosted.org/packages/10/a1/510b0a7fadc6f43a6ce50152e69dbd86415240835868bb0bd9b5b88b1e06/aioitertools-0.13.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/38/0e/27be9fdef66e72d64c0cdc3cc2823101b80585f8119b5c112c2e8f5f7dab/anyio-4.12.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/74/f5/9373290775639cb67a2fce7f629a1c240dce9f12fe927bc32b2736e16dfc/argcomplete-3.6.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ed/c9/d7977eaacb9df673210491da99e6a247e93df98c715fc43fd136ce1d3d33/arrow-1.4.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/54/51/321e821856452f7386c4e9df866f196720b1ad0c5ea1623ea7399969ae3b/authlib-1.6.6-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/77/39/4d8414260c3d83f22029a39e51553c173611b378d62ca391e5ca68e65cfa/awkward-2.9.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/9a/02/0e550c9606ffae81603a9d240369a93cdf1e4bc48e2e314d367825a1c02d/awkward_cpp-52-cp314-cp314-macosx_10_15_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/fc/d8/b8fcba9464f02b121f39de2db2bf57f0b216fe11d014513d666e8634380d/azure_core-1.38.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/5d/ba/2af136406e1c3839aea9ecadc2f6be2bcd1eff255bd451dd39bcf302c47a/bcrypt-5.0.0-cp39-abi3-macosx_10_12_universal2.whl + - pypi: https://files.pythonhosted.org/packages/10/bd/c038d7cc38edc1aa5bf91ab8068b63d4308c66c4c8bb3cbba7dfbc049f9c/pyparsing-3.3.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/14/1b/a298b06749107c305e1fe0f814c6c74aea7b2f1e10989cb30f544a1b3253/python_dotenv-1.2.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/14/2f/967ba146e6d58cf6a652da73885f52fc68001525b4197effc174321d70b4/jmespath-1.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/15/88/3cdd54fa279341afa10acf8d2b503556b1375245dccc9315659f795dd2e9/pandas-3.0.2-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/15/aa/0aca39a37d3c7eb941ba736ede56d689e7be91cab5d9ca846bde3999eba6/isodate-0.7.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/19/0f/f6121b90b86b9093c066889274d26a1de3f29969d45c2ed1ecbe2033cb78/cramjam-2.11.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - pypi: https://files.pythonhosted.org/packages/1a/39/47f9197bdd44df24d67ac8893641e16f386c984a0619ef2ee4c51fbbc019/beautifulsoup4-4.14.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/5e/0a/3966f239e1d9da93cb755dc0213835ce4e9ed93645192878d0a055ecdc31/boto3-1.42.42-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e6/51/aac7e419521d5519e13087a7198623655648c939822bd7f4bdc9ccbe07f9/botocore-1.42.42-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ef/79/c45f2d53efe6ada1110cf6f9fca095e4ff47a0454444aefdde6ac4789179/cachecontrol-0.14.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1c/1c/ab905d19a1349e847e37e02933316d17adfd1dd70b64d366885ab0bd959d/xattr-1.3.0-cp314-cp314-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/1e/db/4254e3eabe8020b458f1a747140d32277ec7a271daf1d235b70dc0b4e6e3/requests-2.32.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/22/a6/858897256d0deac81a172289110f31629fc4cee19b6f01283303e18c8db3/ptyprocess-0.7.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/24/b4/11f8a31d8b67cca3371e046db49baa7c0594d71eb40ac8121e2fc0888db0/bcrypt-5.0.0-cp39-abi3-manylinux_2_28_x86_64.whl - pypi: https://files.pythonhosted.org/packages/28/df/2dd32cce20cbcf6f2ec456b58d44368161ad28320729f64e5e1d5d7bd0ae/cachetools-7.0.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e6/ad/3cc14f097111b4de0040c83a525973216457bbeeb63739ef1ed275c1c021/certifi-2026.1.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/2a/35/7051599bd493e62411d6ede36fd5af83a38f37c4767b92884df7301db25d/charset_normalizer-3.4.4-cp314-cp314-macosx_10_13_universal2.whl - - pypi: https://files.pythonhosted.org/packages/98/78/01c019cdb5d6498122777c1a43056ebb3ebfeef2076d9d026bfe15583b2b/click-8.3.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a7/06/3d6badcf13db419e25b07041d9c7b4a2c331d3f4e7134445ec5df57714cd/coloredlogs-15.0.1-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/de/07/a1051cdbbe6d723df16d756b97f09da7c1adb69e29695c58f0392bc12515/cramjam-2.11.0-cp314-cp314-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl - - pypi: https://files.pythonhosted.org/packages/8d/99/157aae7949a5f30d51fcb1a9851e8ebd5c74bf99b5285d8bb4b8b9ee641e/cryptography-46.0.4-cp311-abi3-macosx_10_9_universal2.whl - - pypi: https://files.pythonhosted.org/packages/db/2b/1239938a2629c29363e07724d7bd4c87a8b566947ecee2afb5f5ac34e1bb/cwl_upgrader-1.2.14-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/63/4b/ccab2a5ca9e0b6553810b85c06387e60fc9443cec3c987e3a062705bd225/cwl_utils-0.40-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/29/9c/47293c58cc91769130fbf85531280e8cc7868f7fbb6d92f4670071b9cb3e/lxml-6.0.2-cp314-cp314-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/29/ce/ed422816fb30ffa3bc11597b30d5deca06b4a1388707a04215da73c65b53/levenshtein-0.27.3-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2b/08/f83e2e0814248b844265802d081f2fac2f1cbe6cd258e72ba14ff006823a/cryptography-46.0.4-cp311-abi3-manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/2d/88/67602dfa2d7ab5d0518af82db34ab4d70dc2c3029b3ca788299a3be4a96d/lhcbdiracx_client-0.0.8-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2e/54/647ade08bf0db230bfea292f893923872fd20be6ac6f53b2b936ba839d75/zipp-3.23.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2f/40/dc34d1a8d5f1e51fc64640b62b191684da52ca469da9cd74e84936ffa4a6/msgpack-1.1.2-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/31/dc/cc50210e11e465c975462439a492516a73300ab8caa8f5e0902544fd748b/zstandard-0.25.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/32/4b/b99e37f88336009971405cbb7630610322ed6fbfa31e1d7ab3fbf3049a2d/invoke-2.2.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/34/8f/6105afdd8f4e1f3b198d09e4b2622622923d9fa9e077aed852c0bb035a3a/lhcbdiracx_core-0.0.8-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/37/f9/f8497ef8b873a8bb2a750ee2a6c5f0fc22258e1acb6245fd237042a6c279/fabric-3.2.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/38/0e/27be9fdef66e72d64c0cdc3cc2823101b80585f8119b5c112c2e8f5f7dab/anyio-4.12.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/38/34/98a2f52245f4d47be93b580dae5f9861ef58977d73a79eb47c58f1ad1f3a/xmltodict-1.0.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/38/ee/a61bb562bdf6f0bc6c51cdcf80ab5503cbb4b2f5053fa4b054cc0a56e48a/python_gitlab-8.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/39/08/aaaad47bc4e9dc8c725e68f9d04865dbcb2052843ff09c97b08904852d84/urllib3-2.6.3-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/3b/56/99a7cf6ca8533695874cf804369221d03bf5e869a7e0b38acbf4dbe8deeb/cwlformat-2022.2.18-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/65/ee/a7aba2b112c5ae879d5cfb231c75189a7fd2a5e84b6af7e07dd71fb2bb35/cwltool-3.1.20260108082145-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/5a/36/17015b7bae2783f7bbde50a8bafdeb702802c080322204f1bfcae25b9e02/DB12-1.0.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3c/c1/d73f12f8cdb1891334a2ccf7389eed244d3941e74d80dd220badb937f3fb/wcwidth-0.5.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3e/d0/f301f83ac8dbe53442c5a43f6a39016f94f754d7a9815a875b65e218a307/pynacl-1.6.2-cp38-abi3-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/3f/51/d4db610ef29373b879047326cbf6fa98b6c1969d6f6dc423279de2b1be2c/requests_toolbelt-1.0.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/40/44/4a5f08c96eb108af5cb50b41f76142f0afa346dfa99d5296fe7202a11854/tabulate-0.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/44/b5/a96872e5184f354da9c84ae119971a0a4c221fe9b27a4d94bd43f2596727/pyasn1-0.6.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/46/2c/1462b1d0a634697ae9e55b3cecdcb64788e8b7d63f54d923fcd0bb140aed/soupsieve-2.8.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/47/8d/d529b5d697919ba8c11ad626e835d4039be708a35b0d22de83a269a6682c/pyasn1_modules-0.4.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/4c/d2/ef2074dc020dd6e109611a8be4449b98cd25e1b9b8a303c2f0fca2f2bcf7/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - pypi: https://files.pythonhosted.org/packages/4e/8c/f3147f5c4b73e7550fe5f9352eaa956ae838d5c51eb58e7a25b9f3e2643b/decorator-5.2.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/84/d0/205d54408c08b13550c733c4b85429e7ead111c7f0014309637425520a9a/deprecated-1.3.1-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/d0/d0/9e71fdc3394ffc632f35946c572e60fcc2a5452ba0a23c52493f23d60672/dirac-9.1.6-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/9f/90/279f55fff9481f9e0424c3c97b24dc10004ec8d8f98ddf5afd07a7b79194/diraccfg-1.0.1-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/f8/b2/ad8e7e63fdf5add3ceb7a0805d700e9fd7cb7d5743f765a4994b4ec286d7/diraccommon-9.1.6-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ab/7e/5f02b757bb825e5cdc65f6f7a12c209963bec877d61497393bea8f41f9ce/diracx_api-0.0.8-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b0/28/87e78ff0d6041f40431d88b8aa3b645be7476a420d8dcbf7197f5b394c5c/diracx_cli-0.0.8-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/f2/61/0c78d9778bffd844863d3173a5fefb506d7131ceebecee523a9e27024aa1/diracx_client-0.0.8-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b2/c9/459da97eb93fad89738951972671d44be197610242b8da88a0384791ea7e/diracx_core-0.0.8-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ba/5a/18ad964b0086c6e62e2e7500f7edc89e3faa45033c71c1893d34eed2b2de/dnspython-2.8.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/dc/80/12235e5b75bb2c586733280854f131b86051e0bbdfb55349ff70d0f72cf9/dogpile_cache-1.5.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/54/51/321e821856452f7386c4e9df866f196720b1ad0c5ea1623ea7399969ae3b/authlib-1.6.6-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/58/19/0380af745f151a1648657bbcef0fb49ac28bf09083d94498163ffd9b32dc/dominate-2.9.1-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/de/15/545e2b6cf2e3be84bc1ed85613edd75b8aea69807a71c26f4ca6a9258e82/email_validator-2.3.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/37/f9/f8497ef8b873a8bb2a750ee2a6c5f0fc22258e1acb6245fd237042a6c279/fabric-3.2.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/8e/e8/a1185e236ec66c20afd72399522f142c3724c785789255202d27ae992818/frozenlist-1.8.0-cp314-cp314-macosx_10_13_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/d5/1f/5f4a3cd9e4440e9d9bc78ad0a91a1c8d46b4d429d5239ebe6793c9fe5c41/fsspec-2026.3.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/73/90/a2c51050d9254bd9134e6368b3f94f92f0eb2c34ed0ca19ec449ce2fc288/fsspec_xrootd-0.5.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/59/25/68f81c50aeb3f30e01c20da0f56d14c1a779b57d9308c50e19c63dc8413f/signurlarity-0.2.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5a/36/17015b7bae2783f7bbde50a8bafdeb702802c080322204f1bfcae25b9e02/DB12-1.0.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5a/87/b70ad306ebb6f9b585f114d0ac2137d792b48be34d732d60e597c2f8465a/pydantic-2.12.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5c/48/ccd6c49477674389d55b5b5520e47d1290f4c29686c36f5674f4a7aced00/rucio_clients-39.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5e/0a/3966f239e1d9da93cb755dc0213835ce4e9ed93645192878d0a055ecdc31/boto3-1.42.42-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/5f/e8/2e6301567e6debaad6abae0e217428471651ce877537b7095b6a8e7d8cd2/fts3-3.14.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a0/61/5c78b91c3143ed5c14207f463aecfc8f9dbb5092fb2869baf37c273b2705/gitdb-4.0.12-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b0/57/dea471da24ceac6de8c3dc5d37e4ddde57a5c340d6bac90010898734de34/gitlint_core-0.19.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/63/4b/ccab2a5ca9e0b6553810b85c06387e60fc9443cec3c987e3a062705bd225/cwl_utils-0.40-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/65/ee/a7aba2b112c5ae879d5cfb231c75189a7fd2a5e84b6af7e07dd71fb2bb35/cwltool-3.1.20260108082145-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/67/ff/f6b948ca32e4f2a4576aa129d8bed61f2e0543bf9f5f2b7fc3758ed005c9/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/68/15/bfb0c717b8f23c16907f3e73e8f56010ccd72e9900a108209665b0d9ed4b/lhcbdiracx_cli-0.0.8-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/6a/09/e21df6aef1e1ffc0c816f0522ddc3f6dcded766c3261813131c78a704470/gitpython-3.1.46-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ae/fb/011c7c717213182caf78084a9bea51c8590b0afda98001f69d9f853a495b/greenlet-3.3.1-cp314-cp314-macosx_11_0_universal2.whl - - pypi: https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/f0/0f/310fb31e39e2d734ccaa2c0fb981ee41f7bd5056ce9bc29b2248bd569169/humanfriendly-10.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/22/ed/9c45c468fd6c31df3fe0622394b1853c00b86545d1e297f3fb9fba1232ce/hyperscan-0.8.2-cp314-cp314-macosx_10_15_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/fa/5e/f8e9a1d23b9c20a551a8a02ea3637b4642e22c2626e3a13a9a29cdea99eb/importlib_metadata-8.7.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a4/ed/1f1afb2e9e7f38a545d628f864d562a5ae64fe6f7a10e28ffb9b185b4e89/importlib_resources-6.5.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/32/4b/b99e37f88336009971405cbb7630610322ed6fbfa31e1d7ab3fbf3049a2d/invoke-2.2.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/15/aa/0aca39a37d3c7eb941ba736ede56d689e7be91cab5d9ca846bde3999eba6/isodate-0.7.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/14/2f/967ba146e6d58cf6a652da73885f52fc68001525b4197effc174321d70b4/jmespath-1.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a1/01/9674cc6d478406ae61d910cb16ca8b5699a8a9e6a2019987ebe5a5957d1d/joserfc-1.6.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ba/24/c65fe1aef4e0681cb17ca136eb0f3e20a47d3941a306bc9d636938029ca5/lb_telemetry-0.5.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/87/a4/afc9dddc6b14fb3d52a900cd9b4c77770128edc4b07e576034bbd0ffd290/LbCondaWrappers-0.5.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/d7/4c/f3b97c7d6008b3a895bbadb2deb44ad3446ae5fe204c72cd540dc222e57d/lbenv-2.4.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/6d/10/b37ac718c5903758fa9058a5182026a4f3b65443196b82c7840389ea0dbd/lbplatformutils-4.6.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/02/64/c86924898062e8217ed914a29458cfde9e4a9b80e4d4cbcca141983ba339/lbprodrun-1.12.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/f3/e1/2f705da403f865a5fa3449b155738dc9c53021698fd6926253a9af03180b/levenshtein-0.27.3-cp314-cp314-macosx_10_15_x86_64.whl - - pypi: git+https://gitlab.cern.ch/jlisalab/LHCbDIRAC.git?rev=modules-to-cwl-migration#bc5f8f1804107bc8807edcc98a97c346ef61c0e8 + - pypi: https://files.pythonhosted.org/packages/6f/01/c26ce75ba460d5cd503da9e13b21a33804d38c2165dec7b716d06b13010c/pyjwt-2.11.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/70/98/d82f14ac7ffedbd38dfa2383f142b26d18d23ca6cf35a40f4af60df666bd/sh-2.2.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/73/90/a2c51050d9254bd9134e6368b3f94f92f0eb2c34ed0ca19ec449ce2fc288/fsspec_xrootd-0.5.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/74/f5/9373290775639cb67a2fce7f629a1c240dce9f12fe927bc32b2736e16dfc/argcomplete-3.6.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/76/3e/c0b690253f0b82d86e99949af13533363acfb5432ecb5d53dd5b3bce9c34/orjson-3.11.9-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/77/39/4d8414260c3d83f22029a39e51553c173611b378d62ca391e5ca68e65cfa/awkward-2.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/7a/f0/8282d9641415e9e33df173516226b404d367a0fc55e1a60424a152913abc/mistune-3.1.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/7e/32/a7125fb28c4261a627f999d5fb4afff25b523800faed2c30979949d6facd/pydot-4.0.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/7f/37/8ea3555769b6048b5e4ec162cc90fd32e761c0e381ffb3baf888cb0d8a71/lhcbdiracx_api-0.0.8-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/68/15/bfb0c717b8f23c16907f3e73e8f56010ccd72e9900a108209665b0d9ed4b/lhcbdiracx_cli-0.0.8-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/2d/88/67602dfa2d7ab5d0518af82db34ab4d70dc2c3029b3ca788299a3be4a96d/lhcbdiracx_client-0.0.8-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/34/8f/6105afdd8f4e1f3b198d09e4b2622622923d9fa9e077aed852c0bb035a3a/lhcbdiracx_core-0.0.8-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b3/68/aa714515d65090fcbcc9a1f3debd5a644b14aad11e59238f42f00bd4b298/logzero-1.7.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c8/e8/c128e37589463668794d503afaeb003987373c5f94d667124ffd8078bbd9/lxml-6.0.2-cp314-cp314-macosx_10_13_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/80/38/9d42d60dffb04b45f03dbab9430898352dba277758640751dc5cc316c521/greenlet-3.3.1-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/81/c4/34e93fe5f5429d7570ec1fa436f1986fb1f00c3e0f43a589fe2bbcd22c3f/pytz-2025.2-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/84/03/0d3ce49e2505ae70cf43bc5bb3033955d2fc9f932163e84dc0779cc47f48/prompt_toolkit-3.0.52-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/84/d0/205d54408c08b13550c733c4b85429e7ead111c7f0014309637425520a9a/deprecated-1.3.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/87/a4/afc9dddc6b14fb3d52a900cd9b4c77770128edc4b07e576034bbd0ffd290/LbCondaWrappers-0.5.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/89/d4/24a137517140fc8cc07f7423695b9296c993d6b6cbf2a7867d8f859de77f/schema_salad-8.9.20251102115403-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/8e/fb/2c4c618185be2bda327f9dacd16b3122cc938809f19df7be840595d0e584/prov-1.5.1-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/94/54/e7d793b573f298e1c9013b8c4dade17d481164aa517d1d7148619c2cedbf/markdown_it_py-4.0.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/7a/f0/8282d9641415e9e33df173516226b404d367a0fc55e1a60424a152913abc/mistune-3.1.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/22/71/201105712d0a2ff07b7873ed3c220292fb2ea5120603c00c4b634bcdafb3/msgpack-1.1.2-cp314-cp314-macosx_10_13_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/d5/22/492f2246bb5b534abd44804292e81eeaf835388901f0c574bac4eeec73c5/multidict-6.7.1-cp314-cp314-macosx_10_15_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/98/78/01c019cdb5d6498122777c1a43056ebb3ebfeef2076d9d026bfe15583b2b/click-8.3.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9e/c3/059298687310d527a58bb01f3b1965787ee3b40dce76752eda8b44e9a2c5/pexpect-4.9.0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/9e/c9/b2622292ea83fbb4ec318f5b9ab867d0a28ab43c5717bb85b0a5f6b3b0a4/networkx-3.6.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/8e/eb/5da01e356015aee6ecfa1187ced87aef51364e306f5e695dd52719bf0e78/orjson-3.11.9-cp314-cp314-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl - - pypi: https://files.pythonhosted.org/packages/bb/40/c6ea527147c73b24fc15c891c3fcffe9c019793119c5742b8784a062c7db/pandas-3.0.2-cp314-cp314-macosx_10_15_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/9f/90/279f55fff9481f9e0424c3c97b24dc10004ec8d8f98ddf5afd07a7b79194/diraccfg-1.0.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a0/1d/d9257dd49ff2ca23ea5f132edf1281a0c4f9de8a762b9ae399b670a59235/typer-0.21.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a0/61/5c78b91c3143ed5c14207f463aecfc8f9dbb5092fb2869baf37c273b2705/gitdb-4.0.12-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a1/01/9674cc6d478406ae61d910cb16ca8b5699a8a9e6a2019987ebe5a5957d1d/joserfc-1.6.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a1/5c/8b56b08db91e569d0a4fbfa3e492ed2026081bdd7e892f63ba1c88a2f548/ruamel_yaml_clib-0.2.15-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/a4/ed/1f1afb2e9e7f38a545d628f864d562a5ae64fe6f7a10e28ffb9b185b4e89/importlib_resources-6.5.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a7/06/3d6badcf13db419e25b07041d9c7b4a2c331d3f4e7134445ec5df57714cd/coloredlogs-15.0.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a7/b2/fabede9fafd976b991e9f1b9c8c873ed86f202889b864756f240ce6dd855/frozenlist-1.8.0-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl - pypi: https://files.pythonhosted.org/packages/a9/90/a744336f5af32c433bd09af7854599682a383b37cfd78f7de263de6ad6cb/paramiko-4.0.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/9e/c3/059298687310d527a58bb01f3b1965787ee3b40dce76752eda8b44e9a2c5/pexpect-4.9.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/84/03/0d3ce49e2505ae70cf43bc5bb3033955d2fc9f932163e84dc0779cc47f48/prompt_toolkit-3.0.52-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/65/9b/03b04e7d82a5f54fb16113d839f5ea1ede58a61e90edf515f6577c66fa8f/propcache-0.4.1-cp314-cp314-macosx_10_13_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/8e/fb/2c4c618185be2bda327f9dacd16b3122cc938809f19df7be840595d0e584/prov-1.5.1-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/22/a6/858897256d0deac81a172289110f31629fc4cee19b6f01283303e18c8db3/ptyprocess-0.7.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/44/b5/a96872e5184f354da9c84ae119971a0a4c221fe9b27a4d94bd43f2596727/pyasn1-0.6.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/47/8d/d529b5d697919ba8c11ad626e835d4039be708a35b0d22de83a269a6682c/pyasn1_modules-0.4.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/5a/87/b70ad306ebb6f9b585f114d0ac2137d792b48be34d732d60e597c2f8465a/pydantic-2.12.5-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ea/28/46b7c5c9635ae96ea0fbb779e271a38129df2550f763937659ee6c5dbc65/pydantic_core-2.41.5-cp314-cp314-macosx_10_12_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/c1/60/5d4751ba3f4a40a6891f24eec885f51afd78d208498268c734e256fb13c4/pydantic_settings-2.12.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/7e/32/a7125fb28c4261a627f999d5fb4afff25b523800faed2c30979949d6facd/pydot-4.0.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/6f/01/c26ce75ba460d5cd503da9e13b21a33804d38c2165dec7b716d06b13010c/pyjwt-2.11.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/be/7b/4845bbf88e94586ec47a432da4e9107e3fc3ce37eb412b1398630a37f7dd/pynacl-1.6.2-cp38-abi3-macosx_10_10_universal2.whl - - pypi: https://files.pythonhosted.org/packages/10/bd/c038d7cc38edc1aa5bf91ab8068b63d4308c66c4c8bb3cbba7dfbc049f9c/pyparsing-3.3.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/14/1b/a298b06749107c305e1fe0f814c6c74aea7b2f1e10989cb30f544a1b3253/python_dotenv-1.2.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/38/ee/a61bb562bdf6f0bc6c51cdcf80ab5503cbb4b2f5053fa4b054cc0a56e48a/python_gitlab-8.2.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/81/c4/34e93fe5f5429d7570ec1fa436f1986fb1f00c3e0f43a589fe2bbcd22c3f/pytz-2025.2-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/81/41/aa3ffb3355e62e1bf91f6599b3092e866bc88487a07c524004943c7676df/rapidfuzz-3.14.5-cp314-cp314-macosx_10_15_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/b9/20/35d2baebacf357b562bd081936b66cd845775442973cb033a377fd639a84/rdflib-7.5.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/1e/db/4254e3eabe8020b458f1a747140d32277ec7a271daf1d235b70dc0b4e6e3/requests-2.32.5-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/3f/51/d4db610ef29373b879047326cbf6fa98b6c1969d6f6dc423279de2b1be2c/requests_toolbelt-1.0.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ef/45/615f5babd880b4bd7d405cc0dc348234c5ffb6ed1ea33e152ede08b2072d/rich-14.3.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/04/80/97b6f357ac458d9ad9872cc3183ca09ef7439ac89e030ea43053ba1294b6/rich_argparse-1.7.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ab/7e/5f02b757bb825e5cdc65f6f7a12c209963bec877d61497393bea8f41f9ce/diracx_api-0.0.8-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/af/fe/b6045c782f1fd1ae317d2a6ca1884857ce5c20f59befe6ab25a8603c43a7/ruamel_yaml-0.18.17-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/3e/bd/ab8459c8bb759c14a146990bf07f632c1cbec0910d4853feeee4be2ab8bb/ruamel_yaml_clib-0.2.15-cp314-cp314-macosx_10_15_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/5c/48/ccd6c49477674389d55b5b5520e47d1290f4c29686c36f5674f4a7aced00/rucio_clients-39.2.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/fc/51/727abb13f44c1fcf6d145979e1535a35794db0f6e450a0cb46aa24732fe2/s3transfer-0.16.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/62/86/3915cb5a603e1b1d798e1ee1ce2a0a390a0f85d35da97e4b6d1c6a45421b/schema_salad-8.9.20251102115403-cp314-cp314-macosx_10_15_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/70/98/d82f14ac7ffedbd38dfa2383f142b26d18d23ca6cf35a40f4af60df666bd/sh-2.2.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e0/f9/0595336914c5619e5f28a1fb793285925a8cd4b432c9da0a987836c7f822/shellingham-1.5.4-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/59/25/68f81c50aeb3f30e01c20da0f56d14c1a779b57d9308c50e19c63dc8413f/signurlarity-0.2.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b0/28/87e78ff0d6041f40431d88b8aa3b645be7476a420d8dcbf7197f5b394c5c/diracx_cli-0.0.8-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b0/57/dea471da24ceac6de8c3dc5d37e4ddde57a5c340d6bac90010898734de34/gitlint_core-0.19.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b2/c9/459da97eb93fad89738951972671d44be197610242b8da88a0384791ea7e/diracx_core-0.0.8-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b2/f2/889ad4b2408f72fe1a4f6a19491177b30ea7bf1a0fd5f17050ca08cfc882/propcache-0.4.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b3/68/aa714515d65090fcbcc9a1f3debd5a644b14aad11e59238f42f00bd4b298/logzero-1.7.0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/04/be/d09147ad1ec7934636ad912901c5fd7667e1c858e19d355237db0d0cd5e4/smmap-5.0.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/46/2c/1462b1d0a634697ae9e55b3cecdcb64788e8b7d63f54d923fcd0bb140aed/soupsieve-2.8.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/f9/38/8b6fc7a8153cb49eb3a9a13acfa9eeb6cc476e37888781e593e6f02ac05e/spython-0.3.14-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/fc/a1/9c4efa03300926601c19c18582531b45aededfb961ab3c3585f1e24f120b/sqlalchemy-2.0.46-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/f4/40/8561ce06dc46fd17242c7724ab25b257a2ac1b35f4ebf551b40ce6105cfa/stevedore-5.6.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/40/44/4a5f08c96eb108af5cb50b41f76142f0afa346dfa99d5296fe7202a11854/tabulate-0.9.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a0/1d/d9257dd49ff2ca23ea5f132edf1281a0c4f9de8a762b9ae399b670a59235/typer-0.21.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/dc/9b/47798a6c91d8bdb567fe2698fe81e0c6b7cb7ef4d13da4114b41d239f65d/typing_inspection-0.4.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c7/b0/003792df09decd6849a5e39c28b513c06e84436a54440380862b5aeff25d/tzdata-2025.3-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b9/20/35d2baebacf357b562bd081936b66cd845775442973cb033a377fd639a84/rdflib-7.5.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ba/24/c65fe1aef4e0681cb17ca136eb0f3e20a47d3941a306bc9d636938029ca5/lb_telemetry-0.5.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ba/5a/18ad964b0086c6e62e2e7500f7edc89e3faa45033c71c1893d34eed2b2de/dnspython-2.8.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c1/60/5d4751ba3f4a40a6891f24eec885f51afd78d208498268c734e256fb13c4/pydantic_settings-2.12.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/c4/55/85e2732345dd8b66437cddedac4ee7ef2d9c25bf8792830b095f2ee658f3/uproot-5.7.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/39/08/aaaad47bc4e9dc8c725e68f9d04865dbcb2052843ff09c97b08904852d84/urllib3-2.6.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/3c/c1/d73f12f8cdb1891334a2ccf7389eed244d3941e74d80dd220badb937f3fb/wcwidth-0.5.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/95/a0/1c2396e272f91efe6b16a6a8bce7ad53856c8f9ae4f34ceaa711d63ec9e1/wrapt-2.1.1-cp314-cp314-macosx_10_15_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/9d/0a/03192e78071cfb86e6d8ceae0e5dcec4bacf0fd734755263aabd01532e50/xattr-1.3.0-cp314-cp314-macosx_10_15_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/c7/b0/003792df09decd6849a5e39c28b513c06e84436a54440380862b5aeff25d/tzdata-2025.3-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c8/85/9535df0b78ba51f478c9ce7eb6d1f85535cc31fe356773b48fd9d3e563ca/rapidfuzz-3.14.5-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl - pypi: https://files.pythonhosted.org/packages/ca/6d/b1a49f9712a910acdcb8dc5765e57d60c2be9fe9b001a21b6a98a1d85adb/xenv-0.0.6-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/38/34/98a2f52245f4d47be93b580dae5f9861ef58977d73a79eb47c58f1ad1f3a/xmltodict-1.0.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/7e/5e/0138bc4484ea9b897864d59fce9be9086030825bc778b76cb5a33a906d37/xxhash-3.6.0-cp314-cp314-macosx_10_13_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/e4/04/3532d990fdbab02e5ede063676b5c4260e7f3abea2151099c2aa745acc4c/yarl-1.22.0-cp314-cp314-macosx_10_13_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/2e/54/647ade08bf0db230bfea292f893923872fd20be6ac6f53b2b936ba839d75/zipp-3.23.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/3d/5c/f8923b595b55fe49e30612987ad8bf053aef555c14f05bb659dd5dbe3e8a/zstandard-0.25.0-cp314-cp314-macosx_10_13_x86_64.whl - - pypi: ./ - osx-arm64: - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/_openmp_mutex-4.5-7_kmp_llvm.conda + - pypi: https://files.pythonhosted.org/packages/ca/aa/ab2d6d68c3ee50f6dedbbc91a31cd38f9fede9258d54e7aca29bfca4ebc1/awkward_cpp-52-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/cd/22/4d16dca3bd1d6475a53063eb72150269cea1a0a201b55288b3402f61f119/aiobotocore-3.1.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d0/23/49cf8ea1d129637941f06fb78f5f66077bf362762c5f6c01712c4cd0e87f/hyperscan-0.8.2-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/d0/d0/9e71fdc3394ffc632f35946c572e60fcc2a5452ba0a23c52493f23d60672/dirac-9.1.6-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d5/1f/5f4a3cd9e4440e9d9bc78ad0a91a1c8d46b4d429d5239ebe6793c9fe5c41/fsspec-2026.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d7/4c/f3b97c7d6008b3a895bbadb2deb44ad3446ae5fe204c72cd540dc222e57d/lbenv-2.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/db/2b/1239938a2629c29363e07724d7bd4c87a8b566947ecee2afb5f5ac34e1bb/cwl_upgrader-1.2.14-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/db/56/073989deb4b5d7d6e7ea424476a4ae4bda02140f2dbeaafb14ba4864dd60/wrapt-2.1.1-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/dc/80/12235e5b75bb2c586733280854f131b86051e0bbdfb55349ff70d0f72cf9/dogpile_cache-1.5.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/dc/9b/47798a6c91d8bdb567fe2698fe81e0c6b7cb7ef4d13da4114b41d239f65d/typing_inspection-0.4.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/de/15/545e2b6cf2e3be84bc1ed85613edd75b8aea69807a71c26f4ca6a9258e82/email_validator-2.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e0/f9/0595336914c5619e5f28a1fb793285925a8cd4b432c9da0a987836c7f822/shellingham-1.5.4-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e3/d1/e30e537a15f53485b61f5be525f2157da719819e8377298502aebac45536/aiohttp-3.13.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/e6/51/aac7e419521d5519e13087a7198623655648c939822bd7f4bdc9ccbe07f9/botocore-1.42.42-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e6/ad/3cc14f097111b4de0040c83a525973216457bbeeb63739ef1ed275c1c021/certifi-2026.1.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ed/ba/603ce3961e339413543d8cd44f21f2c80e2a7c5cfe692a7b1f2cccf58f3c/xxhash-3.6.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/ed/c9/d7977eaacb9df673210491da99e6a247e93df98c715fc43fd136ce1d3d33/arrow-1.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ef/45/615f5babd880b4bd7d405cc0dc348234c5ffb6ed1ea33e152ede08b2072d/rich-14.3.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ef/79/c45f2d53efe6ada1110cf6f9fca095e4ff47a0454444aefdde6ac4789179/cachecontrol-0.14.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f0/0f/310fb31e39e2d734ccaa2c0fb981ee41f7bd5056ce9bc29b2248bd569169/humanfriendly-10.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f2/61/0c78d9778bffd844863d3173a5fefb506d7131ceebecee523a9e27024aa1/diracx_client-0.0.8-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f4/40/8561ce06dc46fd17242c7724ab25b257a2ac1b35f4ebf551b40ce6105cfa/stevedore-5.6.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f5/e7/d8c5a7752fef68205296201f8ec2bf718f5c805a7a7e9880576c67600658/yarl-1.22.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/f8/b2/ad8e7e63fdf5add3ceb7a0805d700e9fd7cb7d5743f765a4994b4ec286d7/diraccommon-9.1.6-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f9/38/8b6fc7a8153cb49eb3a9a13acfa9eeb6cc476e37888781e593e6f02ac05e/spython-0.3.14-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fa/5e/f8e9a1d23b9c20a551a8a02ea3637b4642e22c2626e3a13a9a29cdea99eb/importlib_metadata-8.7.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fc/51/727abb13f44c1fcf6d145979e1535a35794db0f6e450a0cb46aa24732fe2/s3transfer-0.16.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fc/d8/b8fcba9464f02b121f39de2db2bf57f0b216fe11d014513d666e8634380d/azure_core-1.38.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fe/3b/8ec5074bcfc450fe84273713b4b0a0dd47c0249358f5d82eb8104ffe2520/multidict-6.7.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + osx-64: - conda: https://conda.anaconda.org/conda-forge/noarch/attrs-25.4.0-pyhcf101f3_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/backports.asyncio.runner-1.2.0-pyh5ded981_2.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/bzip2-1.0.8-hd037594_8.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/c-ares-1.34.6-hc919400_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.1.4-hbd8a1cb_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/cffi-2.0.0-py314h44086f9_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/cfgv-3.5.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/cyrus-sasl-2.1.28-ha1cbb27_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/davix-0.8.10-h0b7473d_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/dcap-2.47.14-h33e0366_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/distlib-0.4.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/filelock-3.20.3-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/gct-6.2.1705709074-h07e554c_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/gfal2-2.23.5-h46ca294_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/gsoap-2.8.123-hfb11b17_0.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/gtest-1.17.0-ha393de7_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/icu-78.2-h38cb7af_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/identify-2.6.16-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/json-c-0.18-he4178ee_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-4.26.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-specifications-2025.9.1-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/krb5-1.21.3-h237132a_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libblas-3.11.0-5_h51639a9_openblas.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libboost-1.88.0-h0419b56_7.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libboost-python-1.88.0-py314hce24fef_7.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcblas-3.11.0-5_hb0561ab_openblas.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcurl-8.18.0-he38603e_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcxx-21.1.8-h55c6f16_2.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libedit-3.1.20250104-pl5321hafb1f1b_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libev-4.33-h93a5062_2.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libexpat-2.7.3-haf25636_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libffi-3.5.2-hcf2aa1b_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libgcc-15.2.0-hcbb3090_17.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libgfortran-15.2.0-h07b0088_17.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libgfortran5-15.2.0-hdae7583_17.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libglib-2.86.3-hfe11c1f_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libiconv-1.18-h23cfdf5_2.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libintl-0.25.1-h493aca8_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/liblapack-3.11.0-5_hd9741b5_openblas.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libltdl-2.4.3a-h286801f_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/liblzma-5.8.2-h8088a28_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libmpdec-4.0.0-h84a0fba_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libnghttp2-1.67.0-hc438710_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libntlm-1.8-h5505292_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libopenblas-0.3.30-openmp_ha158390_4.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsqlite-3.51.2-h1ae2325_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libssh2-1.11.1-h1590b86_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libtool-2.5.4-h286801f_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libuuid-2.41.3-h0053d0f_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libxcrypt-4.4.36-h93a5062_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libxml2-16-2.15.1-h5ef1a60_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libxml2-2.15.1-h8d039ee_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libxml2-devel-2.15.1-h8d039ee_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libzlib-1.3.1-h8359307_2.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/llvm-openmp-21.1.8-h4a912ad_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/m2crypto-0.45.1-py314hdb6fb3f_2.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/mypy-1.19.1-py314hbdd0d06_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mypy_extensions-1.1.0-pyha770c72_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ncurses-6.5-h5e97a16_3.conda - conda: https://conda.anaconda.org/conda-forge/noarch/nodeenv-1.10.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/numpy-2.4.2-py314hae46ccb_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/openldap-2.6.10-hbe55e7a_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.6.1-hd24854e_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pathspec-1.0.4-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pcre2-10.47-h30297fc_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/perl-5.32.1-7_h4614cfb_perl5.conda - conda: https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.5.1-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pre-commit-4.5.1-pyha770c72_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/psutil-7.2.2-py314ha14b1ff_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pugixml-1.15-hd3d436d_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-asyncio-1.3.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-mock-3.15.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/python-3.14.3-h4c637c5_100_cp314.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/python-gfal2-1.13.1-py314h5c1db39_2.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/python-librt-0.7.8-py314ha14b1ff_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyyaml-6.0.3-py314h6e9b3f0_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/readline-8.3-h46df422_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/referencing-0.37.0-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/rpds-py-0.30.0-py314haad56a0_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ruff-0.15.0-h279115b_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/scitokens-cpp-1.3.0-h608d757_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-80.10.2-pyh332efcf_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/srm-ifce-1.24.6-he0fb9dd_2.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/tk-8.6.13-h010d191_3.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ukkonen-1.1.0-py314h6cfcd04_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/virtualenv-20.36.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/xrootd-5.9.1-py314h6e96a01_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/yaml-0.2.5-h925e9cb_3.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/zlib-1.3.1-h8359307_2.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/zstd-1.5.7-hbf9d68e_6.conda - - pypi: https://files.pythonhosted.org/packages/cd/22/4d16dca3bd1d6475a53063eb72150269cea1a0a201b55288b3402f61f119/aiobotocore-3.1.2-py3-none-any.whl + - conda: https://conda.anaconda.org/conda-forge/osx-64/_openmp_mutex-4.5-7_kmp_llvm.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/bzip2-1.0.8-h500dc9f_8.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/c-ares-1.34.6-hb5e19a0_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/cffi-2.0.0-py314h8ca4d5a_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/cyrus-sasl-2.1.28-h610c526_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/davix-0.8.10-h35d429b_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/dcap-2.47.14-hf4fbb18_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/gct-6.2.1705709074-h8d8e280_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/gfal2-2.23.5-h6ef8084_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/gsoap-2.8.123-h21ae599_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/osx-64/gtest-1.17.0-h9275861_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/icu-78.2-h14c5de8_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/json-c-0.18-hc62ec3d_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/krb5-1.21.3-h37d8d59_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libblas-3.11.0-5_he492b99_openblas.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libboost-1.88.0-h5950822_7.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libboost-python-1.88.0-py314hee2ba4e_7.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libcblas-3.11.0-5_h9b27e0a_openblas.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libcurl-8.18.0-h9348e2b_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libcxx-21.1.8-h4fb565c_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libedit-3.1.20250104-pl5321ha958ccf_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libev-4.33-h10d778d_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libexpat-2.7.3-heffb93a_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libffi-3.5.2-hd1f9c09_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libgcc-15.2.0-h08519bb_17.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libgfortran-15.2.0-h7e5c614_17.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libgfortran5-15.2.0-hd16e46c_17.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libglib-2.86.3-hf241ffe_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libiconv-1.18-h57a12c2_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libintl-0.25.1-h3184127_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/liblapack-3.11.0-5_h859234e_openblas.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libltdl-2.4.3a-h240833e_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/liblzma-5.8.2-h11316ed_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libmpdec-4.0.0-hf3981d6_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libnghttp2-1.67.0-h3338091_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libntlm-1.8-h6e16a3a_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libopenblas-0.3.30-openmp_h6006d49_4.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libsqlite-3.51.2-hb99441e_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libssh2-1.11.1-hed3591d_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libtool-2.5.4-h240833e_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libuuid-2.41.3-h3fe7000_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libxcrypt-4.4.36-h10d778d_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libxml2-16-2.15.1-he456531_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libxml2-2.15.1-h24ca049_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libxml2-devel-2.15.1-h24ca049_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libzlib-1.3.1-hd23fc13_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/llvm-openmp-21.1.8-h472b3d1_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/m2crypto-0.45.1-py314h90001a5_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/mypy-1.19.1-py314h6482030_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/ncurses-6.5-h0622a9a_3.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/numpy-2.4.2-py314hfc4c462_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/openldap-2.6.10-hd8a590d_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/openssl-3.6.1-hb6871ef_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/pcre2-10.47-h13923f0_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/perl-5.32.1-7_h10d778d_perl5.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/psutil-7.2.2-py314hd330473_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/pugixml-1.15-h46091d4_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/python-3.14.3-h4f44bb5_100_cp314.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/python-gfal2-1.13.1-py314hd08135f_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/python-librt-0.7.8-py314hd330473_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/pyyaml-6.0.3-py314h10d0514_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/readline-8.3-h68b038d_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/rpds-py-0.30.0-py314ha7b6dee_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/ruff-0.15.0-h5930b28_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/scitokens-cpp-1.3.0-hcb75e18_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/srm-ifce-1.24.6-h73c9bdb_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/tk-8.6.13-h7142dee_3.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/ukkonen-1.1.0-py314h473ef84_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/xrootd-5.9.1-py314hb36820e_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/yaml-0.2.5-h4132b18_3.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/zlib-1.3.1-hd23fc13_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/zstd-1.5.7-h3eecb57_6.conda + - pypi: . + - pypi: git+https://gitlab.cern.ch/jlisalab/LHCbDIRAC.git?rev=modules-to-cwl-migration#bc5f8f1804107bc8807edcc98a97c346ef61c0e8 + - pypi: https://files.pythonhosted.org/packages/02/64/c86924898062e8217ed914a29458cfde9e4a9b80e4d4cbcca141983ba339/lbprodrun-1.12.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/04/80/97b6f357ac458d9ad9872cc3183ca09ef7439ac89e030ea43053ba1294b6/rich_argparse-1.7.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/04/be/d09147ad1ec7934636ad912901c5fd7667e1c858e19d355237db0d0cd5e4/smmap-5.0.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/0f/15/5bf3b99495fb160b63f95972b81750f18f7f4e02ad051373b669d17d44f2/aiohappyeyeballs-2.6.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e8/0b/b97660c5fd05d3495b4eb27f2d0ef18dc1dc4eff7511a9bf371397ff0264/aiohttp-3.13.3-cp314-cp314-macosx_11_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/10/a1/510b0a7fadc6f43a6ce50152e69dbd86415240835868bb0bd9b5b88b1e06/aioitertools-0.13.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/10/bd/c038d7cc38edc1aa5bf91ab8068b63d4308c66c4c8bb3cbba7dfbc049f9c/pyparsing-3.3.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/14/1b/a298b06749107c305e1fe0f814c6c74aea7b2f1e10989cb30f544a1b3253/python_dotenv-1.2.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/14/2f/967ba146e6d58cf6a652da73885f52fc68001525b4197effc174321d70b4/jmespath-1.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/15/aa/0aca39a37d3c7eb941ba736ede56d689e7be91cab5d9ca846bde3999eba6/isodate-0.7.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1a/39/47f9197bdd44df24d67ac8893641e16f386c984a0619ef2ee4c51fbbc019/beautifulsoup4-4.14.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1e/db/4254e3eabe8020b458f1a747140d32277ec7a271daf1d235b70dc0b4e6e3/requests-2.32.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/22/71/201105712d0a2ff07b7873ed3c220292fb2ea5120603c00c4b634bcdafb3/msgpack-1.1.2-cp314-cp314-macosx_10_13_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/22/a6/858897256d0deac81a172289110f31629fc4cee19b6f01283303e18c8db3/ptyprocess-0.7.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/22/ed/9c45c468fd6c31df3fe0622394b1853c00b86545d1e297f3fb9fba1232ce/hyperscan-0.8.2-cp314-cp314-macosx_10_15_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/28/df/2dd32cce20cbcf6f2ec456b58d44368161ad28320729f64e5e1d5d7bd0ae/cachetools-7.0.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2a/35/7051599bd493e62411d6ede36fd5af83a38f37c4767b92884df7301db25d/charset_normalizer-3.4.4-cp314-cp314-macosx_10_13_universal2.whl + - pypi: https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2d/88/67602dfa2d7ab5d0518af82db34ab4d70dc2c3029b3ca788299a3be4a96d/lhcbdiracx_client-0.0.8-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2e/54/647ade08bf0db230bfea292f893923872fd20be6ac6f53b2b936ba839d75/zipp-3.23.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/32/4b/b99e37f88336009971405cbb7630610322ed6fbfa31e1d7ab3fbf3049a2d/invoke-2.2.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/34/8f/6105afdd8f4e1f3b198d09e4b2622622923d9fa9e077aed852c0bb035a3a/lhcbdiracx_core-0.0.8-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/37/f9/f8497ef8b873a8bb2a750ee2a6c5f0fc22258e1acb6245fd237042a6c279/fabric-3.2.3-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/38/0e/27be9fdef66e72d64c0cdc3cc2823101b80585f8119b5c112c2e8f5f7dab/anyio-4.12.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/74/f5/9373290775639cb67a2fce7f629a1c240dce9f12fe927bc32b2736e16dfc/argcomplete-3.6.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ed/c9/d7977eaacb9df673210491da99e6a247e93df98c715fc43fd136ce1d3d33/arrow-1.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/38/34/98a2f52245f4d47be93b580dae5f9861ef58977d73a79eb47c58f1ad1f3a/xmltodict-1.0.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/38/ee/a61bb562bdf6f0bc6c51cdcf80ab5503cbb4b2f5053fa4b054cc0a56e48a/python_gitlab-8.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/39/08/aaaad47bc4e9dc8c725e68f9d04865dbcb2052843ff09c97b08904852d84/urllib3-2.6.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3b/56/99a7cf6ca8533695874cf804369221d03bf5e869a7e0b38acbf4dbe8deeb/cwlformat-2022.2.18-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3c/c1/d73f12f8cdb1891334a2ccf7389eed244d3941e74d80dd220badb937f3fb/wcwidth-0.5.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3d/5c/f8923b595b55fe49e30612987ad8bf053aef555c14f05bb659dd5dbe3e8a/zstandard-0.25.0-cp314-cp314-macosx_10_13_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/3e/bd/ab8459c8bb759c14a146990bf07f632c1cbec0910d4853feeee4be2ab8bb/ruamel_yaml_clib-0.2.15-cp314-cp314-macosx_10_15_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/3f/51/d4db610ef29373b879047326cbf6fa98b6c1969d6f6dc423279de2b1be2c/requests_toolbelt-1.0.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/40/44/4a5f08c96eb108af5cb50b41f76142f0afa346dfa99d5296fe7202a11854/tabulate-0.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/44/b5/a96872e5184f354da9c84ae119971a0a4c221fe9b27a4d94bd43f2596727/pyasn1-0.6.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/46/2c/1462b1d0a634697ae9e55b3cecdcb64788e8b7d63f54d923fcd0bb140aed/soupsieve-2.8.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/47/8d/d529b5d697919ba8c11ad626e835d4039be708a35b0d22de83a269a6682c/pyasn1_modules-0.4.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/4e/8c/f3147f5c4b73e7550fe5f9352eaa956ae838d5c51eb58e7a25b9f3e2643b/decorator-5.2.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/54/51/321e821856452f7386c4e9df866f196720b1ad0c5ea1623ea7399969ae3b/authlib-1.6.6-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/77/39/4d8414260c3d83f22029a39e51553c173611b378d62ca391e5ca68e65cfa/awkward-2.9.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/fb/b9/0978fa6f21f504b617ccee4843210d7ab8921a10e94e3bbf084498dcfad7/awkward_cpp-52-cp314-cp314-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/fc/d8/b8fcba9464f02b121f39de2db2bf57f0b216fe11d014513d666e8634380d/azure_core-1.38.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/58/19/0380af745f151a1648657bbcef0fb49ac28bf09083d94498163ffd9b32dc/dominate-2.9.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/59/25/68f81c50aeb3f30e01c20da0f56d14c1a779b57d9308c50e19c63dc8413f/signurlarity-0.2.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5a/36/17015b7bae2783f7bbde50a8bafdeb702802c080322204f1bfcae25b9e02/DB12-1.0.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5a/87/b70ad306ebb6f9b585f114d0ac2137d792b48be34d732d60e597c2f8465a/pydantic-2.12.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5c/48/ccd6c49477674389d55b5b5520e47d1290f4c29686c36f5674f4a7aced00/rucio_clients-39.2.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/5d/ba/2af136406e1c3839aea9ecadc2f6be2bcd1eff255bd451dd39bcf302c47a/bcrypt-5.0.0-cp39-abi3-macosx_10_12_universal2.whl - - pypi: https://files.pythonhosted.org/packages/1a/39/47f9197bdd44df24d67ac8893641e16f386c984a0619ef2ee4c51fbbc019/beautifulsoup4-4.14.3-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/5e/0a/3966f239e1d9da93cb755dc0213835ce4e9ed93645192878d0a055ecdc31/boto3-1.42.42-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e6/51/aac7e419521d5519e13087a7198623655648c939822bd7f4bdc9ccbe07f9/botocore-1.42.42-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ef/79/c45f2d53efe6ada1110cf6f9fca095e4ff47a0454444aefdde6ac4789179/cachecontrol-0.14.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/28/df/2dd32cce20cbcf6f2ec456b58d44368161ad28320729f64e5e1d5d7bd0ae/cachetools-7.0.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e6/ad/3cc14f097111b4de0040c83a525973216457bbeeb63739ef1ed275c1c021/certifi-2026.1.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/2a/35/7051599bd493e62411d6ede36fd5af83a38f37c4767b92884df7301db25d/charset_normalizer-3.4.4-cp314-cp314-macosx_10_13_universal2.whl - - pypi: https://files.pythonhosted.org/packages/98/78/01c019cdb5d6498122777c1a43056ebb3ebfeef2076d9d026bfe15583b2b/click-8.3.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a7/06/3d6badcf13db419e25b07041d9c7b4a2c331d3f4e7134445ec5df57714cd/coloredlogs-15.0.1-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/de/07/a1051cdbbe6d723df16d756b97f09da7c1adb69e29695c58f0392bc12515/cramjam-2.11.0-cp314-cp314-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl - - pypi: https://files.pythonhosted.org/packages/8d/99/157aae7949a5f30d51fcb1a9851e8ebd5c74bf99b5285d8bb4b8b9ee641e/cryptography-46.0.4-cp311-abi3-macosx_10_9_universal2.whl - - pypi: https://files.pythonhosted.org/packages/db/2b/1239938a2629c29363e07724d7bd4c87a8b566947ecee2afb5f5ac34e1bb/cwl_upgrader-1.2.14-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5f/e8/2e6301567e6debaad6abae0e217428471651ce877537b7095b6a8e7d8cd2/fts3-3.14.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/62/86/3915cb5a603e1b1d798e1ee1ce2a0a390a0f85d35da97e4b6d1c6a45421b/schema_salad-8.9.20251102115403-cp314-cp314-macosx_10_15_x86_64.whl - pypi: https://files.pythonhosted.org/packages/63/4b/ccab2a5ca9e0b6553810b85c06387e60fc9443cec3c987e3a062705bd225/cwl_utils-0.40-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/3b/56/99a7cf6ca8533695874cf804369221d03bf5e869a7e0b38acbf4dbe8deeb/cwlformat-2022.2.18-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/65/9b/03b04e7d82a5f54fb16113d839f5ea1ede58a61e90edf515f6577c66fa8f/propcache-0.4.1-cp314-cp314-macosx_10_13_x86_64.whl - pypi: https://files.pythonhosted.org/packages/65/ee/a7aba2b112c5ae879d5cfb231c75189a7fd2a5e84b6af7e07dd71fb2bb35/cwltool-3.1.20260108082145-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/5a/36/17015b7bae2783f7bbde50a8bafdeb702802c080322204f1bfcae25b9e02/DB12-1.0.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/4e/8c/f3147f5c4b73e7550fe5f9352eaa956ae838d5c51eb58e7a25b9f3e2643b/decorator-5.2.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/68/15/bfb0c717b8f23c16907f3e73e8f56010ccd72e9900a108209665b0d9ed4b/lhcbdiracx_cli-0.0.8-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/6a/09/e21df6aef1e1ffc0c816f0522ddc3f6dcded766c3261813131c78a704470/gitpython-3.1.46-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/6d/10/b37ac718c5903758fa9058a5182026a4f3b65443196b82c7840389ea0dbd/lbplatformutils-4.6.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/6f/01/c26ce75ba460d5cd503da9e13b21a33804d38c2165dec7b716d06b13010c/pyjwt-2.11.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/70/98/d82f14ac7ffedbd38dfa2383f142b26d18d23ca6cf35a40f4af60df666bd/sh-2.2.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/73/90/a2c51050d9254bd9134e6368b3f94f92f0eb2c34ed0ca19ec449ce2fc288/fsspec_xrootd-0.5.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/74/f5/9373290775639cb67a2fce7f629a1c240dce9f12fe927bc32b2736e16dfc/argcomplete-3.6.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/77/39/4d8414260c3d83f22029a39e51553c173611b378d62ca391e5ca68e65cfa/awkward-2.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/7a/f0/8282d9641415e9e33df173516226b404d367a0fc55e1a60424a152913abc/mistune-3.1.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/7e/32/a7125fb28c4261a627f999d5fb4afff25b523800faed2c30979949d6facd/pydot-4.0.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/7e/5e/0138bc4484ea9b897864d59fce9be9086030825bc778b76cb5a33a906d37/xxhash-3.6.0-cp314-cp314-macosx_10_13_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/7f/37/8ea3555769b6048b5e4ec162cc90fd32e761c0e381ffb3baf888cb0d8a71/lhcbdiracx_api-0.0.8-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/81/41/aa3ffb3355e62e1bf91f6599b3092e866bc88487a07c524004943c7676df/rapidfuzz-3.14.5-cp314-cp314-macosx_10_15_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/81/c4/34e93fe5f5429d7570ec1fa436f1986fb1f00c3e0f43a589fe2bbcd22c3f/pytz-2025.2-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/84/03/0d3ce49e2505ae70cf43bc5bb3033955d2fc9f932163e84dc0779cc47f48/prompt_toolkit-3.0.52-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/84/d0/205d54408c08b13550c733c4b85429e7ead111c7f0014309637425520a9a/deprecated-1.3.1-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/d0/d0/9e71fdc3394ffc632f35946c572e60fcc2a5452ba0a23c52493f23d60672/dirac-9.1.6-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/87/a4/afc9dddc6b14fb3d52a900cd9b4c77770128edc4b07e576034bbd0ffd290/LbCondaWrappers-0.5.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/8d/99/157aae7949a5f30d51fcb1a9851e8ebd5c74bf99b5285d8bb4b8b9ee641e/cryptography-46.0.4-cp311-abi3-macosx_10_9_universal2.whl + - pypi: https://files.pythonhosted.org/packages/8e/e8/a1185e236ec66c20afd72399522f142c3724c785789255202d27ae992818/frozenlist-1.8.0-cp314-cp314-macosx_10_13_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/8e/eb/5da01e356015aee6ecfa1187ced87aef51364e306f5e695dd52719bf0e78/orjson-3.11.9-cp314-cp314-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl + - pypi: https://files.pythonhosted.org/packages/8e/fb/2c4c618185be2bda327f9dacd16b3122cc938809f19df7be840595d0e584/prov-1.5.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/94/54/e7d793b573f298e1c9013b8c4dade17d481164aa517d1d7148619c2cedbf/markdown_it_py-4.0.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/95/a0/1c2396e272f91efe6b16a6a8bce7ad53856c8f9ae4f34ceaa711d63ec9e1/wrapt-2.1.1-cp314-cp314-macosx_10_15_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/98/78/01c019cdb5d6498122777c1a43056ebb3ebfeef2076d9d026bfe15583b2b/click-8.3.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9a/02/0e550c9606ffae81603a9d240369a93cdf1e4bc48e2e314d367825a1c02d/awkward_cpp-52-cp314-cp314-macosx_10_15_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/9d/0a/03192e78071cfb86e6d8ceae0e5dcec4bacf0fd734755263aabd01532e50/xattr-1.3.0-cp314-cp314-macosx_10_15_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/9e/c3/059298687310d527a58bb01f3b1965787ee3b40dce76752eda8b44e9a2c5/pexpect-4.9.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9e/c9/b2622292ea83fbb4ec318f5b9ab867d0a28ab43c5717bb85b0a5f6b3b0a4/networkx-3.6.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/9f/90/279f55fff9481f9e0424c3c97b24dc10004ec8d8f98ddf5afd07a7b79194/diraccfg-1.0.1-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/f8/b2/ad8e7e63fdf5add3ceb7a0805d700e9fd7cb7d5743f765a4994b4ec286d7/diraccommon-9.1.6-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a0/1d/d9257dd49ff2ca23ea5f132edf1281a0c4f9de8a762b9ae399b670a59235/typer-0.21.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a0/61/5c78b91c3143ed5c14207f463aecfc8f9dbb5092fb2869baf37c273b2705/gitdb-4.0.12-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a1/01/9674cc6d478406ae61d910cb16ca8b5699a8a9e6a2019987ebe5a5957d1d/joserfc-1.6.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a4/ed/1f1afb2e9e7f38a545d628f864d562a5ae64fe6f7a10e28ffb9b185b4e89/importlib_resources-6.5.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a7/06/3d6badcf13db419e25b07041d9c7b4a2c331d3f4e7134445ec5df57714cd/coloredlogs-15.0.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a9/90/a744336f5af32c433bd09af7854599682a383b37cfd78f7de263de6ad6cb/paramiko-4.0.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/ab/7e/5f02b757bb825e5cdc65f6f7a12c209963bec877d61497393bea8f41f9ce/diracx_api-0.0.8-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ae/fb/011c7c717213182caf78084a9bea51c8590b0afda98001f69d9f853a495b/greenlet-3.3.1-cp314-cp314-macosx_11_0_universal2.whl + - pypi: https://files.pythonhosted.org/packages/af/fe/b6045c782f1fd1ae317d2a6ca1884857ce5c20f59befe6ab25a8603c43a7/ruamel_yaml-0.18.17-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/b0/28/87e78ff0d6041f40431d88b8aa3b645be7476a420d8dcbf7197f5b394c5c/diracx_cli-0.0.8-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/f2/61/0c78d9778bffd844863d3173a5fefb506d7131ceebecee523a9e27024aa1/diracx_client-0.0.8-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b0/57/dea471da24ceac6de8c3dc5d37e4ddde57a5c340d6bac90010898734de34/gitlint_core-0.19.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/b2/c9/459da97eb93fad89738951972671d44be197610242b8da88a0384791ea7e/diracx_core-0.0.8-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b3/68/aa714515d65090fcbcc9a1f3debd5a644b14aad11e59238f42f00bd4b298/logzero-1.7.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b9/20/35d2baebacf357b562bd081936b66cd845775442973cb033a377fd639a84/rdflib-7.5.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ba/24/c65fe1aef4e0681cb17ca136eb0f3e20a47d3941a306bc9d636938029ca5/lb_telemetry-0.5.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/ba/5a/18ad964b0086c6e62e2e7500f7edc89e3faa45033c71c1893d34eed2b2de/dnspython-2.8.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/bb/40/c6ea527147c73b24fc15c891c3fcffe9c019793119c5742b8784a062c7db/pandas-3.0.2-cp314-cp314-macosx_10_15_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/be/7b/4845bbf88e94586ec47a432da4e9107e3fc3ce37eb412b1398630a37f7dd/pynacl-1.6.2-cp38-abi3-macosx_10_10_universal2.whl + - pypi: https://files.pythonhosted.org/packages/c1/60/5d4751ba3f4a40a6891f24eec885f51afd78d208498268c734e256fb13c4/pydantic_settings-2.12.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c4/55/85e2732345dd8b66437cddedac4ee7ef2d9c25bf8792830b095f2ee658f3/uproot-5.7.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c7/b0/003792df09decd6849a5e39c28b513c06e84436a54440380862b5aeff25d/tzdata-2025.3-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c8/e8/c128e37589463668794d503afaeb003987373c5f94d667124ffd8078bbd9/lxml-6.0.2-cp314-cp314-macosx_10_13_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/ca/6d/b1a49f9712a910acdcb8dc5765e57d60c2be9fe9b001a21b6a98a1d85adb/xenv-0.0.6-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/cd/22/4d16dca3bd1d6475a53063eb72150269cea1a0a201b55288b3402f61f119/aiobotocore-3.1.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d0/d0/9e71fdc3394ffc632f35946c572e60fcc2a5452ba0a23c52493f23d60672/dirac-9.1.6-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d5/1f/5f4a3cd9e4440e9d9bc78ad0a91a1c8d46b4d429d5239ebe6793c9fe5c41/fsspec-2026.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d5/22/492f2246bb5b534abd44804292e81eeaf835388901f0c574bac4eeec73c5/multidict-6.7.1-cp314-cp314-macosx_10_15_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/d7/4c/f3b97c7d6008b3a895bbadb2deb44ad3446ae5fe204c72cd540dc222e57d/lbenv-2.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/db/2b/1239938a2629c29363e07724d7bd4c87a8b566947ecee2afb5f5ac34e1bb/cwl_upgrader-1.2.14-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/dc/80/12235e5b75bb2c586733280854f131b86051e0bbdfb55349ff70d0f72cf9/dogpile_cache-1.5.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/58/19/0380af745f151a1648657bbcef0fb49ac28bf09083d94498163ffd9b32dc/dominate-2.9.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/dc/9b/47798a6c91d8bdb567fe2698fe81e0c6b7cb7ef4d13da4114b41d239f65d/typing_inspection-0.4.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/de/07/a1051cdbbe6d723df16d756b97f09da7c1adb69e29695c58f0392bc12515/cramjam-2.11.0-cp314-cp314-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl - pypi: https://files.pythonhosted.org/packages/de/15/545e2b6cf2e3be84bc1ed85613edd75b8aea69807a71c26f4ca6a9258e82/email_validator-2.3.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/37/f9/f8497ef8b873a8bb2a750ee2a6c5f0fc22258e1acb6245fd237042a6c279/fabric-3.2.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a1/93/72b1736d68f03fda5fdf0f2180fb6caaae3894f1b854d006ac61ecc727ee/frozenlist-1.8.0-cp314-cp314-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/d5/1f/5f4a3cd9e4440e9d9bc78ad0a91a1c8d46b4d429d5239ebe6793c9fe5c41/fsspec-2026.3.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/73/90/a2c51050d9254bd9134e6368b3f94f92f0eb2c34ed0ca19ec449ce2fc288/fsspec_xrootd-0.5.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/5f/e8/2e6301567e6debaad6abae0e217428471651ce877537b7095b6a8e7d8cd2/fts3-3.14.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a0/61/5c78b91c3143ed5c14207f463aecfc8f9dbb5092fb2869baf37c273b2705/gitdb-4.0.12-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b0/57/dea471da24ceac6de8c3dc5d37e4ddde57a5c340d6bac90010898734de34/gitlint_core-0.19.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/6a/09/e21df6aef1e1ffc0c816f0522ddc3f6dcded766c3261813131c78a704470/gitpython-3.1.46-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e0/f9/0595336914c5619e5f28a1fb793285925a8cd4b432c9da0a987836c7f822/shellingham-1.5.4-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e4/04/3532d990fdbab02e5ede063676b5c4260e7f3abea2151099c2aa745acc4c/yarl-1.22.0-cp314-cp314-macosx_10_13_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/e6/51/aac7e419521d5519e13087a7198623655648c939822bd7f4bdc9ccbe07f9/botocore-1.42.42-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e6/ad/3cc14f097111b4de0040c83a525973216457bbeeb63739ef1ed275c1c021/certifi-2026.1.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ea/28/46b7c5c9635ae96ea0fbb779e271a38129df2550f763937659ee6c5dbc65/pydantic_core-2.41.5-cp314-cp314-macosx_10_12_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ed/c9/d7977eaacb9df673210491da99e6a247e93df98c715fc43fd136ce1d3d33/arrow-1.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ef/45/615f5babd880b4bd7d405cc0dc348234c5ffb6ed1ea33e152ede08b2072d/rich-14.3.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ef/79/c45f2d53efe6ada1110cf6f9fca095e4ff47a0454444aefdde6ac4789179/cachecontrol-0.14.4-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/f0/0f/310fb31e39e2d734ccaa2c0fb981ee41f7bd5056ce9bc29b2248bd569169/humanfriendly-10.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/d8/da/a8bb48a4fee86b5dad8a358559b70b010cd7effaa70ca5bb4e6e82e13703/hyperscan-0.8.2-cp314-cp314-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f2/61/0c78d9778bffd844863d3173a5fefb506d7131ceebecee523a9e27024aa1/diracx_client-0.0.8-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f3/e1/2f705da403f865a5fa3449b155738dc9c53021698fd6926253a9af03180b/levenshtein-0.27.3-cp314-cp314-macosx_10_15_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/f4/40/8561ce06dc46fd17242c7724ab25b257a2ac1b35f4ebf551b40ce6105cfa/stevedore-5.6.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f7/49/459327f0d5bcd8c6c9ca69e60fdeebc3622861e696490d8674a6d0cb90a6/aiohttp-3.13.3-cp314-cp314-macosx_10_13_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/f8/b2/ad8e7e63fdf5add3ceb7a0805d700e9fd7cb7d5743f765a4994b4ec286d7/diraccommon-9.1.6-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f9/38/8b6fc7a8153cb49eb3a9a13acfa9eeb6cc476e37888781e593e6f02ac05e/spython-0.3.14-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/fa/5e/f8e9a1d23b9c20a551a8a02ea3637b4642e22c2626e3a13a9a29cdea99eb/importlib_metadata-8.7.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a4/ed/1f1afb2e9e7f38a545d628f864d562a5ae64fe6f7a10e28ffb9b185b4e89/importlib_resources-6.5.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/32/4b/b99e37f88336009971405cbb7630610322ed6fbfa31e1d7ab3fbf3049a2d/invoke-2.2.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/15/aa/0aca39a37d3c7eb941ba736ede56d689e7be91cab5d9ca846bde3999eba6/isodate-0.7.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/14/2f/967ba146e6d58cf6a652da73885f52fc68001525b4197effc174321d70b4/jmespath-1.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a1/01/9674cc6d478406ae61d910cb16ca8b5699a8a9e6a2019987ebe5a5957d1d/joserfc-1.6.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ba/24/c65fe1aef4e0681cb17ca136eb0f3e20a47d3941a306bc9d636938029ca5/lb_telemetry-0.5.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/87/a4/afc9dddc6b14fb3d52a900cd9b4c77770128edc4b07e576034bbd0ffd290/LbCondaWrappers-0.5.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/d7/4c/f3b97c7d6008b3a895bbadb2deb44ad3446ae5fe204c72cd540dc222e57d/lbenv-2.4.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/6d/10/b37ac718c5903758fa9058a5182026a4f3b65443196b82c7840389ea0dbd/lbplatformutils-4.6.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/02/64/c86924898062e8217ed914a29458cfde9e4a9b80e4d4cbcca141983ba339/lbprodrun-1.12.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/76/2c/bb6ef359e007fe7b6b3195b68a94f4dd3ecd1885ee337ee8fbd4df55996f/levenshtein-0.27.3-cp314-cp314-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fc/51/727abb13f44c1fcf6d145979e1535a35794db0f6e450a0cb46aa24732fe2/s3transfer-0.16.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fc/a1/9c4efa03300926601c19c18582531b45aededfb961ab3c3585f1e24f120b/sqlalchemy-2.0.46-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fc/d8/b8fcba9464f02b121f39de2db2bf57f0b216fe11d014513d666e8634380d/azure_core-1.38.0-py3-none-any.whl + osx-arm64: + - conda: https://conda.anaconda.org/conda-forge/noarch/attrs-25.4.0-pyhcf101f3_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/backports.asyncio.runner-1.2.0-pyh5ded981_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.1.4-hbd8a1cb_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/cfgv-3.5.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/distlib-0.4.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/filelock-3.20.3-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/identify-2.6.16-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-4.26.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-specifications-2025.9.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/mypy_extensions-1.1.0-pyha770c72_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/nodeenv-1.10.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pathspec-1.0.4-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.5.1-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pre-commit-4.5.1-pyha770c72_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-asyncio-1.3.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-mock-3.15.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/referencing-0.37.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-80.10.2-pyh332efcf_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/virtualenv-20.36.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/_openmp_mutex-4.5-7_kmp_llvm.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/bzip2-1.0.8-hd037594_8.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/c-ares-1.34.6-hc919400_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/cffi-2.0.0-py314h44086f9_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/cyrus-sasl-2.1.28-ha1cbb27_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/davix-0.8.10-h0b7473d_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/dcap-2.47.14-h33e0366_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/gct-6.2.1705709074-h07e554c_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/gfal2-2.23.5-h46ca294_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/gsoap-2.8.123-hfb11b17_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/gtest-1.17.0-ha393de7_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/icu-78.2-h38cb7af_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/json-c-0.18-he4178ee_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/krb5-1.21.3-h237132a_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libblas-3.11.0-5_h51639a9_openblas.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libboost-1.88.0-h0419b56_7.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libboost-python-1.88.0-py314hce24fef_7.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcblas-3.11.0-5_hb0561ab_openblas.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcurl-8.18.0-he38603e_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcxx-21.1.8-h55c6f16_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libedit-3.1.20250104-pl5321hafb1f1b_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libev-4.33-h93a5062_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libexpat-2.7.3-haf25636_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libffi-3.5.2-hcf2aa1b_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libgcc-15.2.0-hcbb3090_17.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libgfortran-15.2.0-h07b0088_17.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libgfortran5-15.2.0-hdae7583_17.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libglib-2.86.3-hfe11c1f_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libiconv-1.18-h23cfdf5_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libintl-0.25.1-h493aca8_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/liblapack-3.11.0-5_hd9741b5_openblas.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libltdl-2.4.3a-h286801f_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/liblzma-5.8.2-h8088a28_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libmpdec-4.0.0-h84a0fba_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libnghttp2-1.67.0-hc438710_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libntlm-1.8-h5505292_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libopenblas-0.3.30-openmp_ha158390_4.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsqlite-3.51.2-h1ae2325_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libssh2-1.11.1-h1590b86_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libtool-2.5.4-h286801f_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libuuid-2.41.3-h0053d0f_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libxcrypt-4.4.36-h93a5062_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libxml2-16-2.15.1-h5ef1a60_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libxml2-2.15.1-h8d039ee_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libxml2-devel-2.15.1-h8d039ee_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libzlib-1.3.1-h8359307_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/llvm-openmp-21.1.8-h4a912ad_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/m2crypto-0.45.1-py314hdb6fb3f_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/mypy-1.19.1-py314hbdd0d06_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ncurses-6.5-h5e97a16_3.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/numpy-2.4.2-py314hae46ccb_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/openldap-2.6.10-hbe55e7a_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.6.1-hd24854e_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pcre2-10.47-h30297fc_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/perl-5.32.1-7_h4614cfb_perl5.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/psutil-7.2.2-py314ha14b1ff_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pugixml-1.15-hd3d436d_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/python-3.14.3-h4c637c5_100_cp314.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/python-gfal2-1.13.1-py314h5c1db39_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/python-librt-0.7.8-py314ha14b1ff_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyyaml-6.0.3-py314h6e9b3f0_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/readline-8.3-h46df422_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/rpds-py-0.30.0-py314haad56a0_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ruff-0.15.0-h279115b_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/scitokens-cpp-1.3.0-h608d757_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/srm-ifce-1.24.6-he0fb9dd_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/tk-8.6.13-h010d191_3.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ukkonen-1.1.0-py314h6cfcd04_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/xrootd-5.9.1-py314h6e96a01_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/yaml-0.2.5-h925e9cb_3.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/zlib-1.3.1-h8359307_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/zstd-1.5.7-hbf9d68e_6.conda + - pypi: . - pypi: git+https://gitlab.cern.ch/jlisalab/LHCbDIRAC.git?rev=modules-to-cwl-migration#bc5f8f1804107bc8807edcc98a97c346ef61c0e8 - - pypi: https://files.pythonhosted.org/packages/7f/37/8ea3555769b6048b5e4ec162cc90fd32e761c0e381ffb3baf888cb0d8a71/lhcbdiracx_api-0.0.8-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/68/15/bfb0c717b8f23c16907f3e73e8f56010ccd72e9900a108209665b0d9ed4b/lhcbdiracx_cli-0.0.8-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/2d/88/67602dfa2d7ab5d0518af82db34ab4d70dc2c3029b3ca788299a3be4a96d/lhcbdiracx_client-0.0.8-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/34/8f/6105afdd8f4e1f3b198d09e4b2622622923d9fa9e077aed852c0bb035a3a/lhcbdiracx_core-0.0.8-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b3/68/aa714515d65090fcbcc9a1f3debd5a644b14aad11e59238f42f00bd4b298/logzero-1.7.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/02/64/c86924898062e8217ed914a29458cfde9e4a9b80e4d4cbcca141983ba339/lbprodrun-1.12.4-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/03/15/d4a377b385ab693ce97b472fe0c77c2b16ec79590e688b3ccc71fba19884/lxml-6.0.2-cp314-cp314-macosx_10_13_universal2.whl - - pypi: https://files.pythonhosted.org/packages/94/54/e7d793b573f298e1c9013b8c4dade17d481164aa517d1d7148619c2cedbf/markdown_it_py-4.0.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/7a/f0/8282d9641415e9e33df173516226b404d367a0fc55e1a60424a152913abc/mistune-3.1.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/04/80/97b6f357ac458d9ad9872cc3183ca09ef7439ac89e030ea43053ba1294b6/rich_argparse-1.7.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/04/be/d09147ad1ec7934636ad912901c5fd7667e1c858e19d355237db0d0cd5e4/smmap-5.0.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0f/15/5bf3b99495fb160b63f95972b81750f18f7f4e02ad051373b669d17d44f2/aiohappyeyeballs-2.6.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/10/a1/510b0a7fadc6f43a6ce50152e69dbd86415240835868bb0bd9b5b88b1e06/aioitertools-0.13.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/10/bd/c038d7cc38edc1aa5bf91ab8068b63d4308c66c4c8bb3cbba7dfbc049f9c/pyparsing-3.3.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/11/63/ff458113c5c2dac9a9719ac68ee7c947cb621432bcf28c9972b1c0e83938/yarl-1.22.0-cp314-cp314-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/14/1b/a298b06749107c305e1fe0f814c6c74aea7b2f1e10989cb30f544a1b3253/python_dotenv-1.2.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/14/2f/967ba146e6d58cf6a652da73885f52fc68001525b4197effc174321d70b4/jmespath-1.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/15/aa/0aca39a37d3c7eb941ba736ede56d689e7be91cab5d9ca846bde3999eba6/isodate-0.7.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/18/d7/5dac2eb2ec75fd771957a13e5dda560efb2176d5203f39502a5fc571f899/xxhash-3.6.0-cp314-cp314-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/1a/39/47f9197bdd44df24d67ac8893641e16f386c984a0619ef2ee4c51fbbc019/beautifulsoup4-4.14.3-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/1b/9f/38ff9e57a2eade7bf9dfee5eae17f39fc0e998658050279cbb14d97d36d9/msgpack-1.1.2-cp314-cp314-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/f1/4f/733c48f270565d78b4544f2baddc2fb2a245e5a8640254b12c36ac7ac68e/multidict-6.7.1-cp314-cp314-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/9e/c9/b2622292ea83fbb4ec318f5b9ab867d0a28ab43c5717bb85b0a5f6b3b0a4/networkx-3.6.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/8e/eb/5da01e356015aee6ecfa1187ced87aef51364e306f5e695dd52719bf0e78/orjson-3.11.9-cp314-cp314-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl - - pypi: https://files.pythonhosted.org/packages/95/25/bdb9326c3b5455f8d4d3549fce7abcf967259de146fe2cf7a82368141948/pandas-3.0.2-cp314-cp314-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/a9/90/a744336f5af32c433bd09af7854599682a383b37cfd78f7de263de6ad6cb/paramiko-4.0.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/9e/c3/059298687310d527a58bb01f3b1965787ee3b40dce76752eda8b44e9a2c5/pexpect-4.9.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/84/03/0d3ce49e2505ae70cf43bc5bb3033955d2fc9f932163e84dc0779cc47f48/prompt_toolkit-3.0.52-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b2/fa/89a8ef0468d5833a23fff277b143d0573897cf75bd56670a6d28126c7d68/propcache-0.4.1-cp314-cp314-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/8e/fb/2c4c618185be2bda327f9dacd16b3122cc938809f19df7be840595d0e584/prov-1.5.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1e/db/4254e3eabe8020b458f1a747140d32277ec7a271daf1d235b70dc0b4e6e3/requests-2.32.5-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/22/a6/858897256d0deac81a172289110f31629fc4cee19b6f01283303e18c8db3/ptyprocess-0.7.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/28/df/2dd32cce20cbcf6f2ec456b58d44368161ad28320729f64e5e1d5d7bd0ae/cachetools-7.0.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2a/35/7051599bd493e62411d6ede36fd5af83a38f37c4767b92884df7301db25d/charset_normalizer-3.4.4-cp314-cp314-macosx_10_13_universal2.whl + - pypi: https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2d/88/67602dfa2d7ab5d0518af82db34ab4d70dc2c3029b3ca788299a3be4a96d/lhcbdiracx_client-0.0.8-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2d/e1/c2141f1840a41e07ad2db6f724945f8f8ff3065463899a22939152dd6e09/rapidfuzz-3.14.5-cp314-cp314-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/2e/54/647ade08bf0db230bfea292f893923872fd20be6ac6f53b2b936ba839d75/zipp-3.23.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/32/4b/b99e37f88336009971405cbb7630610322ed6fbfa31e1d7ab3fbf3049a2d/invoke-2.2.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/34/8f/6105afdd8f4e1f3b198d09e4b2622622923d9fa9e077aed852c0bb035a3a/lhcbdiracx_core-0.0.8-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/37/f9/f8497ef8b873a8bb2a750ee2a6c5f0fc22258e1acb6245fd237042a6c279/fabric-3.2.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/38/0e/27be9fdef66e72d64c0cdc3cc2823101b80585f8119b5c112c2e8f5f7dab/anyio-4.12.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/38/34/98a2f52245f4d47be93b580dae5f9861ef58977d73a79eb47c58f1ad1f3a/xmltodict-1.0.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/38/ee/a61bb562bdf6f0bc6c51cdcf80ab5503cbb4b2f5053fa4b054cc0a56e48a/python_gitlab-8.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/39/08/aaaad47bc4e9dc8c725e68f9d04865dbcb2052843ff09c97b08904852d84/urllib3-2.6.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3b/56/99a7cf6ca8533695874cf804369221d03bf5e869a7e0b38acbf4dbe8deeb/cwlformat-2022.2.18-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3c/c1/d73f12f8cdb1891334a2ccf7389eed244d3941e74d80dd220badb937f3fb/wcwidth-0.5.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3d/36/9ab4f0b5c3d10df3aceaecf7e395cabe7fb7c7c004b2dc3f3cff0ef70fc3/xattr-1.3.0-cp314-cp314-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/3f/51/d4db610ef29373b879047326cbf6fa98b6c1969d6f6dc423279de2b1be2c/requests_toolbelt-1.0.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/40/44/4a5f08c96eb108af5cb50b41f76142f0afa346dfa99d5296fe7202a11854/tabulate-0.9.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/44/b5/a96872e5184f354da9c84ae119971a0a4c221fe9b27a4d94bd43f2596727/pyasn1-0.6.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/46/2c/1462b1d0a634697ae9e55b3cecdcb64788e8b7d63f54d923fcd0bb140aed/soupsieve-2.8.3-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/47/8d/d529b5d697919ba8c11ad626e835d4039be708a35b0d22de83a269a6682c/pyasn1_modules-0.4.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/4e/8c/f3147f5c4b73e7550fe5f9352eaa956ae838d5c51eb58e7a25b9f3e2643b/decorator-5.2.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/54/51/321e821856452f7386c4e9df866f196720b1ad0c5ea1623ea7399969ae3b/authlib-1.6.6-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/58/19/0380af745f151a1648657bbcef0fb49ac28bf09083d94498163ffd9b32dc/dominate-2.9.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/59/25/68f81c50aeb3f30e01c20da0f56d14c1a779b57d9308c50e19c63dc8413f/signurlarity-0.2.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5a/36/17015b7bae2783f7bbde50a8bafdeb702802c080322204f1bfcae25b9e02/DB12-1.0.4-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/5a/87/b70ad306ebb6f9b585f114d0ac2137d792b48be34d732d60e597c2f8465a/pydantic-2.12.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5c/48/ccd6c49477674389d55b5b5520e47d1290f4c29686c36f5674f4a7aced00/rucio_clients-39.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5d/ba/2af136406e1c3839aea9ecadc2f6be2bcd1eff255bd451dd39bcf302c47a/bcrypt-5.0.0-cp39-abi3-macosx_10_12_universal2.whl + - pypi: https://files.pythonhosted.org/packages/5e/0a/3966f239e1d9da93cb755dc0213835ce4e9ed93645192878d0a055ecdc31/boto3-1.42.42-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5f/e8/2e6301567e6debaad6abae0e217428471651ce877537b7095b6a8e7d8cd2/fts3-3.14.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/63/4b/ccab2a5ca9e0b6553810b85c06387e60fc9443cec3c987e3a062705bd225/cwl_utils-0.40-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/65/ee/a7aba2b112c5ae879d5cfb231c75189a7fd2a5e84b6af7e07dd71fb2bb35/cwltool-3.1.20260108082145-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/68/15/bfb0c717b8f23c16907f3e73e8f56010ccd72e9900a108209665b0d9ed4b/lhcbdiracx_cli-0.0.8-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/69/f2/c4cec0a30f1955510fde498aac451d2e52b24afdbcb00204d3a951b772c3/ruamel_yaml_clib-0.2.15-cp314-cp314-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/6a/09/e21df6aef1e1ffc0c816f0522ddc3f6dcded766c3261813131c78a704470/gitpython-3.1.46-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/6d/10/b37ac718c5903758fa9058a5182026a4f3b65443196b82c7840389ea0dbd/lbplatformutils-4.6.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/6f/01/c26ce75ba460d5cd503da9e13b21a33804d38c2165dec7b716d06b13010c/pyjwt-2.11.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/70/98/d82f14ac7ffedbd38dfa2383f142b26d18d23ca6cf35a40f4af60df666bd/sh-2.2.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/71/3f/212e32937253312e102e152c954a5495df0379255719ce28e0288194748d/schema_salad-8.9.20251102115403-cp314-cp314-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/73/90/a2c51050d9254bd9134e6368b3f94f92f0eb2c34ed0ca19ec449ce2fc288/fsspec_xrootd-0.5.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/74/1a/145646e5687e8d9a1e8d09acb278c8535ebe9e972e1f162ed338a622f193/pydantic_core-2.41.5-cp314-cp314-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/c1/60/5d4751ba3f4a40a6891f24eec885f51afd78d208498268c734e256fb13c4/pydantic_settings-2.12.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/74/f5/9373290775639cb67a2fce7f629a1c240dce9f12fe927bc32b2736e16dfc/argcomplete-3.6.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/76/2c/bb6ef359e007fe7b6b3195b68a94f4dd3ecd1885ee337ee8fbd4df55996f/levenshtein-0.27.3-cp314-cp314-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/77/39/4d8414260c3d83f22029a39e51553c173611b378d62ca391e5ca68e65cfa/awkward-2.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/7a/f0/8282d9641415e9e33df173516226b404d367a0fc55e1a60424a152913abc/mistune-3.1.4-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/7e/32/a7125fb28c4261a627f999d5fb4afff25b523800faed2c30979949d6facd/pydot-4.0.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/6f/01/c26ce75ba460d5cd503da9e13b21a33804d38c2165dec7b716d06b13010c/pyjwt-2.11.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/be/7b/4845bbf88e94586ec47a432da4e9107e3fc3ce37eb412b1398630a37f7dd/pynacl-1.6.2-cp38-abi3-macosx_10_10_universal2.whl - - pypi: https://files.pythonhosted.org/packages/10/bd/c038d7cc38edc1aa5bf91ab8068b63d4308c66c4c8bb3cbba7dfbc049f9c/pyparsing-3.3.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/14/1b/a298b06749107c305e1fe0f814c6c74aea7b2f1e10989cb30f544a1b3253/python_dotenv-1.2.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/38/ee/a61bb562bdf6f0bc6c51cdcf80ab5503cbb4b2f5053fa4b054cc0a56e48a/python_gitlab-8.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/7f/37/8ea3555769b6048b5e4ec162cc90fd32e761c0e381ffb3baf888cb0d8a71/lhcbdiracx_api-0.0.8-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/81/c4/34e93fe5f5429d7570ec1fa436f1986fb1f00c3e0f43a589fe2bbcd22c3f/pytz-2025.2-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/2d/e1/c2141f1840a41e07ad2db6f724945f8f8ff3065463899a22939152dd6e09/rapidfuzz-3.14.5-cp314-cp314-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/b9/20/35d2baebacf357b562bd081936b66cd845775442973cb033a377fd639a84/rdflib-7.5.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/1e/db/4254e3eabe8020b458f1a747140d32277ec7a271daf1d235b70dc0b4e6e3/requests-2.32.5-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/3f/51/d4db610ef29373b879047326cbf6fa98b6c1969d6f6dc423279de2b1be2c/requests_toolbelt-1.0.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ef/45/615f5babd880b4bd7d405cc0dc348234c5ffb6ed1ea33e152ede08b2072d/rich-14.3.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/04/80/97b6f357ac458d9ad9872cc3183ca09ef7439ac89e030ea43053ba1294b6/rich_argparse-1.7.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/84/03/0d3ce49e2505ae70cf43bc5bb3033955d2fc9f932163e84dc0779cc47f48/prompt_toolkit-3.0.52-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/84/d0/205d54408c08b13550c733c4b85429e7ead111c7f0014309637425520a9a/deprecated-1.3.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/87/a4/afc9dddc6b14fb3d52a900cd9b4c77770128edc4b07e576034bbd0ffd290/LbCondaWrappers-0.5.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/8d/09/d0a2a14fc3439c5f874042dca72a79c70a532090b7ba0003be73fee37ae2/zstandard-0.25.0-cp314-cp314-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/8d/99/157aae7949a5f30d51fcb1a9851e8ebd5c74bf99b5285d8bb4b8b9ee641e/cryptography-46.0.4-cp311-abi3-macosx_10_9_universal2.whl + - pypi: https://files.pythonhosted.org/packages/8e/eb/5da01e356015aee6ecfa1187ced87aef51364e306f5e695dd52719bf0e78/orjson-3.11.9-cp314-cp314-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl + - pypi: https://files.pythonhosted.org/packages/8e/fb/2c4c618185be2bda327f9dacd16b3122cc938809f19df7be840595d0e584/prov-1.5.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/94/54/e7d793b573f298e1c9013b8c4dade17d481164aa517d1d7148619c2cedbf/markdown_it_py-4.0.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/95/25/bdb9326c3b5455f8d4d3549fce7abcf967259de146fe2cf7a82368141948/pandas-3.0.2-cp314-cp314-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/98/78/01c019cdb5d6498122777c1a43056ebb3ebfeef2076d9d026bfe15583b2b/click-8.3.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9e/c3/059298687310d527a58bb01f3b1965787ee3b40dce76752eda8b44e9a2c5/pexpect-4.9.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9e/c9/b2622292ea83fbb4ec318f5b9ab867d0a28ab43c5717bb85b0a5f6b3b0a4/networkx-3.6.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9f/90/279f55fff9481f9e0424c3c97b24dc10004ec8d8f98ddf5afd07a7b79194/diraccfg-1.0.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a0/1d/d9257dd49ff2ca23ea5f132edf1281a0c4f9de8a762b9ae399b670a59235/typer-0.21.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a0/61/5c78b91c3143ed5c14207f463aecfc8f9dbb5092fb2869baf37c273b2705/gitdb-4.0.12-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a1/01/9674cc6d478406ae61d910cb16ca8b5699a8a9e6a2019987ebe5a5957d1d/joserfc-1.6.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a1/93/72b1736d68f03fda5fdf0f2180fb6caaae3894f1b854d006ac61ecc727ee/frozenlist-1.8.0-cp314-cp314-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/a4/ed/1f1afb2e9e7f38a545d628f864d562a5ae64fe6f7a10e28ffb9b185b4e89/importlib_resources-6.5.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a7/06/3d6badcf13db419e25b07041d9c7b4a2c331d3f4e7134445ec5df57714cd/coloredlogs-15.0.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a9/90/a744336f5af32c433bd09af7854599682a383b37cfd78f7de263de6ad6cb/paramiko-4.0.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ab/7e/5f02b757bb825e5cdc65f6f7a12c209963bec877d61497393bea8f41f9ce/diracx_api-0.0.8-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/af/fe/b6045c782f1fd1ae317d2a6ca1884857ce5c20f59befe6ab25a8603c43a7/ruamel_yaml-0.18.17-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/69/f2/c4cec0a30f1955510fde498aac451d2e52b24afdbcb00204d3a951b772c3/ruamel_yaml_clib-0.2.15-cp314-cp314-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/5c/48/ccd6c49477674389d55b5b5520e47d1290f4c29686c36f5674f4a7aced00/rucio_clients-39.2.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/fc/51/727abb13f44c1fcf6d145979e1535a35794db0f6e450a0cb46aa24732fe2/s3transfer-0.16.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/71/3f/212e32937253312e102e152c954a5495df0379255719ce28e0288194748d/schema_salad-8.9.20251102115403-cp314-cp314-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/70/98/d82f14ac7ffedbd38dfa2383f142b26d18d23ca6cf35a40f4af60df666bd/sh-2.2.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e0/f9/0595336914c5619e5f28a1fb793285925a8cd4b432c9da0a987836c7f822/shellingham-1.5.4-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/59/25/68f81c50aeb3f30e01c20da0f56d14c1a779b57d9308c50e19c63dc8413f/signurlarity-0.2.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b0/28/87e78ff0d6041f40431d88b8aa3b645be7476a420d8dcbf7197f5b394c5c/diracx_cli-0.0.8-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b0/57/dea471da24ceac6de8c3dc5d37e4ddde57a5c340d6bac90010898734de34/gitlint_core-0.19.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b0/9a/d2faba7e61072a7507b5722db63562fdb22f5a24e237d460d18755627f15/wrapt-2.1.1-cp314-cp314-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/b2/c9/459da97eb93fad89738951972671d44be197610242b8da88a0384791ea7e/diracx_core-0.0.8-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b2/fa/89a8ef0468d5833a23fff277b143d0573897cf75bd56670a6d28126c7d68/propcache-0.4.1-cp314-cp314-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b3/68/aa714515d65090fcbcc9a1f3debd5a644b14aad11e59238f42f00bd4b298/logzero-1.7.0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/04/be/d09147ad1ec7934636ad912901c5fd7667e1c858e19d355237db0d0cd5e4/smmap-5.0.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/46/2c/1462b1d0a634697ae9e55b3cecdcb64788e8b7d63f54d923fcd0bb140aed/soupsieve-2.8.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/f9/38/8b6fc7a8153cb49eb3a9a13acfa9eeb6cc476e37888781e593e6f02ac05e/spython-0.3.14-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e9/f8/5ecdfc73383ec496de038ed1614de9e740a82db9ad67e6e4514ebc0708a3/sqlalchemy-2.0.46-cp314-cp314-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/f4/40/8561ce06dc46fd17242c7724ab25b257a2ac1b35f4ebf551b40ce6105cfa/stevedore-5.6.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/40/44/4a5f08c96eb108af5cb50b41f76142f0afa346dfa99d5296fe7202a11854/tabulate-0.9.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a0/1d/d9257dd49ff2ca23ea5f132edf1281a0c4f9de8a762b9ae399b670a59235/typer-0.21.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/dc/9b/47798a6c91d8bdb567fe2698fe81e0c6b7cb7ef4d13da4114b41d239f65d/typing_inspection-0.4.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c7/b0/003792df09decd6849a5e39c28b513c06e84436a54440380862b5aeff25d/tzdata-2025.3-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b9/20/35d2baebacf357b562bd081936b66cd845775442973cb033a377fd639a84/rdflib-7.5.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ba/24/c65fe1aef4e0681cb17ca136eb0f3e20a47d3941a306bc9d636938029ca5/lb_telemetry-0.5.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ba/5a/18ad964b0086c6e62e2e7500f7edc89e3faa45033c71c1893d34eed2b2de/dnspython-2.8.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/be/7b/4845bbf88e94586ec47a432da4e9107e3fc3ce37eb412b1398630a37f7dd/pynacl-1.6.2-cp38-abi3-macosx_10_10_universal2.whl + - pypi: https://files.pythonhosted.org/packages/c1/60/5d4751ba3f4a40a6891f24eec885f51afd78d208498268c734e256fb13c4/pydantic_settings-2.12.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/c4/55/85e2732345dd8b66437cddedac4ee7ef2d9c25bf8792830b095f2ee658f3/uproot-5.7.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/39/08/aaaad47bc4e9dc8c725e68f9d04865dbcb2052843ff09c97b08904852d84/urllib3-2.6.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/3c/c1/d73f12f8cdb1891334a2ccf7389eed244d3941e74d80dd220badb937f3fb/wcwidth-0.5.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b0/9a/d2faba7e61072a7507b5722db63562fdb22f5a24e237d460d18755627f15/wrapt-2.1.1-cp314-cp314-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/3d/36/9ab4f0b5c3d10df3aceaecf7e395cabe7fb7c7c004b2dc3f3cff0ef70fc3/xattr-1.3.0-cp314-cp314-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/c7/b0/003792df09decd6849a5e39c28b513c06e84436a54440380862b5aeff25d/tzdata-2025.3-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/ca/6d/b1a49f9712a910acdcb8dc5765e57d60c2be9fe9b001a21b6a98a1d85adb/xenv-0.0.6-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/38/34/98a2f52245f4d47be93b580dae5f9861ef58977d73a79eb47c58f1ad1f3a/xmltodict-1.0.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/18/d7/5dac2eb2ec75fd771957a13e5dda560efb2176d5203f39502a5fc571f899/xxhash-3.6.0-cp314-cp314-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/11/63/ff458113c5c2dac9a9719ac68ee7c947cb621432bcf28c9972b1c0e83938/yarl-1.22.0-cp314-cp314-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/2e/54/647ade08bf0db230bfea292f893923872fd20be6ac6f53b2b936ba839d75/zipp-3.23.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/8d/09/d0a2a14fc3439c5f874042dca72a79c70a532090b7ba0003be73fee37ae2/zstandard-0.25.0-cp314-cp314-macosx_11_0_arm64.whl - - pypi: ./ + - pypi: https://files.pythonhosted.org/packages/cd/22/4d16dca3bd1d6475a53063eb72150269cea1a0a201b55288b3402f61f119/aiobotocore-3.1.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d0/d0/9e71fdc3394ffc632f35946c572e60fcc2a5452ba0a23c52493f23d60672/dirac-9.1.6-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d5/1f/5f4a3cd9e4440e9d9bc78ad0a91a1c8d46b4d429d5239ebe6793c9fe5c41/fsspec-2026.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d7/4c/f3b97c7d6008b3a895bbadb2deb44ad3446ae5fe204c72cd540dc222e57d/lbenv-2.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d8/da/a8bb48a4fee86b5dad8a358559b70b010cd7effaa70ca5bb4e6e82e13703/hyperscan-0.8.2-cp314-cp314-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/db/2b/1239938a2629c29363e07724d7bd4c87a8b566947ecee2afb5f5ac34e1bb/cwl_upgrader-1.2.14-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/dc/80/12235e5b75bb2c586733280854f131b86051e0bbdfb55349ff70d0f72cf9/dogpile_cache-1.5.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/dc/9b/47798a6c91d8bdb567fe2698fe81e0c6b7cb7ef4d13da4114b41d239f65d/typing_inspection-0.4.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/de/07/a1051cdbbe6d723df16d756b97f09da7c1adb69e29695c58f0392bc12515/cramjam-2.11.0-cp314-cp314-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl + - pypi: https://files.pythonhosted.org/packages/de/15/545e2b6cf2e3be84bc1ed85613edd75b8aea69807a71c26f4ca6a9258e82/email_validator-2.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e0/f9/0595336914c5619e5f28a1fb793285925a8cd4b432c9da0a987836c7f822/shellingham-1.5.4-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e6/51/aac7e419521d5519e13087a7198623655648c939822bd7f4bdc9ccbe07f9/botocore-1.42.42-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e6/ad/3cc14f097111b4de0040c83a525973216457bbeeb63739ef1ed275c1c021/certifi-2026.1.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e8/0b/b97660c5fd05d3495b4eb27f2d0ef18dc1dc4eff7511a9bf371397ff0264/aiohttp-3.13.3-cp314-cp314-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/e9/f8/5ecdfc73383ec496de038ed1614de9e740a82db9ad67e6e4514ebc0708a3/sqlalchemy-2.0.46-cp314-cp314-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ed/c9/d7977eaacb9df673210491da99e6a247e93df98c715fc43fd136ce1d3d33/arrow-1.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ef/45/615f5babd880b4bd7d405cc0dc348234c5ffb6ed1ea33e152ede08b2072d/rich-14.3.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ef/79/c45f2d53efe6ada1110cf6f9fca095e4ff47a0454444aefdde6ac4789179/cachecontrol-0.14.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f0/0f/310fb31e39e2d734ccaa2c0fb981ee41f7bd5056ce9bc29b2248bd569169/humanfriendly-10.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f1/4f/733c48f270565d78b4544f2baddc2fb2a245e5a8640254b12c36ac7ac68e/multidict-6.7.1-cp314-cp314-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/f2/61/0c78d9778bffd844863d3173a5fefb506d7131ceebecee523a9e27024aa1/diracx_client-0.0.8-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f4/40/8561ce06dc46fd17242c7724ab25b257a2ac1b35f4ebf551b40ce6105cfa/stevedore-5.6.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f8/b2/ad8e7e63fdf5add3ceb7a0805d700e9fd7cb7d5743f765a4994b4ec286d7/diraccommon-9.1.6-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f9/38/8b6fc7a8153cb49eb3a9a13acfa9eeb6cc476e37888781e593e6f02ac05e/spython-0.3.14-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fa/5e/f8e9a1d23b9c20a551a8a02ea3637b4642e22c2626e3a13a9a29cdea99eb/importlib_metadata-8.7.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fb/b9/0978fa6f21f504b617ccee4843210d7ab8921a10e94e3bbf084498dcfad7/awkward_cpp-52-cp314-cp314-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/fc/51/727abb13f44c1fcf6d145979e1535a35794db0f6e450a0cb46aa24732fe2/s3transfer-0.16.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fc/d8/b8fcba9464f02b121f39de2db2bf57f0b216fe11d014513d666e8634380d/azure_core-1.38.0-py3-none-any.whl packages: - conda: https://conda.anaconda.org/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.tar.bz2 sha256: fe51de6107f9edc7aa4f786a70f4a883943bc9d39b3bb7307c04c41410990726 @@ -766,2801 +770,1932 @@ packages: purls: [] size: 23621 timestamp: 1650670423406 -- conda: https://conda.anaconda.org/conda-forge/osx-64/_openmp_mutex-4.5-7_kmp_llvm.conda - build_number: 7 - sha256: 30006902a9274de8abdad5a9f02ef7c8bb3d69a503486af0c1faee30b023e5b7 - md5: eaac87c21aff3ed21ad9656697bb8326 +- conda: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_8.conda + sha256: c30daba32ddebbb7ded490f0e371eae90f51e72db620554089103b4a6934b0d5 + md5: 51a19bba1b8ebfb60df25cde030b7ebc depends: - - llvm-openmp >=9.0.1 - license: BSD-3-Clause + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + license: bzip2-1.0.6 license_family: BSD purls: [] - size: 8328 - timestamp: 1764092562779 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/_openmp_mutex-4.5-7_kmp_llvm.conda - build_number: 7 - sha256: 7acaa2e0782cad032bdaf756b536874346ac1375745fb250e9bdd6a48a7ab3cd - md5: a44032f282e7d2acdeb1c240308052dd + size: 260341 + timestamp: 1757437258798 +- conda: https://conda.anaconda.org/conda-forge/linux-64/c-ares-1.34.6-hb03c661_0.conda + sha256: cc9accf72fa028d31c2a038460787751127317dcfa991f8d1f1babf216bb454e + md5: 920bb03579f15389b9e512095ad995b7 depends: - - llvm-openmp >=9.0.1 - license: BSD-3-Clause - license_family: BSD + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + license: MIT + license_family: MIT purls: [] - size: 8325 - timestamp: 1764092507920 -- pypi: https://files.pythonhosted.org/packages/cd/22/4d16dca3bd1d6475a53063eb72150269cea1a0a201b55288b3402f61f119/aiobotocore-3.1.2-py3-none-any.whl - name: aiobotocore - version: 3.1.2 - sha256: 1141cec16c47cc3e466d89fcccc5c57291a3751a15488fe7fbaea8550f94f468 - requires_dist: - - aiohttp>=3.12.0,<4.0.0 - - aioitertools>=0.5.1,<1.0.0 - - botocore>=1.41.0,<1.42.43 - - python-dateutil>=2.1,<3.0.0 - - jmespath>=0.7.1,<2.0.0 - - multidict>=6.0.0,<7.0.0 - - typing-extensions>=4.14.0,<5.0.0 ; python_full_version < '3.11' - - wrapt>=1.10.10,<3.0.0 - - httpx>=0.25.1,<0.29 ; extra == 'httpx' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/0f/15/5bf3b99495fb160b63f95972b81750f18f7f4e02ad051373b669d17d44f2/aiohappyeyeballs-2.6.1-py3-none-any.whl - name: aiohappyeyeballs - version: 2.6.1 - sha256: f349ba8f4b75cb25c99c5c2d84e997e485204d2902a9597802b0371f09331fb8 - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/e3/d1/e30e537a15f53485b61f5be525f2157da719819e8377298502aebac45536/aiohttp-3.13.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - name: aiohttp - version: 3.13.3 - sha256: bbe7d4cecacb439e2e2a8a1a7b935c25b812af7a5fd26503a66dadf428e79ec1 - requires_dist: - - aiohappyeyeballs>=2.5.0 - - aiosignal>=1.4.0 - - async-timeout>=4.0,<6.0 ; python_full_version < '3.11' - - attrs>=17.3.0 - - frozenlist>=1.1.1 - - multidict>=4.5,<7.0 - - propcache>=0.2.0 - - yarl>=1.17.0,<2.0 - - aiodns>=3.3.0 ; extra == 'speedups' - - brotli>=1.2 ; platform_python_implementation == 'CPython' and extra == 'speedups' - - brotlicffi>=1.2 ; platform_python_implementation != 'CPython' and extra == 'speedups' - - backports-zstd ; python_full_version < '3.14' and platform_python_implementation == 'CPython' and extra == 'speedups' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/e8/0b/b97660c5fd05d3495b4eb27f2d0ef18dc1dc4eff7511a9bf371397ff0264/aiohttp-3.13.3-cp314-cp314-macosx_11_0_arm64.whl - name: aiohttp - version: 3.13.3 - sha256: c685f2d80bb67ca8c3837823ad76196b3694b0159d232206d1e461d3d434666f - requires_dist: - - aiohappyeyeballs>=2.5.0 - - aiosignal>=1.4.0 - - async-timeout>=4.0,<6.0 ; python_full_version < '3.11' - - attrs>=17.3.0 - - frozenlist>=1.1.1 - - multidict>=4.5,<7.0 - - propcache>=0.2.0 - - yarl>=1.17.0,<2.0 - - aiodns>=3.3.0 ; extra == 'speedups' - - brotli>=1.2 ; platform_python_implementation == 'CPython' and extra == 'speedups' - - brotlicffi>=1.2 ; platform_python_implementation != 'CPython' and extra == 'speedups' - - backports-zstd ; python_full_version < '3.14' and platform_python_implementation == 'CPython' and extra == 'speedups' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/f7/49/459327f0d5bcd8c6c9ca69e60fdeebc3622861e696490d8674a6d0cb90a6/aiohttp-3.13.3-cp314-cp314-macosx_10_13_x86_64.whl - name: aiohttp - version: 3.13.3 - sha256: 6fc0e2337d1a4c3e6acafda6a78a39d4c14caea625124817420abceed36e2415 - requires_dist: - - aiohappyeyeballs>=2.5.0 - - aiosignal>=1.4.0 - - async-timeout>=4.0,<6.0 ; python_full_version < '3.11' - - attrs>=17.3.0 - - frozenlist>=1.1.1 - - multidict>=4.5,<7.0 - - propcache>=0.2.0 - - yarl>=1.17.0,<2.0 - - aiodns>=3.3.0 ; extra == 'speedups' - - brotli>=1.2 ; platform_python_implementation == 'CPython' and extra == 'speedups' - - brotlicffi>=1.2 ; platform_python_implementation != 'CPython' and extra == 'speedups' - - backports-zstd ; python_full_version < '3.14' and platform_python_implementation == 'CPython' and extra == 'speedups' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/10/a1/510b0a7fadc6f43a6ce50152e69dbd86415240835868bb0bd9b5b88b1e06/aioitertools-0.13.0-py3-none-any.whl - name: aioitertools - version: 0.13.0 - sha256: 0be0292b856f08dfac90e31f4739432f4cb6d7520ab9eb73e143f4f2fa5259be - requires_dist: - - typing-extensions>=4.0 ; python_full_version < '3.10' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl - name: aiosignal - version: 1.4.0 - sha256: 053243f8b92b990551949e63930a839ff0cf0b0ebbe0597b0f3fb19e1a0fe82e - requires_dist: - - frozenlist>=1.1.0 - - typing-extensions>=4.2 ; python_full_version < '3.13' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl - name: annotated-types - version: 0.7.0 - sha256: 1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53 - requires_dist: - - typing-extensions>=4.0.0 ; python_full_version < '3.9' - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/38/0e/27be9fdef66e72d64c0cdc3cc2823101b80585f8119b5c112c2e8f5f7dab/anyio-4.12.1-py3-none-any.whl - name: anyio - version: 4.12.1 - sha256: d405828884fc140aa80a3c667b8beed277f1dfedec42ba031bd6ac3db606ab6c - requires_dist: - - exceptiongroup>=1.0.2 ; python_full_version < '3.11' - - idna>=2.8 - - typing-extensions>=4.5 ; python_full_version < '3.13' - - trio>=0.32.0 ; python_full_version >= '3.10' and extra == 'trio' - - trio>=0.31.0 ; python_full_version < '3.10' and extra == 'trio' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/74/f5/9373290775639cb67a2fce7f629a1c240dce9f12fe927bc32b2736e16dfc/argcomplete-3.6.3-py3-none-any.whl - name: argcomplete - version: 3.6.3 - sha256: f5007b3a600ccac5d25bbce33089211dfd49eab4a7718da3f10e3082525a92ce - requires_dist: - - coverage ; extra == 'test' - - mypy ; extra == 'test' - - pexpect ; extra == 'test' - - ruff ; extra == 'test' - - wheel ; extra == 'test' - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/ed/c9/d7977eaacb9df673210491da99e6a247e93df98c715fc43fd136ce1d3d33/arrow-1.4.0-py3-none-any.whl - name: arrow - version: 1.4.0 - sha256: 749f0769958ebdc79c173ff0b0670d59051a535fa26e8eba02953dc19eb43205 - requires_dist: - - python-dateutil>=2.7.0 - - backports-zoneinfo==0.2.1 ; python_full_version < '3.9' - - tzdata ; python_full_version >= '3.9' - - doc8 ; extra == 'doc' - - sphinx>=7.0.0 ; extra == 'doc' - - sphinx-autobuild ; extra == 'doc' - - sphinx-autodoc-typehints ; extra == 'doc' - - sphinx-rtd-theme>=1.3.0 ; extra == 'doc' - - dateparser==1.* ; extra == 'test' - - pre-commit ; extra == 'test' - - pytest ; extra == 'test' - - pytest-cov ; extra == 'test' - - pytest-mock ; extra == 'test' - - pytz==2025.2 ; extra == 'test' - - simplejson==3.* ; extra == 'test' - requires_python: '>=3.8' -- conda: https://conda.anaconda.org/conda-forge/noarch/attrs-25.4.0-pyhcf101f3_1.conda - sha256: c13d5e42d187b1d0255f591b7ce91201d4ed8a5370f0d986707a802c20c9d32f - md5: 537296d57ea995666c68c821b00e360b + size: 207882 + timestamp: 1765214722852 +- conda: https://conda.anaconda.org/conda-forge/linux-64/cffi-2.0.0-py314h4a8dc5f_1.conda + sha256: c6339858a0aaf5d939e00d345c98b99e4558f285942b27232ac098ad17ac7f8e + md5: cf45f4278afd6f4e6d03eda0f435d527 depends: - - python >=3.10 - - python + - __glibc >=2.17,<3.0.a0 + - libffi >=3.5.2,<3.6.0a0 + - libgcc >=14 + - pycparser + - python >=3.14,<3.15.0a0 + - python_abi 3.14.* *_cp314 license: MIT license_family: MIT purls: - - pkg:pypi/attrs?source=compressed-mapping - size: 64759 - timestamp: 1764875182184 -- pypi: https://files.pythonhosted.org/packages/54/51/321e821856452f7386c4e9df866f196720b1ad0c5ea1623ea7399969ae3b/authlib-1.6.6-py2.py3-none-any.whl - name: authlib - version: 1.6.6 - sha256: 7d9e9bc535c13974313a87f53e8430eb6ea3d1cf6ae4f6efcd793f2e949143fd - requires_dist: - - cryptography - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/77/39/4d8414260c3d83f22029a39e51553c173611b378d62ca391e5ca68e65cfa/awkward-2.9.0-py3-none-any.whl - name: awkward - version: 2.9.0 - sha256: 4859e371c606ca7fe737546f302de08110d53ed986cdd1254fb059dd48912db6 - requires_dist: - - awkward-cpp==52 - - fsspec>=2022.11.0 - - importlib-metadata>=4.13.0 ; python_full_version < '3.12' - - numpy>=1.21.3 - - packaging - - typing-extensions>=4.1.0 ; python_full_version < '3.11' - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/9a/02/0e550c9606ffae81603a9d240369a93cdf1e4bc48e2e314d367825a1c02d/awkward_cpp-52-cp314-cp314-macosx_10_15_x86_64.whl - name: awkward-cpp - version: '52' - sha256: d792c969c5261d8141c0b817a6a541849355b0fafe49e6e63a542a501cc0b73a - requires_dist: - - numpy>=1.21.3 - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/ca/aa/ab2d6d68c3ee50f6dedbbc91a31cd38f9fede9258d54e7aca29bfca4ebc1/awkward_cpp-52-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl - name: awkward-cpp - version: '52' - sha256: bbfd5745b59684a044c91394d7c1c5a82bac204ed9ef6125f37ffe35aa719e2b - requires_dist: - - numpy>=1.21.3 - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/fb/b9/0978fa6f21f504b617ccee4843210d7ab8921a10e94e3bbf084498dcfad7/awkward_cpp-52-cp314-cp314-macosx_11_0_arm64.whl - name: awkward-cpp - version: '52' - sha256: 626e75125267c7ce51fdb891fa628e7cf3ea9c37df19126e25dd9587917f94ab - requires_dist: - - numpy>=1.21.3 - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/fc/d8/b8fcba9464f02b121f39de2db2bf57f0b216fe11d014513d666e8634380d/azure_core-1.38.0-py3-none-any.whl - name: azure-core - version: 1.38.0 - sha256: ab0c9b2cd71fecb1842d52c965c95285d3cfb38902f6766e4a471f1cd8905335 - requires_dist: - - requests>=2.21.0 - - typing-extensions>=4.6.0 - - aiohttp>=3.0 ; extra == 'aio' - - opentelemetry-api~=1.26 ; extra == 'tracing' - requires_python: '>=3.9' -- conda: https://conda.anaconda.org/conda-forge/noarch/backports.asyncio.runner-1.2.0-pyh5ded981_2.conda - sha256: 2ade43752e8494f110a2cfb9e4d5b1ea29e3dcb037fba63395442d00371e8bf9 - md5: 0fd7e45c862b3305226a992f9f7b204a + - pkg:pypi/cffi?source=hash-mapping + size: 300271 + timestamp: 1761203085220 +- conda: https://conda.anaconda.org/conda-forge/linux-64/cgsi-gsoap-1.3.12-h32d023c_0.conda + sha256: 65fc6650c5d7ca754b0a4ea344df089bbf19ca0b76c89dcdb9ede7a6065f8673 + md5: f86a805cdeb4c3b89ad8b538f635cdeb depends: - - python >=3.11 - - python - constrains: - - python >=3.11 - license: PSF-2.0 - license_family: PSF + - __glibc >=2.17,<3.0.a0 + - gct >=6.2.1705709074,<6.2.1705709075.0a0 + - gsoap >=2.8.123,<2.8.124.0a0 + - libgcc >=12 + - libstdcxx >=12 + - openssl >=3.4.0,<4.0a0 + - voms + license: Apache-2.0 + license_family: Apache purls: [] - size: 10186 - timestamp: 1753456386827 -- pypi: https://files.pythonhosted.org/packages/24/b4/11f8a31d8b67cca3371e046db49baa7c0594d71eb40ac8121e2fc0888db0/bcrypt-5.0.0-cp39-abi3-manylinux_2_28_x86_64.whl - name: bcrypt - version: 5.0.0 - sha256: f8429e1c410b4073944f03bd778a9e066e7fad723564a52ff91841d278dfc822 - requires_dist: - - pytest>=3.2.1,!=3.3.0 ; extra == 'tests' - - mypy ; extra == 'typecheck' - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/5d/ba/2af136406e1c3839aea9ecadc2f6be2bcd1eff255bd451dd39bcf302c47a/bcrypt-5.0.0-cp39-abi3-macosx_10_12_universal2.whl - name: bcrypt - version: 5.0.0 - sha256: 0c418ca99fd47e9c59a301744d63328f17798b5947b0f791e9af3c1c499c2d0a - requires_dist: - - pytest>=3.2.1,!=3.3.0 ; extra == 'tests' - - mypy ; extra == 'typecheck' - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/1a/39/47f9197bdd44df24d67ac8893641e16f386c984a0619ef2ee4c51fbbc019/beautifulsoup4-4.14.3-py3-none-any.whl - name: beautifulsoup4 - version: 4.14.3 - sha256: 0918bfe44902e6ad8d57732ba310582e98da931428d231a5ecb9e7c703a735bb - requires_dist: - - soupsieve>=1.6.1 - - typing-extensions>=4.0.0 - - cchardet ; extra == 'cchardet' - - chardet ; extra == 'chardet' - - charset-normalizer ; extra == 'charset-normalizer' - - html5lib ; extra == 'html5lib' - - lxml ; extra == 'lxml' - requires_python: '>=3.7.0' -- pypi: https://files.pythonhosted.org/packages/5e/0a/3966f239e1d9da93cb755dc0213835ce4e9ed93645192878d0a055ecdc31/boto3-1.42.42-py3-none-any.whl - name: boto3 - version: 1.42.42 - sha256: 8c78169ef47dc29863ebb11ba99134b1b418d3dfdd836419830f22552f8afe43 - requires_dist: - - botocore>=1.42.42,<1.43.0 - - jmespath>=0.7.1,<2.0.0 - - s3transfer>=0.16.0,<0.17.0 - - botocore[crt]>=1.21.0,<2.0a0 ; extra == 'crt' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/e6/51/aac7e419521d5519e13087a7198623655648c939822bd7f4bdc9ccbe07f9/botocore-1.42.42-py3-none-any.whl - name: botocore - version: 1.42.42 - sha256: 1c9df5fc31e9073a9aa956271c4007d72f5d342cafca5f4154ea099bc6f83085 - requires_dist: - - jmespath>=0.7.1,<2.0.0 - - python-dateutil>=2.1,<3.0.0 - - urllib3>=1.25.4,<1.27 ; python_full_version < '3.10' - - urllib3>=1.25.4,!=2.2.0,<3 ; python_full_version >= '3.10' - - awscrt==0.29.2 ; extra == 'crt' - requires_python: '>=3.9' -- conda: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_8.conda - sha256: c30daba32ddebbb7ded490f0e371eae90f51e72db620554089103b4a6934b0d5 - md5: 51a19bba1b8ebfb60df25cde030b7ebc + size: 46998 + timestamp: 1738622766217 +- conda: https://conda.anaconda.org/conda-forge/linux-64/cyrus-sasl-2.1.28-hd9c7081_0.conda + sha256: ee09ad7610c12c7008262d713416d0b58bf365bc38584dce48950025850bdf3f + md5: cae723309a49399d2949362f4ab5c9e4 depends: - __glibc >=2.17,<3.0.a0 - - libgcc >=14 - license: bzip2-1.0.6 + - krb5 >=1.21.3,<1.22.0a0 + - libgcc >=13 + - libntlm >=1.8,<2.0a0 + - libstdcxx >=13 + - libxcrypt >=4.4.36 + - openssl >=3.5.0,<4.0a0 + license: BSD-3-Clause-Attribution license_family: BSD purls: [] - size: 260341 - timestamp: 1757437258798 -- conda: https://conda.anaconda.org/conda-forge/osx-64/bzip2-1.0.8-h500dc9f_8.conda - sha256: 8f50b58efb29c710f3cecf2027a8d7325ba769ab10c746eff75cea3ac050b10c - md5: 97c4b3bd8a90722104798175a1bdddbf + size: 209774 + timestamp: 1750239039316 +- conda: https://conda.anaconda.org/conda-forge/linux-64/davix-0.8.10-he574acc_1.conda + sha256: 485e77acdeb00bc63d05f5ee1f24321a41d747d1918d2cf780820af64794cba6 + md5: 1c3944b5210bdc83ab9306bfb5317c4f depends: - - __osx >=10.13 - license: bzip2-1.0.6 - license_family: BSD + - openssl + - libcurl + - libxml2-devel + - libstdcxx >=14 + - libgcc >=14 + - __glibc >=2.17,<3.0.a0 + - gsoap >=2.8.123,<2.8.124.0a0 + - gtest >=1.17.0,<1.17.1.0a0 + - libxml2 + - libxml2-16 >=2.14.6 + - libzlib >=1.3.1,<2.0a0 + - openssl >=3.5.4,<4.0a0 + license: LGPL-2.1-only purls: [] - size: 132607 - timestamp: 1757437730085 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/bzip2-1.0.8-hd037594_8.conda - sha256: b456200636bd5fecb2bec63f7e0985ad2097cf1b83d60ce0b6968dffa6d02aa1 - md5: 58fd217444c2a5701a44244faf518206 + size: 1172159 + timestamp: 1764194717843 +- conda: https://conda.anaconda.org/conda-forge/linux-64/dcap-2.47.14-h481617c_2.conda + sha256: 596bcda16b281e5cf92e5f69a21dec01209a9cab7e65e4c30f3b7bbc4dcfe85a + md5: 8472f17f6be124fcf2cd03550629788d depends: - - __osx >=11.0 - license: bzip2-1.0.6 - license_family: BSD + - gct >=6.2.1705709074,<6.2.1705709075.0a0 + - krb5 >=1.21.2,<1.22.0a0 + - libgcc-ng >=12 + - libstdcxx-ng >=12 + - libzlib >=1.2.13,<2.0.0a0 + - openssl >=3.2.1,<4.0a0 + license: LGPL-2.0-only + license_family: GPL purls: [] - size: 125061 - timestamp: 1757437486465 -- conda: https://conda.anaconda.org/conda-forge/linux-64/c-ares-1.34.6-hb03c661_0.conda - sha256: cc9accf72fa028d31c2a038460787751127317dcfa991f8d1f1babf216bb454e - md5: 920bb03579f15389b9e512095ad995b7 + size: 201103 + timestamp: 1709906343755 +- conda: https://conda.anaconda.org/conda-forge/linux-64/expat-2.7.3-hecca717_0.conda + sha256: c5d573e6831fb41177fb5ae0f1ee09caed55a868ec9887bc80ccc22c3e57b9b4 + md5: c81f6fa1865526f5ab1e6b669b3ee877 depends: - __glibc >=2.17,<3.0.a0 + - libexpat 2.7.3 hecca717_0 - libgcc >=14 license: MIT license_family: MIT purls: [] - size: 207882 - timestamp: 1765214722852 -- conda: https://conda.anaconda.org/conda-forge/osx-64/c-ares-1.34.6-hb5e19a0_0.conda - sha256: 2f5bc0292d595399df0d168355b4e9820affc8036792d6984bd751fdda2bcaea - md5: fc9a153c57c9f070bebaa7eef30a8f17 + size: 143991 + timestamp: 1763549744569 +- conda: https://conda.anaconda.org/conda-forge/linux-64/gct-6.2.1705709074-h6bbaf85_0.conda + sha256: d0dc86c605be9f7de04a3d47524acb4bc8cbf0fd8f77ad2e444913788cb1d360 + md5: 17103926aa1221d9d7520ca55ff09ef9 depends: - - __osx >=10.13 - license: MIT - license_family: MIT + - libedit >=3.1.20191231,<3.2.0a0 + - libgcc-ng >=12 + - libstdcxx-ng >=12 + - libtool >=2.4.7,<3.0a0 + - libzlib >=1.2.13,<2.0.0a0 + - openssl >=3.2.1,<4.0a0 + - perl + license: Apache-2.0 + license_family: Apache purls: [] - size: 186122 - timestamp: 1765215100384 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/c-ares-1.34.6-hc919400_0.conda - sha256: 2995f2aed4e53725e5efbc28199b46bf311c3cab2648fc4f10c2227d6d5fa196 - md5: bcb3cba70cf1eec964a03b4ba7775f01 + size: 3399111 + timestamp: 1709823867374 +- conda: https://conda.anaconda.org/conda-forge/linux-64/gfal2-2.23.5-h3ec3711_0.conda + sha256: f7b7b766a6ed222bd0657db4f9d66e3b1420e8638b7a8aef58bbf26e3e213450 + md5: 31e0c86aff2be99388ab9913e13dac4b depends: - - __osx >=11.0 - license: MIT - license_family: MIT + - json-c >=0.18,<0.19.0a0 + - libgcc >=14 + - __glibc >=2.17,<3.0.a0 + - libstdcxx >=14 + - gtest >=1.17.0,<1.17.1.0a0 + - srm-ifce >=1.24.6,<2.0a0 + - gsoap >=2.8.123,<2.8.124.0a0 + - libzlib >=1.3.1,<2.0a0 + - libssh2 >=1.11.1,<2.0a0 + - pugixml >=1.15,<1.16.0a0 + - davix >=0.8.10,<0.9.0a0 + - gct >=6.2.1705709074,<6.2.1705709075.0a0 + - libuuid >=2.41.3,<3.0a0 + - xrootd >=5.8.4,<6.0a0 + - openldap >=2.6.10,<2.7.0a0 + - libglib >=2.86.3,<3.0a0 + - dcap >=2.47.14,<2.48.0a0 + license: Apache-2.0 + license_family: APACHE purls: [] - size: 180327 - timestamp: 1765215064054 -- conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.1.4-hbd8a1cb_0.conda - sha256: b5974ec9b50e3c514a382335efa81ed02b05906849827a34061c496f4defa0b2 - md5: bddacf101bb4dd0e51811cb69c7790e2 + size: 501235 + timestamp: 1769072269303 +- conda: https://conda.anaconda.org/conda-forge/linux-64/gsoap-2.8.123-h8dc497d_0.tar.bz2 + sha256: c6a16f2b36a6a653d399cc542214b3601c54097dd5f6c4b96a0f3302d3d6480d + md5: e539f696d01d28dc42313a2ce66c0627 depends: - - __unix - license: ISC + - libgcc-ng >=12 + - libstdcxx-ng >=12 + - libzlib >=1.2.12,<2.0.0a0 + - openssl >=3.0.5,<4.0a0 + license: GPL-2.0-only + license_family: GPL purls: [] - size: 146519 - timestamp: 1767500828366 -- pypi: https://files.pythonhosted.org/packages/ef/79/c45f2d53efe6ada1110cf6f9fca095e4ff47a0454444aefdde6ac4789179/cachecontrol-0.14.4-py3-none-any.whl - name: cachecontrol - version: 0.14.4 - sha256: b7ac014ff72ee199b5f8af1de29d60239954f223e948196fa3d84adaffc71d2b - requires_dist: - - requests>=2.16.0 - - msgpack>=0.5.2,<2.0.0 - - cachecontrol[filecache,redis] ; extra == 'dev' - - cherrypy ; extra == 'dev' - - cheroot>=11.1.2 ; extra == 'dev' - - codespell ; extra == 'dev' - - furo ; extra == 'dev' - - mypy ; extra == 'dev' - - pytest ; extra == 'dev' - - pytest-cov ; extra == 'dev' - - ruff ; extra == 'dev' - - sphinx ; extra == 'dev' - - sphinx-copybutton ; extra == 'dev' - - types-redis ; extra == 'dev' - - types-requests ; extra == 'dev' - - filelock>=3.8.0 ; extra == 'filecache' - - redis>=2.10.5 ; extra == 'redis' - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/28/df/2dd32cce20cbcf6f2ec456b58d44368161ad28320729f64e5e1d5d7bd0ae/cachetools-7.0.0-py3-none-any.whl - name: cachetools - version: 7.0.0 - sha256: d52fef60e6e964a1969cfb61ccf6242a801b432790fe520d78720d757c81cbd2 - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/e6/ad/3cc14f097111b4de0040c83a525973216457bbeeb63739ef1ed275c1c021/certifi-2026.1.4-py3-none-any.whl - name: certifi - version: 2026.1.4 - sha256: 9943707519e4add1115f44c2bc244f782c0249876bf51b6599fee1ffbedd685c - requires_python: '>=3.7' -- conda: https://conda.anaconda.org/conda-forge/linux-64/cffi-2.0.0-py314h4a8dc5f_1.conda - sha256: c6339858a0aaf5d939e00d345c98b99e4558f285942b27232ac098ad17ac7f8e - md5: cf45f4278afd6f4e6d03eda0f435d527 + size: 1911621 + timestamp: 1662007838768 +- conda: https://conda.anaconda.org/conda-forge/linux-64/gtest-1.17.0-h84d6215_1.conda + sha256: 1f738280f245863c5ac78bcc04bb57266357acda45661c4aa25823030c6fb5db + md5: 55e29b72a71339bc651f9975492db71f + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + - libstdcxx >=13 + constrains: + - gmock 1.17.0 + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 416610 + timestamp: 1748320117187 +- conda: https://conda.anaconda.org/conda-forge/linux-64/icu-78.2-h33c6efd_0.conda + sha256: 142a722072fa96cf16ff98eaaf641f54ab84744af81754c292cb81e0881c0329 + md5: 186a18e3ba246eccfc7cff00cd19a870 depends: - __glibc >=2.17,<3.0.a0 - - libffi >=3.5.2,<3.6.0a0 - libgcc >=14 - - pycparser - - python >=3.14,<3.15.0a0 - - python_abi 3.14.* *_cp314 + - libstdcxx >=14 license: MIT license_family: MIT - purls: - - pkg:pypi/cffi?source=hash-mapping - size: 300271 - timestamp: 1761203085220 -- conda: https://conda.anaconda.org/conda-forge/osx-64/cffi-2.0.0-py314h8ca4d5a_1.conda - sha256: e2c58cc2451cc96db2a3c8ec34e18889878db1e95cc3e32c85e737e02a7916fb - md5: 71c2caaa13f50fe0ebad0f961aee8073 + purls: [] + size: 12728445 + timestamp: 1767969922681 +- conda: https://conda.anaconda.org/conda-forge/linux-64/json-c-0.18-h6688a6e_0.conda + sha256: 09e706cb388d3ea977fabcee8e28384bdaad8ce1fc49340df5f868a2bd95a7da + md5: 38f5dbc9ac808e31c00650f7be1db93f depends: - - __osx >=10.13 - - libffi >=3.5.2,<3.6.0a0 - - pycparser - - python >=3.14,<3.15.0a0 - - python_abi 3.14.* *_cp314 + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 license: MIT license_family: MIT - purls: - - pkg:pypi/cffi?source=hash-mapping - size: 293633 - timestamp: 1761203106369 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/cffi-2.0.0-py314h44086f9_1.conda - sha256: 5b5ee5de01eb4e4fd2576add5ec9edfc654fbaf9293e7b7ad2f893a67780aa98 - md5: 10dd19e4c797b8f8bdb1ec1fbb6821d7 + purls: [] + size: 82709 + timestamp: 1726487116178 +- conda: https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.3-hb9d3cd8_0.conda + sha256: 0960d06048a7185d3542d850986d807c6e37ca2e644342dd0c72feefcf26c2a4 + md5: b38117a3c920364aff79f870c984b4a3 depends: - - __osx >=11.0 - - libffi >=3.5.2,<3.6.0a0 - - pycparser - - python >=3.14,<3.15.0a0 - - python >=3.14,<3.15.0a0 *_cp314 - - python_abi 3.14.* *_cp314 - license: MIT - license_family: MIT - purls: - - pkg:pypi/cffi?source=hash-mapping - size: 292983 - timestamp: 1761203354051 -- conda: https://conda.anaconda.org/conda-forge/noarch/cfgv-3.5.0-pyhd8ed1ab_0.conda - sha256: aa589352e61bb221351a79e5946d56916e3c595783994884accdb3b97fe9d449 - md5: 381bd45fb7aa032691f3063aff47e3a1 + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + license: LGPL-2.1-or-later + purls: [] + size: 134088 + timestamp: 1754905959823 +- conda: https://conda.anaconda.org/conda-forge/linux-64/krb5-1.21.3-h659f571_0.conda + sha256: 99df692f7a8a5c27cd14b5fb1374ee55e756631b9c3d659ed3ee60830249b238 + md5: 3f43953b7d3fb3aaa1d0d0723d91e368 depends: - - python >=3.10 + - keyutils >=1.6.1,<2.0a0 + - libedit >=3.1.20191231,<3.2.0a0 + - libedit >=3.1.20191231,<4.0a0 + - libgcc-ng >=12 + - libstdcxx-ng >=12 + - openssl >=3.3.1,<4.0a0 license: MIT license_family: MIT - purls: - - pkg:pypi/cfgv?source=hash-mapping - size: 13589 - timestamp: 1763607964133 -- conda: https://conda.anaconda.org/conda-forge/linux-64/cgsi-gsoap-1.3.12-h32d023c_0.conda - sha256: 65fc6650c5d7ca754b0a4ea344df089bbf19ca0b76c89dcdb9ede7a6065f8673 - md5: f86a805cdeb4c3b89ad8b538f635cdeb + purls: [] + size: 1370023 + timestamp: 1719463201255 +- conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_101.conda + sha256: 565941ac1f8b0d2f2e8f02827cbca648f4d18cd461afc31f15604cd291b5c5f3 + md5: 12bd9a3f089ee6c9266a37dab82afabd depends: - __glibc >=2.17,<3.0.a0 - - gct >=6.2.1705709074,<6.2.1705709075.0a0 - - gsoap >=2.8.123,<2.8.124.0a0 - - libgcc >=12 - - libstdcxx >=12 - - openssl >=3.4.0,<4.0a0 - - voms - license: Apache-2.0 - license_family: Apache + - zstd >=1.5.7,<1.6.0a0 + constrains: + - binutils_impl_linux-64 2.45.1 + license: GPL-3.0-only purls: [] - size: 46998 - timestamp: 1738622766217 -- pypi: https://files.pythonhosted.org/packages/2a/35/7051599bd493e62411d6ede36fd5af83a38f37c4767b92884df7301db25d/charset_normalizer-3.4.4-cp314-cp314-macosx_10_13_universal2.whl - name: charset-normalizer - version: 3.4.4 - sha256: da3326d9e65ef63a817ecbcc0df6e94463713b754fe293eaa03da99befb9a5bd - requires_python: '>=3.7' -- pypi: https://files.pythonhosted.org/packages/67/ff/f6b948ca32e4f2a4576aa129d8bed61f2e0543bf9f5f2b7fc3758ed005c9/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - name: charset-normalizer - version: 3.4.4 - sha256: ecaae4149d99b1c9e7b88bb03e3221956f68fd6d50be2ef061b2381b61d20838 - requires_python: '>=3.7' -- pypi: https://files.pythonhosted.org/packages/98/78/01c019cdb5d6498122777c1a43056ebb3ebfeef2076d9d026bfe15583b2b/click-8.3.1-py3-none-any.whl - name: click - version: 8.3.1 - sha256: 981153a64e25f12d547d3426c367a4857371575ee7ad18df2a6183ab0545b2a6 - requires_dist: - - colorama ; sys_platform == 'win32' - requires_python: '>=3.10' -- conda: https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda - sha256: ab29d57dc70786c1269633ba3dff20288b81664d3ff8d21af995742e2bb03287 - md5: 962b9857ee8e7018c22f2776ffa0b2d7 + size: 725507 + timestamp: 1770267139900 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-5_h4a7cf45_openblas.conda + build_number: 5 + sha256: 18c72545080b86739352482ba14ba2c4815e19e26a7417ca21a95b76ec8da24c + md5: c160954f7418d7b6e87eaf05a8913fa9 depends: - - python >=3.9 + - libopenblas >=0.3.30,<0.3.31.0a0 + - libopenblas >=0.3.30,<1.0a0 + constrains: + - mkl <2026 + - liblapack 3.11.0 5*_openblas + - libcblas 3.11.0 5*_openblas + - blas 2.305 openblas + - liblapacke 3.11.0 5*_openblas license: BSD-3-Clause license_family: BSD - purls: - - pkg:pypi/colorama?source=hash-mapping - size: 27011 - timestamp: 1733218222191 -- pypi: https://files.pythonhosted.org/packages/a7/06/3d6badcf13db419e25b07041d9c7b4a2c331d3f4e7134445ec5df57714cd/coloredlogs-15.0.1-py2.py3-none-any.whl - name: coloredlogs - version: 15.0.1 - sha256: 612ee75c546f53e92e70049c9dbfcc18c935a2b9a53b66085ce9ef6a6e5c0934 - requires_dist: - - humanfriendly>=9.1 - - capturer>=2.4 ; extra == 'cron' - requires_python: '>=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*' -- pypi: https://files.pythonhosted.org/packages/19/0f/f6121b90b86b9093c066889274d26a1de3f29969d45c2ed1ecbe2033cb78/cramjam-2.11.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - name: cramjam - version: 2.11.0 - sha256: 17eb39b1696179fb471eea2de958fa21f40a2cd8bf6b40d428312d5541e19dc4 - requires_dist: - - black==22.3.0 ; extra == 'dev' - - numpy ; extra == 'dev' - - pytest>=5.30 ; extra == 'dev' - - pytest-xdist ; extra == 'dev' - - pytest-benchmark ; extra == 'dev' - - hypothesis==6.60.0 ; extra == 'dev' - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/de/07/a1051cdbbe6d723df16d756b97f09da7c1adb69e29695c58f0392bc12515/cramjam-2.11.0-cp314-cp314-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl - name: cramjam - version: 2.11.0 - sha256: 7ba5e38c9fbd06f086f4a5a64a1a5b7b417cd3f8fc07a20e5c03651f72f36100 - requires_dist: - - black==22.3.0 ; extra == 'dev' - - numpy ; extra == 'dev' - - pytest>=5.30 ; extra == 'dev' - - pytest-xdist ; extra == 'dev' - - pytest-benchmark ; extra == 'dev' - - hypothesis==6.60.0 ; extra == 'dev' - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/2b/08/f83e2e0814248b844265802d081f2fac2f1cbe6cd258e72ba14ff006823a/cryptography-46.0.4-cp311-abi3-manylinux_2_28_x86_64.whl - name: cryptography - version: 46.0.4 - sha256: 0a9ad24359fee86f131836a9ac3bffc9329e956624a2d379b613f8f8abaf5255 - requires_dist: - - cffi>=1.14 ; python_full_version == '3.8.*' and platform_python_implementation != 'PyPy' - - cffi>=2.0.0 ; python_full_version >= '3.9' and platform_python_implementation != 'PyPy' - - typing-extensions>=4.13.2 ; python_full_version < '3.11' - - bcrypt>=3.1.5 ; extra == 'ssh' - - nox[uv]>=2024.4.15 ; extra == 'nox' - - cryptography-vectors==46.0.4 ; extra == 'test' - - pytest>=7.4.0 ; extra == 'test' - - pytest-benchmark>=4.0 ; extra == 'test' - - pytest-cov>=2.10.1 ; extra == 'test' - - pytest-xdist>=3.5.0 ; extra == 'test' - - pretend>=0.7 ; extra == 'test' - - certifi>=2024 ; extra == 'test' - - pytest-randomly ; extra == 'test-randomorder' - - sphinx>=5.3.0 ; extra == 'docs' - - sphinx-rtd-theme>=3.0.0 ; extra == 'docs' - - sphinx-inline-tabs ; extra == 'docs' - - pyenchant>=3 ; extra == 'docstest' - - readme-renderer>=30.0 ; extra == 'docstest' - - sphinxcontrib-spelling>=7.3.1 ; extra == 'docstest' - - build>=1.0.0 ; extra == 'sdist' - - ruff>=0.11.11 ; extra == 'pep8test' - - mypy>=1.14 ; extra == 'pep8test' - - check-sdist ; extra == 'pep8test' - - click>=8.0.1 ; extra == 'pep8test' - requires_python: '>=3.8,!=3.9.0,!=3.9.1' -- pypi: https://files.pythonhosted.org/packages/8d/99/157aae7949a5f30d51fcb1a9851e8ebd5c74bf99b5285d8bb4b8b9ee641e/cryptography-46.0.4-cp311-abi3-macosx_10_9_universal2.whl - name: cryptography - version: 46.0.4 - sha256: 281526e865ed4166009e235afadf3a4c4cba6056f99336a99efba65336fd5485 - requires_dist: - - cffi>=1.14 ; python_full_version == '3.8.*' and platform_python_implementation != 'PyPy' - - cffi>=2.0.0 ; python_full_version >= '3.9' and platform_python_implementation != 'PyPy' - - typing-extensions>=4.13.2 ; python_full_version < '3.11' - - bcrypt>=3.1.5 ; extra == 'ssh' - - nox[uv]>=2024.4.15 ; extra == 'nox' - - cryptography-vectors==46.0.4 ; extra == 'test' - - pytest>=7.4.0 ; extra == 'test' - - pytest-benchmark>=4.0 ; extra == 'test' - - pytest-cov>=2.10.1 ; extra == 'test' - - pytest-xdist>=3.5.0 ; extra == 'test' - - pretend>=0.7 ; extra == 'test' - - certifi>=2024 ; extra == 'test' - - pytest-randomly ; extra == 'test-randomorder' - - sphinx>=5.3.0 ; extra == 'docs' - - sphinx-rtd-theme>=3.0.0 ; extra == 'docs' - - sphinx-inline-tabs ; extra == 'docs' - - pyenchant>=3 ; extra == 'docstest' - - readme-renderer>=30.0 ; extra == 'docstest' - - sphinxcontrib-spelling>=7.3.1 ; extra == 'docstest' - - build>=1.0.0 ; extra == 'sdist' - - ruff>=0.11.11 ; extra == 'pep8test' - - mypy>=1.14 ; extra == 'pep8test' - - check-sdist ; extra == 'pep8test' - - click>=8.0.1 ; extra == 'pep8test' - requires_python: '>=3.8,!=3.9.0,!=3.9.1' -- pypi: https://files.pythonhosted.org/packages/db/2b/1239938a2629c29363e07724d7bd4c87a8b566947ecee2afb5f5ac34e1bb/cwl_upgrader-1.2.14-py3-none-any.whl - name: cwl-upgrader - version: 1.2.14 - sha256: 7c4ed6dfe082d56a58bf4e7451303213b5ee7b4e3621237dbbaad8d13018afbe - requires_dist: - - ruamel-yaml>=0.16.0,<0.19 - - schema-salad - - pytest<10 ; extra == 'testing' - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/63/4b/ccab2a5ca9e0b6553810b85c06387e60fc9443cec3c987e3a062705bd225/cwl_utils-0.40-py3-none-any.whl - name: cwl-utils - version: '0.40' - sha256: f6688cd3b78b826af2aa5518b31d8d7ba784914d0a7a5784266c615093e1e94b - requires_dist: - - cwl-upgrader>=1.2.3 - - packaging - - rdflib - - requests - - schema-salad>=8.8.20250205075315,<9 - - ruamel-yaml>=0.17.6,<0.19 - - typing-extensions ; python_full_version < '3.10' - - cwlformat ; extra == 'pretty' - - pytest<9 ; extra == 'testing' - - pytest-mock ; extra == 'testing' - requires_python: '>=3.9,<3.15' -- pypi: https://files.pythonhosted.org/packages/3b/56/99a7cf6ca8533695874cf804369221d03bf5e869a7e0b38acbf4dbe8deeb/cwlformat-2022.2.18-py3-none-any.whl - name: cwlformat - version: 2022.2.18 - sha256: d3e2dca192ce10e703ed4eb0bae26539db08d8ddd7c6a6fe9d1406c3f1b53cda - requires_dist: - - ruamel-yaml>=0.16.12 - - importlib-resources ; python_full_version < '3.7' - requires_python: '>=3.6.0' -- pypi: https://files.pythonhosted.org/packages/65/ee/a7aba2b112c5ae879d5cfb231c75189a7fd2a5e84b6af7e07dd71fb2bb35/cwltool-3.1.20260108082145-py3-none-any.whl - name: cwltool - version: 3.1.20260108082145 - sha256: ddc895c809cccf04b731476d2e35ca0126f498be079b349457a5c56471155556 - requires_dist: - - requests>=2.6.1 - - ruamel-yaml>=0.16,<0.20 - - rdflib>=4.2.2,<7.6.0 - - schema-salad>=8.9,<9 - - prov==1.5.1 - - mypy-extensions - - psutil>=5.6.6 - - coloredlogs - - pydot>=1.4.1 - - argcomplete>=1.12.0 - - pyparsing!=3.0.2 - - cwl-utils>=0.32 - - spython>=0.3.0 - - rich-argparse - - typing-extensions>=4.1.0 - - galaxy-tool-util>=22.1.2,!=23.0.1,!=23.0.2,!=23.0.3,!=23.0.4,!=23.0.5,<25.2 ; extra == 'deps' - - galaxy-util<25.2 ; extra == 'deps' - - pillow ; extra == 'deps' - requires_python: '>=3.10,<3.15' -- conda: https://conda.anaconda.org/conda-forge/linux-64/cyrus-sasl-2.1.28-hd9c7081_0.conda - sha256: ee09ad7610c12c7008262d713416d0b58bf365bc38584dce48950025850bdf3f - md5: cae723309a49399d2949362f4ab5c9e4 + purls: [] + size: 18213 + timestamp: 1765818813880 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libboost-1.88.0-hd24cca6_7.conda + sha256: dd489228e1916c7720c925248d0ba12803d1dc8b9898be0c51f4ab37bab6ffa5 + md5: d70e4dc6a847d437387d45462fe60cf9 depends: - __glibc >=2.17,<3.0.a0 - - krb5 >=1.21.3,<1.22.0a0 - - libgcc >=13 - - libntlm >=1.8,<2.0a0 - - libstdcxx >=13 - - libxcrypt >=4.4.36 - - openssl >=3.5.0,<4.0a0 - license: BSD-3-Clause-Attribution - license_family: BSD + - bzip2 >=1.0.8,<2.0a0 + - icu >=78.1,<79.0a0 + - libgcc >=14 + - liblzma >=5.8.1,<6.0a0 + - libstdcxx >=14 + - libzlib >=1.3.1,<2.0a0 + - zstd >=1.5.7,<1.6.0a0 + constrains: + - boost-cpp <0.0a0 + license: BSL-1.0 purls: [] - size: 209774 - timestamp: 1750239039316 -- conda: https://conda.anaconda.org/conda-forge/osx-64/cyrus-sasl-2.1.28-h610c526_0.conda - sha256: beee5d279d48d67ba39f1b8f64bc050238d3d465fb9a53098eba2a85e9286949 - md5: 314cd5e4aefc50fec5ffd80621cfb4f8 + size: 3072984 + timestamp: 1766347479317 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libboost-python-1.88.0-py314h3a4f467_7.conda + sha256: a701f2a6afa984b52cfffe51abb5aaf8e6e534082f71e36078f0f4cf54d2e7fe + md5: ed299171ab3525d8f4ed400083105743 depends: - - __osx >=10.13 - - krb5 >=1.21.3,<1.22.0a0 - - libcxx >=18 - - libntlm >=1.8,<2.0a0 - - openssl >=3.5.0,<4.0a0 - license: BSD-3-Clause-Attribution - license_family: BSD + - __glibc >=2.17,<3.0.a0 + - libboost 1.88.0 hd24cca6_7 + - libgcc >=14 + - libstdcxx >=14 + - numpy >=1.23,<3 + - python >=3.14,<3.15.0a0 + - python_abi 3.14.* *_cp314 + constrains: + - py-boost <0.0a0 + - boost <0.0a0 + license: BSL-1.0 purls: [] - size: 197689 - timestamp: 1750239254864 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/cyrus-sasl-2.1.28-ha1cbb27_0.conda - sha256: 7de03254fa5421e7ec2347c830a59530fb5356022ee0dc26ec1cef0be1de0911 - md5: 2867ea6551e97e53a81787fd967162b1 + size: 132709 + timestamp: 1766347940966 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-5_h0358290_openblas.conda + build_number: 5 + sha256: 0cbdcc67901e02dc17f1d19e1f9170610bd828100dc207de4d5b6b8ad1ae7ad8 + md5: 6636a2b6f1a87572df2970d3ebc87cc0 depends: - - __osx >=11.0 - - krb5 >=1.21.3,<1.22.0a0 - - libcxx >=18 - - libntlm >=1.8,<2.0a0 - - openssl >=3.5.0,<4.0a0 - license: BSD-3-Clause-Attribution + - libblas 3.11.0 5_h4a7cf45_openblas + constrains: + - liblapacke 3.11.0 5*_openblas + - blas 2.305 openblas + - liblapack 3.11.0 5*_openblas + license: BSD-3-Clause license_family: BSD purls: [] - size: 193732 - timestamp: 1750239236574 -- conda: https://conda.anaconda.org/conda-forge/linux-64/davix-0.8.10-he574acc_1.conda - sha256: 485e77acdeb00bc63d05f5ee1f24321a41d747d1918d2cf780820af64794cba6 - md5: 1c3944b5210bdc83ab9306bfb5317c4f + size: 18194 + timestamp: 1765818837135 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libcurl-8.18.0-h4e3cde8_0.conda + sha256: 5454709d9fb6e9c3dd6423bc284fa7835a7823bfa8323f6e8786cdd555101fab + md5: 0a5563efed19ca4461cf927419b6eb73 depends: - - openssl - - libcurl - - libxml2-devel - - libstdcxx >=14 - - libgcc >=14 - __glibc >=2.17,<3.0.a0 - - gsoap >=2.8.123,<2.8.124.0a0 - - gtest >=1.17.0,<1.17.1.0a0 - - libxml2 - - libxml2-16 >=2.14.6 + - krb5 >=1.21.3,<1.22.0a0 + - libgcc >=14 + - libnghttp2 >=1.67.0,<2.0a0 + - libssh2 >=1.11.1,<2.0a0 - libzlib >=1.3.1,<2.0a0 - openssl >=3.5.4,<4.0a0 - license: LGPL-2.1-only + - zstd >=1.5.7,<1.6.0a0 + license: curl + license_family: MIT purls: [] - size: 1172159 - timestamp: 1764194717843 -- conda: https://conda.anaconda.org/conda-forge/osx-64/davix-0.8.10-h35d429b_1.conda - sha256: e76f71e61622aedcb8b8e936cf0a595eb44123b3ac355c28e46c48622f6943f5 - md5: 558377132bfd2fe14f6dbd28d644b25c + size: 462942 + timestamp: 1767821743793 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949ede_0.conda + sha256: d789471216e7aba3c184cd054ed61ce3f6dac6f87a50ec69291b9297f8c18724 + md5: c277e0a4d549b03ac1e9d6cbbe3d017b depends: - - openssl - - libcurl - - libxml2-devel - - libcxx >=19 - - __osx >=10.13 - - gsoap >=2.8.123,<2.8.124.0a0 - - libxml2 - - libxml2-16 >=2.14.6 - - libzlib >=1.3.1,<2.0a0 - - openssl >=3.5.4,<4.0a0 - - gtest >=1.17.0,<1.17.1.0a0 - license: LGPL-2.1-only + - ncurses + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + - ncurses >=6.5,<7.0a0 + license: BSD-2-Clause + license_family: BSD purls: [] - size: 990237 - timestamp: 1764194905133 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/davix-0.8.10-h0b7473d_1.conda - sha256: de0e457af62183ef91e7b92d172da9887d1bd21f1f85122656c47d79199c49ec - md5: 59f9ecae2150f2e7feaeb72349923965 + size: 134676 + timestamp: 1738479519902 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libev-4.33-hd590300_2.conda + sha256: 1cd6048169fa0395af74ed5d8f1716e22c19a81a8a36f934c110ca3ad4dd27b4 + md5: 172bf1cd1ff8629f2b1179945ed45055 depends: - - openssl - - libcurl - - libxml2-devel - - libcxx >=19 - - __osx >=11.0 - - gtest >=1.17.0,<1.17.1.0a0 - - openssl >=3.5.4,<4.0a0 - - libxml2 - - libxml2-16 >=2.14.6 - - libzlib >=1.3.1,<2.0a0 - - gsoap >=2.8.123,<2.8.124.0a0 - license: LGPL-2.1-only + - libgcc-ng >=12 + license: BSD-2-Clause + license_family: BSD purls: [] - size: 926053 - timestamp: 1764194930352 -- pypi: https://files.pythonhosted.org/packages/5a/36/17015b7bae2783f7bbde50a8bafdeb702802c080322204f1bfcae25b9e02/DB12-1.0.4-py3-none-any.whl - name: db12 - version: 1.0.4 - sha256: 2dbb96e77e43870e02f3dfe32bb9a4e0ad0a6e68db65bc2d5ac96b136469e2d3 - requires_python: '>=2.7' -- conda: https://conda.anaconda.org/conda-forge/linux-64/dcap-2.47.14-h481617c_2.conda - sha256: 596bcda16b281e5cf92e5f69a21dec01209a9cab7e65e4c30f3b7bbc4dcfe85a - md5: 8472f17f6be124fcf2cd03550629788d + size: 112766 + timestamp: 1702146165126 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.3-hecca717_0.conda + sha256: 1e1b08f6211629cbc2efe7a5bca5953f8f6b3cae0eeb04ca4dacee1bd4e2db2f + md5: 8b09ae86839581147ef2e5c5e229d164 depends: - - gct >=6.2.1705709074,<6.2.1705709075.0a0 - - krb5 >=1.21.2,<1.22.0a0 - - libgcc-ng >=12 - - libstdcxx-ng >=12 - - libzlib >=1.2.13,<2.0.0a0 - - openssl >=3.2.1,<4.0a0 - license: LGPL-2.0-only - license_family: GPL + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + constrains: + - expat 2.7.3.* + license: MIT + license_family: MIT purls: [] - size: 201103 - timestamp: 1709906343755 -- conda: https://conda.anaconda.org/conda-forge/osx-64/dcap-2.47.14-hf4fbb18_2.conda - sha256: a27f5509216f8e329bfa3f17f90ba75ec5042d1804056c556eb369d2b32bb4e1 - md5: ea46df07255b836c340deaab872e4049 + size: 76643 + timestamp: 1763549731408 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda + sha256: 31f19b6a88ce40ebc0d5a992c131f57d919f73c0b92cd1617a5bec83f6e961e6 + md5: a360c33a5abe61c07959e449fa1453eb depends: - - gct >=6.2.1705709074,<6.2.1705709075.0a0 - - krb5 >=1.21.2,<1.22.0a0 - - libcxx >=16 - - libzlib >=1.2.13,<2.0.0a0 - - openssl >=3.2.1,<4.0a0 - license: LGPL-2.0-only - license_family: GPL + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + license: MIT + license_family: MIT purls: [] - size: 162986 - timestamp: 1709906839770 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/dcap-2.47.14-h33e0366_2.conda - sha256: fd0c392617be15682341deaa473637a73361964ce3154539833e69390d4cccfc - md5: 5d4e4cda1dcbe3c2503e2440be7c1954 + size: 58592 + timestamp: 1769456073053 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_17.conda + sha256: 43860222cf3abf04ded0cf24541a105aa388e0e1d4d6ca46258e186d4e87ae3e + md5: 3c281169ea25b987311400d7a7e28445 depends: - - gct >=6.2.1705709074,<6.2.1705709075.0a0 - - krb5 >=1.21.2,<1.22.0a0 - - libcxx >=16 - - libzlib >=1.2.13,<2.0.0a0 - - openssl >=3.2.1,<4.0a0 - license: LGPL-2.0-only - license_family: GPL + - __glibc >=2.17,<3.0.a0 + - _openmp_mutex >=4.5 + constrains: + - libgcc-ng ==15.2.0=*_17 + - libgomp 15.2.0 he0feb66_17 + license: GPL-3.0-only WITH GCC-exception-3.1 purls: [] - size: 171436 - timestamp: 1709906737580 -- pypi: https://files.pythonhosted.org/packages/4e/8c/f3147f5c4b73e7550fe5f9352eaa956ae838d5c51eb58e7a25b9f3e2643b/decorator-5.2.1-py3-none-any.whl - name: decorator - version: 5.2.1 - sha256: d316bb415a2d9e2d2b3abcc4084c6502fc09240e292cd76a76afc106a1c8e04a - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/84/d0/205d54408c08b13550c733c4b85429e7ead111c7f0014309637425520a9a/deprecated-1.3.1-py2.py3-none-any.whl - name: deprecated - version: 1.3.1 - sha256: 597bfef186b6f60181535a29fbe44865ce137a5079f295b479886c82729d5f3f - requires_dist: - - wrapt>=1.10,<3 - - inspect2 ; python_full_version < '3' - - tox ; extra == 'dev' - - pytest ; extra == 'dev' - - pytest-cov ; extra == 'dev' - - bump2version<1 ; extra == 'dev' - - setuptools ; python_full_version >= '3.12' and extra == 'dev' - requires_python: '>=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*' -- pypi: https://files.pythonhosted.org/packages/d0/d0/9e71fdc3394ffc632f35946c572e60fcc2a5452ba0a23c52493f23d60672/dirac-9.1.6-py3-none-any.whl - name: dirac - version: 9.1.6 - sha256: d818427204216f239df4171ddaa3cc646d7e208a34577bb8c86f2d9d50f6ffb3 - requires_dist: - - boto3>=1.35 - - botocore>=1.35 - - cachetools - - certifi - - cwltool - - diraccfg - - diraccommon==9.1.6 - - diracx-client>=0.0.1 - - diracx-core>=0.0.1 - - diracx-cli>=0.0.1 - - db12 - - fabric - - fts3 - - gfal2-python - - importlib-metadata>=4.4 - - importlib-resources - - invoke - - m2crypto>=0.36 - - packaging - - paramiko - - pexpect - - prompt-toolkit>=3 - - psutil - - pyasn1 - - pyasn1-modules - - pydantic>=2.4 - - pyparsing - - python-dateutil - - pytz - - requests - - rucio-clients>=34.4.2 - - sqlalchemy - - typing-extensions>=4.3.0 - - authlib>=1.0.0a2 - - pyjwt - - dominate - - zstandard - - xattr - - cmreshandler ; extra == 'server' - - opensearch-py ; extra == 'server' - - gitpython ; extra == 'server' - - ldap3 ; extra == 'server' - - apache-libcloud ; extra == 'server' - - matplotlib ; extra == 'server' - - mysqlclient ; extra == 'server' - - numpy ; extra == 'server' - - pillow ; extra == 'server' - - python-json-logger ; extra == 'server' - - pyyaml ; extra == 'server' - - stomp-py ; extra == 'server' - - suds ; extra == 'server' - - tornado~=5.1.1 ; extra == 'server' - - tornado-m2crypto ; extra == 'server' - - importlib-resources ; extra == 'server' - - hypothesis ; extra == 'testing' - - mock ; extra == 'testing' - - parameterized ; extra == 'testing' - - pytest ; extra == 'testing' - - pytest-cov ; extra == 'testing' - - pytest-mock ; extra == 'testing' - - pytest-rerunfailures ; extra == 'testing' - - pycodestyle ; extra == 'testing' - requires_python: '>=3.11' -- pypi: ./ - name: dirac-cwl - version: 1.2.1.dev11+g1da58a2a5.d20260428 - sha256: 6b2880b8b3e1502d70cfb2bf1823439ef595fe963b873bb23ef101a9cae108f2 - requires_dist: - - cwl-utils - - cwlformat - - cwltool - - dirac>=9.0.0 - - diracx-core>=0.0.8 - - diracx-api>=0.0.8 - - diracx-client>=0.0.8 - - diracx-cli>=0.0.8 - - lbprodrun - - lhcbdirac @ git+https://****@gitlab.cern.ch/jlisalab/LHCbDIRAC.git@modules-to-cwl-migration - - pydantic - - pyyaml - - typer - - referencing>=0.30 - - rich - - ruamel-yaml - - pytest>=6 ; extra == 'testing' - - pytest-mock ; extra == 'testing' - - mypy ; extra == 'testing' - requires_python: '>=3.11' - editable: true -- pypi: https://files.pythonhosted.org/packages/9f/90/279f55fff9481f9e0424c3c97b24dc10004ec8d8f98ddf5afd07a7b79194/diraccfg-1.0.1-py2.py3-none-any.whl - name: diraccfg - version: 1.0.1 - sha256: 5103e25208fd41c623a72ddd5775416633f97b376531c86fb4e79282871db218 - requires_dist: - - pytest>=4.6 ; extra == 'testing' - - pytest-cov ; extra == 'testing' - - pylint>=1.6.5 ; extra == 'testing' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/f8/b2/ad8e7e63fdf5add3ceb7a0805d700e9fd7cb7d5743f765a4994b4ec286d7/diraccommon-9.1.6-py3-none-any.whl - name: diraccommon - version: 9.1.6 - sha256: 53c765edf120eff9764d49e57d4073c0f2d671ed391f52a2ca940abef0810963 - requires_dist: - - diraccfg - - pydantic>=2.0.0 - - typing-extensions>=4.0.0 - - pytest-cov>=4.0.0 ; extra == 'testing' - - pytest>=7.0.0 ; extra == 'testing' - requires_python: '>=3.11' -- pypi: https://files.pythonhosted.org/packages/ab/7e/5f02b757bb825e5cdc65f6f7a12c209963bec877d61497393bea8f41f9ce/diracx_api-0.0.8-py3-none-any.whl - name: diracx-api - version: 0.0.8 - sha256: 73343b5cebadf17ab511a3dfb47492f1fc2b8aca0d3fe1b3c4808d5595e9ce7d - requires_dist: - - diracx-client - - diracx-core - - httpx - - zstandard - - diracx-testing ; extra == 'testing' - requires_python: '>=3.11' -- pypi: https://files.pythonhosted.org/packages/b0/28/87e78ff0d6041f40431d88b8aa3b645be7476a420d8dcbf7197f5b394c5c/diracx_cli-0.0.8-py3-none-any.whl - name: diracx-cli - version: 0.0.8 - sha256: 3c38d3913e99922a0d9d8692a6d154bbdf98c63bb4411609bf5a65881b157e10 - requires_dist: - - diraccfg - - diracx-api - - diracx-client - - diracx-core - - gitpython - - pydantic>=2.10 - - pyyaml - - rich - - typer>=0.15.4 - - diracx-testing ; extra == 'testing' - - types-pyyaml ; extra == 'types' - requires_python: '>=3.11' -- pypi: https://files.pythonhosted.org/packages/f2/61/0c78d9778bffd844863d3173a5fefb506d7131ceebecee523a9e27024aa1/diracx_client-0.0.8-py3-none-any.whl - name: diracx-client - version: 0.0.8 - sha256: 9c8406add1f14c103ac91440fa41bb93e400d98bcad60f32e987ff6b233fa18b - requires_dist: - - azure-core - - diracx-core - - httpx - - isodate - - pyjwt - - diracx-testing ; extra == 'testing' - requires_python: '>=3.11' -- pypi: https://files.pythonhosted.org/packages/b2/c9/459da97eb93fad89738951972671d44be197610242b8da88a0384791ea7e/diracx_core-0.0.8-py3-none-any.whl - name: diracx-core - version: 0.0.8 - sha256: caed9a107a1ee93a4c5a44e1e2ca753acefbacdb44a46e22907d7ef839e3bdf8 - requires_dist: - - aiobotocore>=2.15 - - botocore>=1.35 - - cachetools - - diraccommon>=9.0.0 - - email-validator - - gitpython - - joserfc>=1.1.0 - - pydantic-settings - - pydantic>=2.10 - - pyyaml - - sh - - diracx-testing ; extra == 'testing' - - moto[server] ; extra == 'testing' - - botocore-stubs ; extra == 'types' - - types-aiobotocore-s3 ; extra == 'types' - - types-aiobotocore[essential] ; extra == 'types' - - types-cachetools ; extra == 'types' - - types-pyyaml ; extra == 'types' - requires_python: '>=3.11' -- conda: https://conda.anaconda.org/conda-forge/noarch/distlib-0.4.0-pyhd8ed1ab_0.conda - sha256: 6d977f0b2fc24fee21a9554389ab83070db341af6d6f09285360b2e09ef8b26e - md5: 003b8ba0a94e2f1e117d0bd46aebc901 + size: 1040478 + timestamp: 1770252533873 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_17.conda + sha256: bdfe50501e4a2d904a5eae65a7ae26e2b7a29b473ab084ad55d96080b966502e + md5: 1478bfa85224a65ab096d69ffd2af1e5 depends: - - python >=3.9 - license: Apache-2.0 - license_family: APACHE - purls: - - pkg:pypi/distlib?source=hash-mapping - size: 275642 - timestamp: 1752823081585 -- pypi: https://files.pythonhosted.org/packages/ba/5a/18ad964b0086c6e62e2e7500f7edc89e3faa45033c71c1893d34eed2b2de/dnspython-2.8.0-py3-none-any.whl - name: dnspython - version: 2.8.0 - sha256: 01d9bbc4a2d76bf0db7c1f729812ded6d912bd318d3b1cf81d30c0f845dbf3af - requires_dist: - - black>=25.1.0 ; extra == 'dev' - - coverage>=7.0 ; extra == 'dev' - - flake8>=7 ; extra == 'dev' - - hypercorn>=0.17.0 ; extra == 'dev' - - mypy>=1.17 ; extra == 'dev' - - pylint>=3 ; extra == 'dev' - - pytest-cov>=6.2.0 ; extra == 'dev' - - pytest>=8.4 ; extra == 'dev' - - quart-trio>=0.12.0 ; extra == 'dev' - - sphinx-rtd-theme>=3.0.0 ; extra == 'dev' - - sphinx>=8.2.0 ; extra == 'dev' - - twine>=6.1.0 ; extra == 'dev' - - wheel>=0.45.0 ; extra == 'dev' - - cryptography>=45 ; extra == 'dnssec' - - h2>=4.2.0 ; extra == 'doh' - - httpcore>=1.0.0 ; extra == 'doh' - - httpx>=0.28.0 ; extra == 'doh' - - aioquic>=1.2.0 ; extra == 'doq' - - idna>=3.10 ; extra == 'idna' - - trio>=0.30 ; extra == 'trio' - - wmi>=1.5.1 ; sys_platform == 'win32' and extra == 'wmi' - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/dc/80/12235e5b75bb2c586733280854f131b86051e0bbdfb55349ff70d0f72cf9/dogpile_cache-1.5.0-py3-none-any.whl - name: dogpile-cache - version: 1.5.0 - sha256: dc7b47d37844db15e8fdc0243c1b58857a2ddc52a5118237a97127bac200e18d - requires_dist: - - decorator>=4.0.0 - - stevedore>=3.0.0 - - typing-extensions>=4.0.1 ; python_full_version < '3.11' - - pifpaf>=3.3.0 ; extra == 'pifpaf' - - pymemcache ; extra == 'pymemcache' - - python-memcached ; extra == 'memcached' - - python-binary-memcached ; extra == 'bmemcached' - - pylibmc ; extra == 'pylibmc' - - redis ; extra == 'redis' - - valkey ; extra == 'valkey' - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/58/19/0380af745f151a1648657bbcef0fb49ac28bf09083d94498163ffd9b32dc/dominate-2.9.1-py2.py3-none-any.whl - name: dominate - version: 2.9.1 - sha256: cb7b6b79d33b15ae0a6e87856b984879927c7c2ebb29522df4c75b28ffd9b989 - requires_python: '>=3.4' -- pypi: https://files.pythonhosted.org/packages/de/15/545e2b6cf2e3be84bc1ed85613edd75b8aea69807a71c26f4ca6a9258e82/email_validator-2.3.0-py3-none-any.whl - name: email-validator - version: 2.3.0 - sha256: 80f13f623413e6b197ae73bb10bf4eb0908faf509ad8362c5edeb0be7fd450b4 - requires_dist: - - dnspython>=2.0.0 - - idna>=2.0.0 - requires_python: '>=3.8' -- conda: https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda - sha256: ee6cf346d017d954255bbcbdb424cddea4d14e4ed7e9813e429db1d795d01144 - md5: 8e662bd460bda79b1ea39194e3c4c9ab + - libgcc 15.2.0 he0feb66_17 + license: GPL-3.0-only WITH GCC-exception-3.1 + purls: [] + size: 27541 + timestamp: 1770252546553 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_17.conda + sha256: 1604c083dd65bc91e68b6cfe32c8610395088cb96af1acaf71f0dcaf83ac58f7 + md5: a6c682ac611cb1fa4d73478f9e6efb06 depends: - - python >=3.10 - - typing_extensions >=4.6.0 - license: MIT and PSF-2.0 - purls: - - pkg:pypi/exceptiongroup?source=hash-mapping - size: 21333 - timestamp: 1763918099466 -- conda: https://conda.anaconda.org/conda-forge/linux-64/expat-2.7.3-hecca717_0.conda - sha256: c5d573e6831fb41177fb5ae0f1ee09caed55a868ec9887bc80ccc22c3e57b9b4 - md5: c81f6fa1865526f5ab1e6b669b3ee877 + - libgfortran5 15.2.0 h68bc16d_17 + constrains: + - libgfortran-ng ==15.2.0=*_17 + license: GPL-3.0-only WITH GCC-exception-3.1 + purls: [] + size: 27515 + timestamp: 1770252591906 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_17.conda + sha256: b1c77b85da9a3e204de986f59e262268805c6a35dffdf3953f1b98407db2aef3 + md5: 202fdf8cad9eea704c2b0d823d1732bf depends: - __glibc >=2.17,<3.0.a0 - - libexpat 2.7.3 hecca717_0 + - libgcc >=15.2.0 + constrains: + - libgfortran 15.2.0 + license: GPL-3.0-only WITH GCC-exception-3.1 + purls: [] + size: 2480824 + timestamp: 1770252563579 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libglib-2.86.3-h6548e54_0.conda + sha256: 82d6c2ee9f548c84220fb30fb1b231c64a53561d6e485447394f0a0eeeffe0e6 + md5: 034bea55a4feef51c98e8449938e9cee + depends: + - __glibc >=2.17,<3.0.a0 + - libffi >=3.5.2,<3.6.0a0 + - libgcc >=14 + - libiconv >=1.18,<2.0a0 + - libzlib >=1.3.1,<2.0a0 + - pcre2 >=10.47,<10.48.0a0 + constrains: + - glib 2.86.3 *_0 + license: LGPL-2.1-or-later + purls: [] + size: 3946542 + timestamp: 1765221858705 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_17.conda + sha256: b961b5dd9761907a7179678b58a69bb4fc16b940eb477f635aea3aec0a3f17a6 + md5: 51b78c6a757575c0d12f4401ffc67029 + depends: + - __glibc >=2.17,<3.0.a0 + license: GPL-3.0-only WITH GCC-exception-3.1 + purls: [] + size: 603334 + timestamp: 1770252441199 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libiconv-1.18-h3b78370_2.conda + sha256: c467851a7312765447155e071752d7bf9bf44d610a5687e32706f480aad2833f + md5: 915f5995e94f60e9a4826e0b0920ee88 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + license: LGPL-2.1-only + purls: [] + size: 790176 + timestamp: 1754908768807 +- conda: https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-5_h47877c9_openblas.conda + build_number: 5 + sha256: c723b6599fcd4c6c75dee728359ef418307280fa3e2ee376e14e85e5bbdda053 + md5: b38076eb5c8e40d0106beda6f95d7609 + depends: + - libblas 3.11.0 5_h4a7cf45_openblas + constrains: + - blas 2.305 openblas + - liblapacke 3.11.0 5*_openblas + - libcblas 3.11.0 5*_openblas + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 18200 + timestamp: 1765818857876 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libltdl-2.4.3a-h5888daf_0.conda + sha256: 7620c6425d4491e17083106ca49624448fc16186c30a93cf2b58f862bba416d1 + md5: 8e5de39cab514fa908fcaa7ba37a8738 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + license: LGPL-2.0-or-later + license_family: LGPL + purls: [] + size: 38472 + timestamp: 1740593829307 +- conda: https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.2-hb03c661_0.conda + sha256: 755c55ebab181d678c12e49cced893598f2bab22d582fbbf4d8b83c18be207eb + md5: c7c83eecbb72d88b940c249af56c8b17 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + constrains: + - xz 5.8.2.* + license: 0BSD + purls: [] + size: 113207 + timestamp: 1768752626120 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb03c661_1.conda + sha256: fe171ed5cf5959993d43ff72de7596e8ac2853e9021dec0344e583734f1e0843 + md5: 2c21e66f50753a083cbe6b80f38268fa + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + license: BSD-2-Clause + license_family: BSD + purls: [] + size: 92400 + timestamp: 1769482286018 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libnghttp2-1.67.0-had1ee68_0.conda + sha256: a4a7dab8db4dc81c736e9a9b42bdfd97b087816e029e221380511960ac46c690 + md5: b499ce4b026493a13774bcf0f4c33849 + depends: + - __glibc >=2.17,<3.0.a0 + - c-ares >=1.34.5,<2.0a0 + - libev >=4.33,<4.34.0a0 + - libev >=4.33,<5.0a0 - libgcc >=14 + - libstdcxx >=14 + - libzlib >=1.3.1,<2.0a0 + - openssl >=3.5.2,<4.0a0 license: MIT license_family: MIT purls: [] - size: 143991 - timestamp: 1763549744569 -- pypi: https://files.pythonhosted.org/packages/37/f9/f8497ef8b873a8bb2a750ee2a6c5f0fc22258e1acb6245fd237042a6c279/fabric-3.2.3-py3-none-any.whl - name: fabric - version: 3.2.3 - sha256: ce61917f4f398018337ce279b357650a3a74baecf3fdd53a5839013944af965e - requires_dist: - - invoke>=2.0,<3.0 - - paramiko>=2.4 - - decorator>=5 - - deprecated>=1.2 - - pytest>=7 ; extra == 'pytest' -- conda: https://conda.anaconda.org/conda-forge/noarch/filelock-3.20.3-pyhd8ed1ab_0.conda - sha256: 8b90dc21f00167a7e58abb5141a140bdb31a7c5734fe1361b5f98f4a4183fd32 - md5: 2cfaaccf085c133a477f0a7a8657afe9 + size: 666600 + timestamp: 1756834976695 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libntlm-1.8-hb9d3cd8_0.conda + sha256: 3b3f19ced060013c2dd99d9d46403be6d319d4601814c772a3472fe2955612b0 + md5: 7c7927b404672409d9917d49bff5f2d6 depends: - - python >=3.10 - license: Unlicense - purls: - - pkg:pypi/filelock?source=hash-mapping - size: 18661 - timestamp: 1768022315929 -- pypi: https://files.pythonhosted.org/packages/8e/e8/a1185e236ec66c20afd72399522f142c3724c785789255202d27ae992818/frozenlist-1.8.0-cp314-cp314-macosx_10_13_x86_64.whl - name: frozenlist - version: 1.8.0 - sha256: 119fb2a1bd47307e899c2fac7f28e85b9a543864df47aa7ec9d3c1b4545f096f - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/a1/93/72b1736d68f03fda5fdf0f2180fb6caaae3894f1b854d006ac61ecc727ee/frozenlist-1.8.0-cp314-cp314-macosx_11_0_arm64.whl - name: frozenlist - version: 1.8.0 - sha256: 4970ece02dbc8c3a92fcc5228e36a3e933a01a999f7094ff7c23fbd2beeaa67c - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/a7/b2/fabede9fafd976b991e9f1b9c8c873ed86f202889b864756f240ce6dd855/frozenlist-1.8.0-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl - name: frozenlist - version: 1.8.0 - sha256: cba69cb73723c3f329622e34bdbf5ce1f80c21c290ff04256cff1cd3c2036ed2 - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/d5/1f/5f4a3cd9e4440e9d9bc78ad0a91a1c8d46b4d429d5239ebe6793c9fe5c41/fsspec-2026.3.0-py3-none-any.whl - name: fsspec - version: 2026.3.0 - sha256: d2ceafaad1b3457968ed14efa28798162f1638dbb5d2a6868a2db002a5ee39a4 - requires_dist: - - adlfs ; extra == 'abfs' - - adlfs ; extra == 'adl' - - pyarrow>=1 ; extra == 'arrow' - - dask ; extra == 'dask' - - distributed ; extra == 'dask' - - pre-commit ; extra == 'dev' - - ruff>=0.5 ; extra == 'dev' - - numpydoc ; extra == 'doc' - - sphinx ; extra == 'doc' - - sphinx-design ; extra == 'doc' - - sphinx-rtd-theme ; extra == 'doc' - - yarl ; extra == 'doc' - - dropbox ; extra == 'dropbox' - - dropboxdrivefs ; extra == 'dropbox' - - requests ; extra == 'dropbox' - - adlfs ; extra == 'full' - - aiohttp!=4.0.0a0,!=4.0.0a1 ; extra == 'full' - - dask ; extra == 'full' - - distributed ; extra == 'full' - - dropbox ; extra == 'full' - - dropboxdrivefs ; extra == 'full' - - fusepy ; extra == 'full' - - gcsfs>2024.2.0 ; extra == 'full' - - libarchive-c ; extra == 'full' - - ocifs ; extra == 'full' - - panel ; extra == 'full' - - paramiko ; extra == 'full' - - pyarrow>=1 ; extra == 'full' - - pygit2 ; extra == 'full' - - requests ; extra == 'full' - - s3fs>2024.2.0 ; extra == 'full' - - smbprotocol ; extra == 'full' - - tqdm ; extra == 'full' - - fusepy ; extra == 'fuse' - - gcsfs>2024.2.0 ; extra == 'gcs' - - pygit2 ; extra == 'git' - - requests ; extra == 'github' - - gcsfs ; extra == 'gs' - - panel ; extra == 'gui' - - pyarrow>=1 ; extra == 'hdfs' - - aiohttp!=4.0.0a0,!=4.0.0a1 ; extra == 'http' - - libarchive-c ; extra == 'libarchive' - - ocifs ; extra == 'oci' - - s3fs>2024.2.0 ; extra == 's3' - - paramiko ; extra == 'sftp' - - smbprotocol ; extra == 'smb' - - paramiko ; extra == 'ssh' - - aiohttp!=4.0.0a0,!=4.0.0a1 ; extra == 'test' - - numpy ; extra == 'test' - - pytest ; extra == 'test' - - pytest-asyncio!=0.22.0 ; extra == 'test' - - pytest-benchmark ; extra == 'test' - - pytest-cov ; extra == 'test' - - pytest-mock ; extra == 'test' - - pytest-recording ; extra == 'test' - - pytest-rerunfailures ; extra == 'test' - - requests ; extra == 'test' - - aiobotocore>=2.5.4,<3.0.0 ; extra == 'test-downstream' - - dask[dataframe,test] ; extra == 'test-downstream' - - moto[server]>4,<5 ; extra == 'test-downstream' - - pytest-timeout ; extra == 'test-downstream' - - xarray ; extra == 'test-downstream' - - adlfs ; extra == 'test-full' - - aiohttp!=4.0.0a0,!=4.0.0a1 ; extra == 'test-full' - - backports-zstd ; python_full_version < '3.14' and extra == 'test-full' - - cloudpickle ; extra == 'test-full' - - dask ; extra == 'test-full' - - distributed ; extra == 'test-full' - - dropbox ; extra == 'test-full' - - dropboxdrivefs ; extra == 'test-full' - - fastparquet ; extra == 'test-full' - - fusepy ; extra == 'test-full' - - gcsfs ; extra == 'test-full' - - jinja2 ; extra == 'test-full' - - kerchunk ; extra == 'test-full' - - libarchive-c ; extra == 'test-full' - - lz4 ; extra == 'test-full' - - notebook ; extra == 'test-full' - - numpy ; extra == 'test-full' - - ocifs ; extra == 'test-full' - - pandas<3.0.0 ; extra == 'test-full' - - panel ; extra == 'test-full' - - paramiko ; extra == 'test-full' - - pyarrow ; extra == 'test-full' - - pyarrow>=1 ; extra == 'test-full' - - pyftpdlib ; extra == 'test-full' - - pygit2 ; extra == 'test-full' - - pytest ; extra == 'test-full' - - pytest-asyncio!=0.22.0 ; extra == 'test-full' - - pytest-benchmark ; extra == 'test-full' - - pytest-cov ; extra == 'test-full' - - pytest-mock ; extra == 'test-full' - - pytest-recording ; extra == 'test-full' - - pytest-rerunfailures ; extra == 'test-full' - - python-snappy ; extra == 'test-full' - - requests ; extra == 'test-full' - - smbprotocol ; extra == 'test-full' - - tqdm ; extra == 'test-full' - - urllib3 ; extra == 'test-full' - - zarr ; extra == 'test-full' - - zstandard ; python_full_version < '3.14' and extra == 'test-full' - - tqdm ; extra == 'tqdm' - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/73/90/a2c51050d9254bd9134e6368b3f94f92f0eb2c34ed0ca19ec449ce2fc288/fsspec_xrootd-0.5.2-py3-none-any.whl - name: fsspec-xrootd - version: 0.5.2 - sha256: 314763b6f31c01358ffe1fb1dca038085690efbee80ac5f5204f66d0ae9fd417 - requires_dist: - - fsspec - - pytest>=6 ; extra == 'dev' - - sphinx>=4.0 ; extra == 'docs' - - myst-parser>=0.13 ; extra == 'docs' - - sphinx-book-theme>=0.1.0 ; extra == 'docs' - - sphinx-copybutton ; extra == 'docs' - - pytest>=6 ; extra == 'test' - - pytest-rerunfailures ; extra == 'test' - - pytest-timeout ; extra == 'test' - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/5f/e8/2e6301567e6debaad6abae0e217428471651ce877537b7095b6a8e7d8cd2/fts3-3.14.2-py3-none-any.whl - name: fts3 - version: 3.14.2 - sha256: 28528f3656f156dd7cddb02ce82bb88cbaa8ab635d899aa2b97aa838d080bfd4 - requires_dist: - - m2crypto - - requests - - setuptools>=39 - requires_python: '>=3.9' -- conda: https://conda.anaconda.org/conda-forge/linux-64/gct-6.2.1705709074-h6bbaf85_0.conda - sha256: d0dc86c605be9f7de04a3d47524acb4bc8cbf0fd8f77ad2e444913788cb1d360 - md5: 17103926aa1221d9d7520ca55ff09ef9 - depends: - - libedit >=3.1.20191231,<3.2.0a0 - - libgcc-ng >=12 - - libstdcxx-ng >=12 - - libtool >=2.4.7,<3.0a0 - - libzlib >=1.2.13,<2.0.0a0 - - openssl >=3.2.1,<4.0a0 - - perl - license: Apache-2.0 - license_family: Apache - purls: [] - size: 3399111 - timestamp: 1709823867374 -- conda: https://conda.anaconda.org/conda-forge/osx-64/gct-6.2.1705709074-h8d8e280_0.conda - sha256: 02abd54ab941346e41aa65bc32bb51750c24bb559660bc6b5c8710294a489349 - md5: fb76224d23bd06f2dc83791fa56eea23 - depends: - - __osx >=11.0 - - libcxx >=16 - - libedit >=3.1.20191231,<3.2.0a0 - - libtool >=2.4.7,<3.0a0 - - libzlib >=1.2.13,<2.0.0a0 - - openssl >=3.2.1,<4.0a0 - - perl - license: Apache-2.0 - license_family: Apache + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + license: LGPL-2.1-or-later purls: [] - size: 3229688 - timestamp: 1709825282762 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/gct-6.2.1705709074-h07e554c_0.conda - sha256: eaadb01056b490a777e9dfa7fc6f176f41cbb4ae07e434513de680fc561c64f3 - md5: 4703e9e9400e3824297171fd972ce97a + size: 33418 + timestamp: 1734670021371 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.30-pthreads_h94d23a6_4.conda + sha256: 199d79c237afb0d4780ccd2fbf829cea80743df60df4705202558675e07dd2c5 + md5: be43915efc66345cccb3c310b6ed0374 depends: - - libcxx >=16 - - libedit >=3.1.20191231,<3.2.0a0 - - libtool >=2.4.7,<3.0a0 - - libzlib >=1.2.13,<2.0.0a0 - - openssl >=3.2.1,<4.0a0 - - perl - license: Apache-2.0 - license_family: Apache + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - libgfortran + - libgfortran5 >=14.3.0 + constrains: + - openblas >=0.3.30,<0.3.31.0a0 + license: BSD-3-Clause + license_family: BSD purls: [] - size: 3410291 - timestamp: 1709824989090 -- conda: https://conda.anaconda.org/conda-forge/linux-64/gfal2-2.23.5-h3ec3711_0.conda - sha256: f7b7b766a6ed222bd0657db4f9d66e3b1420e8638b7a8aef58bbf26e3e213450 - md5: 31e0c86aff2be99388ab9913e13dac4b + size: 5927939 + timestamp: 1763114673331 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.2-hf4e2dac_0.conda + sha256: 04596fcee262a870e4b7c9807224680ff48d4d0cc0dac076a602503d3dc6d217 + md5: da5be73701eecd0e8454423fd6ffcf30 depends: - - json-c >=0.18,<0.19.0a0 - - libgcc >=14 - __glibc >=2.17,<3.0.a0 - - libstdcxx >=14 - - gtest >=1.17.0,<1.17.1.0a0 - - srm-ifce >=1.24.6,<2.0a0 - - gsoap >=2.8.123,<2.8.124.0a0 + - icu >=78.2,<79.0a0 + - libgcc >=14 - libzlib >=1.3.1,<2.0a0 - - libssh2 >=1.11.1,<2.0a0 - - pugixml >=1.15,<1.16.0a0 - - davix >=0.8.10,<0.9.0a0 - - gct >=6.2.1705709074,<6.2.1705709075.0a0 - - libuuid >=2.41.3,<3.0a0 - - xrootd >=5.8.4,<6.0a0 - - openldap >=2.6.10,<2.7.0a0 - - libglib >=2.86.3,<3.0a0 - - dcap >=2.47.14,<2.48.0a0 - license: Apache-2.0 - license_family: APACHE + license: blessing purls: [] - size: 501235 - timestamp: 1769072269303 -- conda: https://conda.anaconda.org/conda-forge/osx-64/gfal2-2.23.5-h6ef8084_0.conda - sha256: 82333798f4c4980de18baeed6fca6ffadb46cb149fd492f1d0f6c7c471bfebb7 - md5: 982b40947d8ed9d1e7e56cfc00a0cce3 + size: 942808 + timestamp: 1768147973361 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libssh2-1.11.1-hcf80075_0.conda + sha256: fa39bfd69228a13e553bd24601332b7cfeb30ca11a3ca50bb028108fe90a7661 + md5: eecce068c7e4eddeb169591baac20ac4 depends: - - json-c >=0.18,<0.19.0a0 - - libcxx >=19 - - __osx >=10.13 - - libssh2 >=1.11.1,<2.0a0 - - gct >=6.2.1705709074,<6.2.1705709075.0a0 - - libglib >=2.86.3,<3.0a0 - - davix >=0.8.10,<0.9.0a0 - - srm-ifce >=1.24.6,<2.0a0 - - gsoap >=2.8.123,<2.8.124.0a0 - - dcap >=2.47.14,<2.48.0a0 - - gtest >=1.17.0,<1.17.1.0a0 - - openldap >=2.6.10,<2.7.0a0 + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 - libzlib >=1.3.1,<2.0a0 - - pugixml >=1.15,<1.16.0a0 - - libuuid >=2.41.3,<3.0a0 - - xrootd >=5.8.4,<6.0a0 - license: Apache-2.0 - license_family: APACHE + - openssl >=3.5.0,<4.0a0 + license: BSD-3-Clause + license_family: BSD purls: [] - size: 814499 - timestamp: 1769072316410 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/gfal2-2.23.5-h46ca294_0.conda - sha256: 86f943d3531e3636a458c25f9bc11ace03bea4a745f90867cb3d9607f932bd0f - md5: f6fbc5578b64a47c78cc2e7b5b58ffe5 - depends: - - json-c >=0.18,<0.19.0a0 - - libcxx >=19 - - __osx >=11.0 - - srm-ifce >=1.24.6,<2.0a0 - - gsoap >=2.8.123,<2.8.124.0a0 - - davix >=0.8.10,<0.9.0a0 - - dcap >=2.47.14,<2.48.0a0 - - openldap >=2.6.10,<2.7.0a0 - - libglib >=2.86.3,<3.0a0 - - xrootd >=5.8.4,<6.0a0 - - libuuid >=2.41.3,<3.0a0 - - gtest >=1.17.0,<1.17.1.0a0 - - libssh2 >=1.11.1,<2.0a0 - - gct >=6.2.1705709074,<6.2.1705709075.0a0 - - libzlib >=1.3.1,<2.0a0 - - pugixml >=1.15,<1.16.0a0 - license: Apache-2.0 - license_family: APACHE - purls: [] - size: 756388 - timestamp: 1769072357132 -- pypi: https://files.pythonhosted.org/packages/a0/61/5c78b91c3143ed5c14207f463aecfc8f9dbb5092fb2869baf37c273b2705/gitdb-4.0.12-py3-none-any.whl - name: gitdb - version: 4.0.12 - sha256: 67073e15955400952c6565cc3e707c554a4eea2e428946f7a4c162fab9bd9bcf - requires_dist: - - smmap>=3.0.1,<6 - requires_python: '>=3.7' -- pypi: https://files.pythonhosted.org/packages/b0/57/dea471da24ceac6de8c3dc5d37e4ddde57a5c340d6bac90010898734de34/gitlint_core-0.19.1-py3-none-any.whl - name: gitlint-core - version: 0.19.1 - sha256: f41effd1dcbc06ffbfc56b6888cce72241796f517b46bd9fd4ab1b145056988c - requires_dist: - - arrow>=1 - - click>=8 - - importlib-metadata>=1.0 ; python_full_version < '3.8' - - sh>=1.13.0 ; sys_platform != 'win32' - - arrow==1.2.3 ; extra == 'trusted-deps' - - click==8.1.3 ; extra == 'trusted-deps' - - sh==1.14.3 ; sys_platform != 'win32' and extra == 'trusted-deps' - requires_python: '>=3.7' -- pypi: https://files.pythonhosted.org/packages/6a/09/e21df6aef1e1ffc0c816f0522ddc3f6dcded766c3261813131c78a704470/gitpython-3.1.46-py3-none-any.whl - name: gitpython - version: 3.1.46 - sha256: 79812ed143d9d25b6d176a10bb511de0f9c67b1fa641d82097b0ab90398a2058 - requires_dist: - - gitdb>=4.0.1,<5 - - typing-extensions>=3.10.0.2 ; python_full_version < '3.10' - - coverage[toml] ; extra == 'test' - - ddt>=1.1.1,!=1.4.3 ; extra == 'test' - - mock ; python_full_version < '3.8' and extra == 'test' - - mypy==1.18.2 ; python_full_version >= '3.9' and extra == 'test' - - pre-commit ; extra == 'test' - - pytest>=7.3.1 ; extra == 'test' - - pytest-cov ; extra == 'test' - - pytest-instafail ; extra == 'test' - - pytest-mock ; extra == 'test' - - pytest-sugar ; extra == 'test' - - typing-extensions ; python_full_version < '3.11' and extra == 'test' - - sphinx>=7.1.2,<7.2 ; extra == 'doc' - - sphinx-rtd-theme ; extra == 'doc' - - sphinx-autodoc-typehints ; extra == 'doc' - requires_python: '>=3.7' -- pypi: https://files.pythonhosted.org/packages/80/38/9d42d60dffb04b45f03dbab9430898352dba277758640751dc5cc316c521/greenlet-3.3.1-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl - name: greenlet - version: 3.3.1 - sha256: 34a729e2e4e4ffe9ae2408d5ecaf12f944853f40ad724929b7585bca808a9d6f - requires_dist: - - sphinx ; extra == 'docs' - - furo ; extra == 'docs' - - objgraph ; extra == 'test' - - psutil ; extra == 'test' - - setuptools ; extra == 'test' - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/ae/fb/011c7c717213182caf78084a9bea51c8590b0afda98001f69d9f853a495b/greenlet-3.3.1-cp314-cp314-macosx_11_0_universal2.whl - name: greenlet - version: 3.3.1 - sha256: bd59acd8529b372775cd0fcbc5f420ae20681c5b045ce25bd453ed8455ab99b5 - requires_dist: - - sphinx ; extra == 'docs' - - furo ; extra == 'docs' - - objgraph ; extra == 'test' - - psutil ; extra == 'test' - - setuptools ; extra == 'test' - requires_python: '>=3.10' -- conda: https://conda.anaconda.org/conda-forge/linux-64/gsoap-2.8.123-h8dc497d_0.tar.bz2 - sha256: c6a16f2b36a6a653d399cc542214b3601c54097dd5f6c4b96a0f3302d3d6480d - md5: e539f696d01d28dc42313a2ce66c0627 + size: 304790 + timestamp: 1745608545575 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_17.conda + sha256: 50c48cd3716a2e58e8e2e02edc78fef2d08fffe1e3b1ed40eb5f87e7e2d07889 + md5: 24c2fe35fa45cd71214beba6f337c071 depends: - - libgcc-ng >=12 - - libstdcxx-ng >=12 - - libzlib >=1.2.12,<2.0.0a0 - - openssl >=3.0.5,<4.0a0 - license: GPL-2.0-only - license_family: GPL + - __glibc >=2.17,<3.0.a0 + - libgcc 15.2.0 he0feb66_17 + constrains: + - libstdcxx-ng ==15.2.0=*_17 + license: GPL-3.0-only WITH GCC-exception-3.1 purls: [] - size: 1911621 - timestamp: 1662007838768 -- conda: https://conda.anaconda.org/conda-forge/osx-64/gsoap-2.8.123-h21ae599_0.tar.bz2 - sha256: 6ddba7cd259edbe80e153dcc6f239f1391ff9277af62b0cf935e1060d74dcedd - md5: b5c0854d2a52f20ea68fa9c29a68b786 + size: 5852406 + timestamp: 1770252584235 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_17.conda + sha256: ca3fb322dab3373946b1064da686ec076f5b1b9caf0a2823dad00d0b0f704928 + md5: ea12f5a6bf12c88c06750d9803e1a570 depends: - - libcxx >=14.0.4 - - libzlib >=1.2.12,<2.0.0a0 - - openssl >=3.0.5,<4.0a0 - license: GPL-2.0-only - license_family: GPL + - libstdcxx 15.2.0 h934c35e_17 + license: GPL-3.0-only WITH GCC-exception-3.1 purls: [] - size: 1844166 - timestamp: 1662007947987 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/gsoap-2.8.123-hfb11b17_0.tar.bz2 - sha256: c0cb7fc084ecf7a522044010d755ee697b878e82a8f579db29bf36c473ae18ba - md5: e01fe9aa10adaca07d0b9bcd073fab52 + size: 27573 + timestamp: 1770252638797 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libtool-2.5.4-h5888daf_0.conda + sha256: c8245c70ba5b075e0cd61f430afbda00b60931603ed4ea31ce89e7fe930e4e3d + md5: 90697d80c181414aa3472199e136a04e depends: - - libcxx >=14.0.4 - - libzlib >=1.2.12,<2.0.0a0 - - openssl >=3.0.5,<4.0a0 - license: GPL-2.0-only + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + - libltdl 2.4.3a h5888daf_0 + license: GPL-2.0-or-later license_family: GPL purls: [] - size: 1907483 - timestamp: 1662008204245 -- conda: https://conda.anaconda.org/conda-forge/linux-64/gtest-1.17.0-h84d6215_1.conda - sha256: 1f738280f245863c5ac78bcc04bb57266357acda45661c4aa25823030c6fb5db - md5: 55e29b72a71339bc651f9975492db71f + size: 415044 + timestamp: 1740593851157 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.3-h5347b49_0.conda + sha256: 1a7539cfa7df00714e8943e18de0b06cceef6778e420a5ee3a2a145773758aee + md5: db409b7c1720428638e7c0d509d3e1b5 depends: - __glibc >=2.17,<3.0.a0 - - libgcc >=13 - - libstdcxx >=13 - constrains: - - gmock 1.17.0 + - libgcc >=14 license: BSD-3-Clause license_family: BSD purls: [] - size: 416610 - timestamp: 1748320117187 -- conda: https://conda.anaconda.org/conda-forge/osx-64/gtest-1.17.0-h9275861_1.conda - sha256: 95410f5b305170b65a8dca803981f9972051aaad3d7a5af608b94b2c2a56f88a - md5: 00ff8e205f86bf121c07c95f65205713 + size: 40311 + timestamp: 1766271528534 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libxcrypt-4.4.36-hd590300_1.conda + sha256: 6ae68e0b86423ef188196fff6207ed0c8195dd84273cb5623b85aa08033a410c + md5: 5aa797f8787fe7a17d1b0821485b5adc depends: - - __osx >=10.13 - - libcxx >=18 + - libgcc-ng >=12 + license: LGPL-2.1-or-later + purls: [] + size: 100393 + timestamp: 1702724383534 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libxml2-16-2.15.1-hca6bf5a_1.conda + sha256: 8331284bf9ae641b70cdc0e5866502dd80055fc3b9350979c74bb1d192e8e09e + md5: 3fdd8d99683da9fe279c2f4cecd1e048 + depends: + - __glibc >=2.17,<3.0.a0 + - icu >=78.1,<79.0a0 + - libgcc >=14 + - libiconv >=1.18,<2.0a0 + - liblzma >=5.8.1,<6.0a0 + - libzlib >=1.3.1,<2.0a0 constrains: - - gmock 1.17.0 - license: BSD-3-Clause - license_family: BSD + - libxml2 2.15.1 + license: MIT + license_family: MIT purls: [] - size: 391059 - timestamp: 1748320150242 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/gtest-1.17.0-ha393de7_1.conda - sha256: 441fb779db5f14eff8997ddde88c90c30ab64ea8bd4c219b76724e4d3d736c76 - md5: f277a9eb8063fe7c4e33d91b8296fb0c + size: 555747 + timestamp: 1766327145986 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.15.1-he237659_1.conda + sha256: 047be059033c394bd32ae5de66ce389824352120b3a7c0eff980195f7ed80357 + md5: 417955234eccd8f252b86a265ccdab7f depends: - - __osx >=11.0 - - libcxx >=18 + - __glibc >=2.17,<3.0.a0 + - icu >=78.1,<79.0a0 + - libgcc >=14 + - libiconv >=1.18,<2.0a0 + - liblzma >=5.8.1,<6.0a0 + - libxml2-16 2.15.1 hca6bf5a_1 + - libzlib >=1.3.1,<2.0a0 + license: MIT + license_family: MIT + purls: [] + size: 45402 + timestamp: 1766327161688 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libxml2-devel-2.15.1-he237659_1.conda + sha256: 6621eb70375ff867c7c6606c216139e47eade8dfad78bcf7bdd0a62dc87d629f + md5: 644b2a3a92ba0bb8e2aa671dd831e793 + depends: + - __glibc >=2.17,<3.0.a0 + - icu >=78.1,<79.0a0 + - libgcc >=14 + - libiconv >=1.18,<2.0a0 + - liblzma >=5.8.1,<6.0a0 + - libxml2 2.15.1 he237659_1 + - libxml2-16 2.15.1 hca6bf5a_1 + - libzlib >=1.3.1,<2.0a0 + license: MIT + license_family: MIT + purls: [] + size: 79680 + timestamp: 1766327176426 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda + sha256: d4bfe88d7cb447768e31650f06257995601f89076080e76df55e3112d4e47dc4 + md5: edb0dca6bc32e4f4789199455a1dbeb8 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 constrains: - - gmock 1.17.0 - license: BSD-3-Clause - license_family: BSD + - zlib 1.3.1 *_2 + license: Zlib + license_family: Other purls: [] - size: 378391 - timestamp: 1748320218212 -- pypi: https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl - name: h11 - version: 0.16.0 - sha256: 63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86 - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl - name: httpcore - version: 1.0.9 - sha256: 2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55 - requires_dist: - - certifi - - h11>=0.16 - - anyio>=4.0,<5.0 ; extra == 'asyncio' - - h2>=3,<5 ; extra == 'http2' - - socksio==1.* ; extra == 'socks' - - trio>=0.22.0,<1.0 ; extra == 'trio' - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl - name: httpx - version: 0.28.1 - sha256: d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad - requires_dist: - - anyio - - certifi - - httpcore==1.* - - idna - - brotli ; platform_python_implementation == 'CPython' and extra == 'brotli' - - brotlicffi ; platform_python_implementation != 'CPython' and extra == 'brotli' - - click==8.* ; extra == 'cli' - - pygments==2.* ; extra == 'cli' - - rich>=10,<14 ; extra == 'cli' - - h2>=3,<5 ; extra == 'http2' - - socksio==1.* ; extra == 'socks' - - zstandard>=0.18.0 ; extra == 'zstd' - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/f0/0f/310fb31e39e2d734ccaa2c0fb981ee41f7bd5056ce9bc29b2248bd569169/humanfriendly-10.0-py2.py3-none-any.whl - name: humanfriendly - version: '10.0' - sha256: 1697e1a8a8f550fd43c2865cd84542fc175a61dcb779b6fee18cf6b6ccba1477 - requires_dist: - - monotonic ; python_full_version == '2.7.*' - - pyreadline ; python_full_version < '3.8' and sys_platform == 'win32' - - pyreadline3 ; python_full_version >= '3.8' and sys_platform == 'win32' - requires_python: '>=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*' -- pypi: https://files.pythonhosted.org/packages/22/ed/9c45c468fd6c31df3fe0622394b1853c00b86545d1e297f3fb9fba1232ce/hyperscan-0.8.2-cp314-cp314-macosx_10_15_x86_64.whl - name: hyperscan - version: 0.8.2 - sha256: 2c579c1ebccc384d904de4a20e7a105df6041dd82adb54cb9acd5bb19b9b07dc - requires_python: '>=3.9,<4.0' -- pypi: https://files.pythonhosted.org/packages/d0/23/49cf8ea1d129637941f06fb78f5f66077bf362762c5f6c01712c4cd0e87f/hyperscan-0.8.2-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl - name: hyperscan - version: 0.8.2 - sha256: 0c0af5d882bd6afb61e2b9a13c0d39fcbcee49c62f392096d6303bd34452813f - requires_python: '>=3.9,<4.0' -- pypi: https://files.pythonhosted.org/packages/d8/da/a8bb48a4fee86b5dad8a358559b70b010cd7effaa70ca5bb4e6e82e13703/hyperscan-0.8.2-cp314-cp314-macosx_11_0_arm64.whl - name: hyperscan - version: 0.8.2 - sha256: 4e9f8d1ae2c9596385d906e062b9e0081ae843e3975fd4a656e5fcf6bbc48c13 - requires_python: '>=3.9,<4.0' -- conda: https://conda.anaconda.org/conda-forge/linux-64/icu-78.2-h33c6efd_0.conda - sha256: 142a722072fa96cf16ff98eaaf641f54ab84744af81754c292cb81e0881c0329 - md5: 186a18e3ba246eccfc7cff00cd19a870 + size: 60963 + timestamp: 1727963148474 +- conda: https://conda.anaconda.org/conda-forge/linux-64/m2crypto-0.45.1-py314haf11619_2.conda + sha256: f923b3fcc7875c24e21d6de6841fdacc150ca87146aa2a0ebcf39c0c9e7572fd + md5: edaeb576dc4f23f2063787f62da70fef depends: + - openssl + - python - __glibc >=2.17,<3.0.a0 - libgcc >=14 - - libstdcxx >=14 + - openssl >=3.5.2,<4.0a0 + - python_abi 3.14.* *_cp314 license: MIT license_family: MIT - purls: [] - size: 12728445 - timestamp: 1767969922681 -- conda: https://conda.anaconda.org/conda-forge/osx-64/icu-78.2-h14c5de8_0.conda - sha256: f3066beae7fe3002f09c8a412cdf1819f49a2c9a485f720ec11664330cf9f1fe - md5: 30334add4de016489b731c6662511684 + purls: + - pkg:pypi/m2crypto?source=hash-mapping + size: 413718 + timestamp: 1757689047646 +- conda: https://conda.anaconda.org/conda-forge/linux-64/mypy-1.19.1-py314h5bd0f2a_0.conda + sha256: 4e607095b92cac2ec6dbb8de348d8e006408291c9c2805926f01e4a30e94edbb + md5: 0490f2b08d179719201fdb9514d67157 depends: - - __osx >=10.13 + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - mypy_extensions >=1.0.0 + - pathspec >=0.9.0 + - psutil >=4.0 + - python >=3.14,<3.15.0a0 + - python-librt >=0.6.2 + - python_abi 3.14.* *_cp314 + - typing_extensions >=4.6.0 license: MIT license_family: MIT - purls: [] - size: 12263724 - timestamp: 1767970604977 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/icu-78.2-h38cb7af_0.conda - sha256: d4cefbca587429d1192509edc52c88de52bc96c2447771ddc1f8bee928aed5ef - md5: 1e93aca311da0210e660d2247812fa02 + purls: + - pkg:pypi/mypy?source=hash-mapping + size: 18632958 + timestamp: 1765795548407 +- conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda + sha256: 3fde293232fa3fca98635e1167de6b7c7fda83caf24b9d6c91ec9eefb4f4d586 + md5: 47e340acb35de30501a76c7c799c41d7 depends: - - __osx >=11.0 - license: MIT - license_family: MIT + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + license: X11 AND BSD-3-Clause purls: [] - size: 12358010 - timestamp: 1767970350308 -- conda: https://conda.anaconda.org/conda-forge/noarch/identify-2.6.16-pyhd8ed1ab_0.conda - sha256: 6a88cdde151469131df1948839ac2315ada99cf8d38aaacc9a7a5984e9cd8c19 - md5: 8bc5851c415865334882157127e75799 - depends: - - python >=3.10 - - ukkonen - license: MIT - license_family: MIT - purls: - - pkg:pypi/identify?source=compressed-mapping - size: 79302 - timestamp: 1768295306539 -- pypi: https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl - name: idna - version: '3.11' - sha256: 771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea - requires_dist: - - ruff>=0.6.2 ; extra == 'all' - - mypy>=1.11.2 ; extra == 'all' - - pytest>=8.3.2 ; extra == 'all' - - flake8>=7.1.1 ; extra == 'all' - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/fa/5e/f8e9a1d23b9c20a551a8a02ea3637b4642e22c2626e3a13a9a29cdea99eb/importlib_metadata-8.7.1-py3-none-any.whl - name: importlib-metadata - version: 8.7.1 - sha256: 5a1f80bf1daa489495071efbb095d75a634cf28a8bc299581244063b53176151 - requires_dist: - - zipp>=3.20 - - pytest>=6,!=8.1.* ; extra == 'test' - - packaging ; extra == 'test' - - pyfakefs ; extra == 'test' - - flufl-flake8 ; extra == 'test' - - pytest-perf>=0.9.2 ; extra == 'test' - - jaraco-test>=5.4 ; extra == 'test' - - sphinx>=3.5 ; extra == 'doc' - - jaraco-packaging>=9.3 ; extra == 'doc' - - rst-linker>=1.9 ; extra == 'doc' - - furo ; extra == 'doc' - - sphinx-lint ; extra == 'doc' - - jaraco-tidelift>=1.4 ; extra == 'doc' - - ipython ; extra == 'perf' - - pytest-checkdocs>=2.4 ; extra == 'check' - - pytest-ruff>=0.2.1 ; sys_platform != 'cygwin' and extra == 'check' - - pytest-cov ; extra == 'cover' - - pytest-enabler>=3.4 ; extra == 'enabler' - - pytest-mypy>=1.0.1 ; extra == 'type' - - mypy<1.19 ; platform_python_implementation == 'PyPy' and extra == 'type' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/a4/ed/1f1afb2e9e7f38a545d628f864d562a5ae64fe6f7a10e28ffb9b185b4e89/importlib_resources-6.5.2-py3-none-any.whl - name: importlib-resources - version: 6.5.2 - sha256: 789cfdc3ed28c78b67a06acb8126751ced69a3d5f79c095a98298cd8a760ccec - requires_dist: - - zipp>=3.1.0 ; python_full_version < '3.10' - - pytest>=6,!=8.1.* ; extra == 'test' - - zipp>=3.17 ; extra == 'test' - - jaraco-test>=5.4 ; extra == 'test' - - sphinx>=3.5 ; extra == 'doc' - - jaraco-packaging>=9.3 ; extra == 'doc' - - rst-linker>=1.9 ; extra == 'doc' - - furo ; extra == 'doc' - - sphinx-lint ; extra == 'doc' - - jaraco-tidelift>=1.4 ; extra == 'doc' - - pytest-checkdocs>=2.4 ; extra == 'check' - - pytest-ruff>=0.2.1 ; sys_platform != 'cygwin' and extra == 'check' - - pytest-cov ; extra == 'cover' - - pytest-enabler>=2.2 ; extra == 'enabler' - - pytest-mypy ; extra == 'type' - requires_python: '>=3.9' -- conda: https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda - sha256: e1a9e3b1c8fe62dc3932a616c284b5d8cbe3124bbfbedcf4ce5c828cb166ee19 - md5: 9614359868482abba1bd15ce465e3c42 + size: 891641 + timestamp: 1738195959188 +- conda: https://conda.anaconda.org/conda-forge/linux-64/numpy-2.4.2-py314h2b28147_1.conda + sha256: 1d8377c8001c15ed12c2713b723213474b435706ab9d34ede69795d64af9e94d + md5: 4ea6b620fdf24a1a0bc4f1c7134dfafb depends: - - python >=3.10 - license: MIT - license_family: MIT + - python + - libstdcxx >=14 + - libgcc >=14 + - __glibc >=2.17,<3.0.a0 + - libcblas >=3.9.0,<4.0a0 + - python_abi 3.14.* *_cp314 + - libblas >=3.9.0,<4.0a0 + - liblapack >=3.9.0,<4.0a0 + constrains: + - numpy-base <0a0 + license: BSD-3-Clause + license_family: BSD purls: - - pkg:pypi/iniconfig?source=compressed-mapping - size: 13387 - timestamp: 1760831448842 -- pypi: https://files.pythonhosted.org/packages/32/4b/b99e37f88336009971405cbb7630610322ed6fbfa31e1d7ab3fbf3049a2d/invoke-2.2.1-py3-none-any.whl - name: invoke - version: 2.2.1 - sha256: 2413bc441b376e5cd3f55bb5d364f973ad8bdd7bf87e53c79de3c11bf3feecc8 - requires_python: '>=3.6' -- pypi: https://files.pythonhosted.org/packages/15/aa/0aca39a37d3c7eb941ba736ede56d689e7be91cab5d9ca846bde3999eba6/isodate-0.7.2-py3-none-any.whl - name: isodate - version: 0.7.2 - sha256: 28009937d8031054830160fce6d409ed342816b543597cece116d966c6d99e15 - requires_python: '>=3.7' -- pypi: https://files.pythonhosted.org/packages/14/2f/967ba146e6d58cf6a652da73885f52fc68001525b4197effc174321d70b4/jmespath-1.1.0-py3-none-any.whl - name: jmespath - version: 1.1.0 - sha256: a5663118de4908c91729bea0acadca56526eb2698e83de10cd116ae0f4e97c64 - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/a1/01/9674cc6d478406ae61d910cb16ca8b5699a8a9e6a2019987ebe5a5957d1d/joserfc-1.6.1-py3-none-any.whl - name: joserfc - version: 1.6.1 - sha256: 74d158c9d56be54c710cdcb2a0741372254b682ad2101a0f72e5bd0e925695f0 - requires_dist: - - cryptography>=45.0.1 - - pycryptodome ; extra == 'drafts' - requires_python: '>=3.9' -- conda: https://conda.anaconda.org/conda-forge/linux-64/json-c-0.18-h6688a6e_0.conda - sha256: 09e706cb388d3ea977fabcee8e28384bdaad8ce1fc49340df5f868a2bd95a7da - md5: 38f5dbc9ac808e31c00650f7be1db93f + - pkg:pypi/numpy?source=compressed-mapping + size: 8926994 + timestamp: 1770098474394 +- conda: https://conda.anaconda.org/conda-forge/linux-64/openldap-2.6.10-he970967_0.conda + sha256: cb0b07db15e303e6f0a19646807715d28f1264c6350309a559702f4f34f37892 + md5: 2e5bf4f1da39c0b32778561c3c4e5878 depends: - __glibc >=2.17,<3.0.a0 + - cyrus-sasl >=2.1.27,<3.0a0 + - krb5 >=1.21.3,<1.22.0a0 - libgcc >=13 - license: MIT - license_family: MIT + - libstdcxx >=13 + - openssl >=3.5.0,<4.0a0 + license: OLDAP-2.8 + license_family: BSD purls: [] - size: 82709 - timestamp: 1726487116178 -- conda: https://conda.anaconda.org/conda-forge/osx-64/json-c-0.18-hc62ec3d_0.conda - sha256: b58f8002318d6b880a98e1b0aa943789b3b0f49334a3bdb9c19b463a0b799cad - md5: 2c5a3c42de607dda0cfa0edd541fd279 + size: 780253 + timestamp: 1748010165522 +- conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.1-h35e630c_1.conda + sha256: 44c877f8af015332a5d12f5ff0fb20ca32f896526a7d0cdb30c769df1144fb5c + md5: f61eb8cd60ff9057122a3d338b99c00f depends: - - __osx >=10.13 - license: MIT - license_family: MIT - purls: [] - size: 71514 - timestamp: 1726487153769 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/json-c-0.18-he4178ee_0.conda - sha256: 73179a1cd0b45c09d4f631cb359d9e755e6e573c5d908df42006728e0bf8297c - md5: 94f14ef6157687c30feb44e1abecd577 + - __glibc >=2.17,<3.0.a0 + - ca-certificates + - libgcc >=14 + license: Apache-2.0 + license_family: Apache + purls: [] + size: 3164551 + timestamp: 1769555830639 +- conda: https://conda.anaconda.org/conda-forge/linux-64/pcre2-10.47-haa7fec5_0.conda + sha256: 5e6f7d161356fefd981948bea5139c5aa0436767751a6930cb1ca801ebb113ff + md5: 7a3bff861a6583f1889021facefc08b1 depends: - - __osx >=11.0 + - __glibc >=2.17,<3.0.a0 + - bzip2 >=1.0.8,<2.0a0 + - libgcc >=14 + - libzlib >=1.3.1,<2.0a0 + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 1222481 + timestamp: 1763655398280 +- conda: https://conda.anaconda.org/conda-forge/linux-64/perl-5.32.1-7_hd590300_perl5.conda + build_number: 7 + sha256: 9ec32b6936b0e37bcb0ed34f22ec3116e75b3c0964f9f50ecea5f58734ed6ce9 + md5: f2cfec9406850991f4e3d960cc9e3321 + depends: + - libgcc-ng >=12 + - libxcrypt >=4.4.36 + license: GPL-1.0-or-later OR Artistic-1.0-Perl + purls: [] + size: 13344463 + timestamp: 1703310653947 +- conda: https://conda.anaconda.org/conda-forge/linux-64/psutil-7.2.2-py314h0f05182_0.conda + sha256: f15574ed6c8c8ed8c15a0c5a00102b1efe8b867c0bd286b498cd98d95bd69ae5 + md5: 4f225a966cfee267a79c5cb6382bd121 + depends: + - python + - libgcc >=14 + - __glibc >=2.17,<3.0.a0 + - python_abi 3.14.* *_cp314 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/psutil?source=compressed-mapping + size: 231303 + timestamp: 1769678156552 +- conda: https://conda.anaconda.org/conda-forge/linux-64/pugixml-1.15-h3f63f65_0.conda + sha256: 23c98a5000356e173568dc5c5770b53393879f946f3ace716bbdefac2a8b23d2 + md5: b11a4c6bf6f6f44e5e143f759ffa2087 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + - libstdcxx >=13 license: MIT license_family: MIT purls: [] - size: 73715 - timestamp: 1726487214495 -- conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-4.26.0-pyhcf101f3_0.conda - sha256: db973a37d75db8e19b5f44bbbdaead0c68dde745407f281e2a7fe4db74ec51d7 - md5: ada41c863af263cc4c5fcbaff7c3e4dc + size: 118488 + timestamp: 1736601364156 +- conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.14.3-h32b2ec7_100_cp314.conda + build_number: 100 + sha256: ff087b19d158644d3b0708eca10a5e40d692cdc8e95f53715f4490c6959f3768 + md5: b40594d5da041824087eebe12228af42 + depends: + - __glibc >=2.17,<3.0.a0 + - bzip2 >=1.0.8,<2.0a0 + - ld_impl_linux-64 >=2.36.1 + - libexpat >=2.7.3,<3.0a0 + - libffi >=3.5.2,<3.6.0a0 + - libgcc >=14 + - liblzma >=5.8.2,<6.0a0 + - libmpdec >=4.0.0,<5.0a0 + - libsqlite >=3.51.2,<4.0a0 + - libuuid >=2.41.3,<3.0a0 + - libzlib >=1.3.1,<2.0a0 + - ncurses >=6.5,<7.0a0 + - openssl >=3.5.5,<4.0a0 + - python_abi 3.14.* *_cp314 + - readline >=8.3,<9.0a0 + - tk >=8.6.13,<8.7.0a0 + - tzdata + - zstd >=1.5.7,<1.6.0a0 + license: Python-2.0 + purls: [] + size: 36529771 + timestamp: 1770271970971 + python_site_packages_path: lib/python3.14/site-packages +- conda: https://conda.anaconda.org/conda-forge/linux-64/python-gfal2-1.13.1-py314h1571e64_2.conda + sha256: a549f56ae1e753ffba31b69f42889a9e45112f572a538c2d2c21d114da7aca39 + md5: 5f47942674eda34dbd006be72b036e6b + depends: + - python + - libgcc >=14 + - __glibc >=2.17,<3.0.a0 + - libstdcxx >=14 + - libboost-python >=1.88.0,<1.89.0a0 + - libglib >=2.86.3,<3.0a0 + - gfal2 >=2.23.5,<2.24.0a0 + - python_abi 3.14.* *_cp314 + license: Apache-2.0 + license_family: APACHE + purls: + - pkg:pypi/gfal2-python?source=hash-mapping + size: 201775 + timestamp: 1769083114809 +- conda: https://conda.anaconda.org/conda-forge/linux-64/python-librt-0.7.8-py314h0f05182_0.conda + sha256: 7c4615367e1d8bee1e98abcfccd742fb0c382a150f21cb592a66af69063eae43 + md5: 1cdbb8798d700d90f33998d41baed1ec depends: - - attrs >=22.2.0 - - jsonschema-specifications >=2023.3.6 - - python >=3.10 - - referencing >=0.28.4 - - rpds-py >=0.25.0 - python + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - python_abi 3.14.* *_cp314 license: MIT license_family: MIT purls: - - pkg:pypi/jsonschema?source=compressed-mapping - size: 82356 - timestamp: 1767839954256 -- conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-specifications-2025.9.1-pyhcf101f3_0.conda - sha256: 0a4f3b132f0faca10c89fdf3b60e15abb62ded6fa80aebfc007d05965192aa04 - md5: 439cd0f567d697b20a8f45cb70a1005a + - pkg:pypi/librt?source=hash-mapping + size: 64072 + timestamp: 1768406896488 +- conda: https://conda.anaconda.org/conda-forge/linux-64/pyyaml-6.0.3-py314h67df5f8_1.conda + sha256: b318fb070c7a1f89980ef124b80a0b5ccf3928143708a85e0053cde0169c699d + md5: 2035f68f96be30dc60a5dfd7452c7941 depends: - - python >=3.10 - - referencing >=0.31.0 - - python + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - python >=3.14,<3.15.0a0 + - python_abi 3.14.* *_cp314 + - yaml >=0.2.5,<0.3.0a0 license: MIT license_family: MIT purls: - - pkg:pypi/jsonschema-specifications?source=hash-mapping - size: 19236 - timestamp: 1757335715225 -- conda: https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.3-hb9d3cd8_0.conda - sha256: 0960d06048a7185d3542d850986d807c6e37ca2e644342dd0c72feefcf26c2a4 - md5: b38117a3c920364aff79f870c984b4a3 + - pkg:pypi/pyyaml?source=compressed-mapping + size: 202391 + timestamp: 1770223462836 +- conda: https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda + sha256: 12ffde5a6f958e285aa22c191ca01bbd3d6e710aa852e00618fa6ddc59149002 + md5: d7d95fc8287ea7bf33e0e7116d2b95ec depends: - __glibc >=2.17,<3.0.a0 - - libgcc >=13 - license: LGPL-2.1-or-later + - libgcc >=14 + - ncurses >=6.5,<7.0a0 + license: GPL-3.0-only + license_family: GPL purls: [] - size: 134088 - timestamp: 1754905959823 -- conda: https://conda.anaconda.org/conda-forge/linux-64/krb5-1.21.3-h659f571_0.conda - sha256: 99df692f7a8a5c27cd14b5fb1374ee55e756631b9c3d659ed3ee60830249b238 - md5: 3f43953b7d3fb3aaa1d0d0723d91e368 + size: 345073 + timestamp: 1765813471974 +- conda: https://conda.anaconda.org/conda-forge/linux-64/rpds-py-0.30.0-py314h2e6c369_0.conda + sha256: e53b0cbf3b324eaa03ca1fe1a688fdf4ab42cea9c25270b0a7307d8aaaa4f446 + md5: c1c368b5437b0d1a68f372ccf01cb133 depends: - - keyutils >=1.6.1,<2.0a0 - - libedit >=3.1.20191231,<3.2.0a0 - - libedit >=3.1.20191231,<4.0a0 - - libgcc-ng >=12 - - libstdcxx-ng >=12 - - openssl >=3.3.1,<4.0a0 + - python + - libgcc >=14 + - __glibc >=2.17,<3.0.a0 + - python_abi 3.14.* *_cp314 + constrains: + - __glibc >=2.17 license: MIT license_family: MIT - purls: [] - size: 1370023 - timestamp: 1719463201255 -- conda: https://conda.anaconda.org/conda-forge/osx-64/krb5-1.21.3-h37d8d59_0.conda - sha256: 83b52685a4ce542772f0892a0f05764ac69d57187975579a0835ff255ae3ef9c - md5: d4765c524b1d91567886bde656fb514b + purls: + - pkg:pypi/rpds-py?source=hash-mapping + size: 376121 + timestamp: 1764543122774 +- conda: https://conda.anaconda.org/conda-forge/linux-64/ruff-0.15.0-h40fa522_0.conda + noarch: python + sha256: fc456645570586c798d2da12fe723b38ea0d0901373fd9959cab914cbb19518b + md5: fe90be2abf12b301dde984719a02ca0b depends: - - __osx >=10.13 - - libcxx >=16 - - libedit >=3.1.20191231,<3.2.0a0 - - libedit >=3.1.20191231,<4.0a0 - - openssl >=3.3.1,<4.0a0 + - python + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + constrains: + - __glibc >=2.17 license: MIT license_family: MIT + purls: + - pkg:pypi/ruff?source=compressed-mapping + size: 9103793 + timestamp: 1770153712370 +- conda: https://conda.anaconda.org/conda-forge/linux-64/scitokens-cpp-1.3.0-h096d96b_0.conda + sha256: 11ad442837d2bd3c856c8a7ed08754ca430e6779999d898d1fa313fcd670458c + md5: 946024dbdba971eeda33da76ae586694 + depends: + - __glibc >=2.17,<3.0.a0 + - libcurl >=8.18.0,<9.0a0 + - libgcc >=14 + - libsqlite >=3.51.2,<4.0a0 + - libstdcxx >=14 + - libuuid >=2.41.3,<3.0a0 + - openssl >=3.5.5,<4.0a0 + license: Apache-2.0 + license_family: APACHE purls: [] - size: 1185323 - timestamp: 1719463492984 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/krb5-1.21.3-h237132a_0.conda - sha256: 4442f957c3c77d69d9da3521268cad5d54c9033f1a73f99cde0a3658937b159b - md5: c6dc8a0fdec13a0565936655c33069a1 + size: 2227714 + timestamp: 1769697062631 +- conda: https://conda.anaconda.org/conda-forge/linux-64/srm-ifce-1.24.6-h3b26d37_2.conda + sha256: 994e04767e2fa540c43ffb96397835154a7fcc5b7bd9281d0923615f2f208352 + md5: a84d7ea541bfada40c748035211a9ce9 depends: - - __osx >=11.0 - - libcxx >=16 - - libedit >=3.1.20191231,<3.2.0a0 - - libedit >=3.1.20191231,<4.0a0 - - openssl >=3.3.1,<4.0a0 - license: MIT - license_family: MIT + - cgsi-gsoap >=1.3.11,<1.4.0a0 + - gct >=6.2.1705709074,<6.2.1705709075.0a0 + - gsoap >=2.8.123,<2.8.124.0a0 + - libgcc-ng >=12 + - libglib >=2.78.4,<3.0a0 + - libstdcxx-ng >=12 + - openssl >=3.2.1,<4.0a0 + license: Apache-2.0 + license_family: Apache purls: [] - size: 1155530 - timestamp: 1719463474401 -- pypi: https://files.pythonhosted.org/packages/ba/24/c65fe1aef4e0681cb17ca136eb0f3e20a47d3941a306bc9d636938029ca5/lb_telemetry-0.5.0-py3-none-any.whl - name: lb-telemetry - version: 0.5.0 - sha256: 45c2ef5a5bdb98446f0a57b71742ef76b0a3add44e58ab059761ccc5d6fd1bbf - requires_dist: - - lbplatformutils - - logzero - - requests - - mypy ; extra == 'dev' - - mypy-extensions ; extra == 'dev' - - pre-commit ; extra == 'dev' - - pytest ; extra == 'dev' - - pytest-cov ; extra == 'dev' - - ruff ; extra == 'dev' - - types-requests ; extra == 'dev' -- pypi: https://files.pythonhosted.org/packages/87/a4/afc9dddc6b14fb3d52a900cd9b4c77770128edc4b07e576034bbd0ffd290/LbCondaWrappers-0.5.2-py3-none-any.whl - name: lbcondawrappers - version: 0.5.2 - sha256: 4200c89661017bc28b910aa040092970c357f4130375d84ec14a258adf8318e0 - requires_dist: - - lb-telemetry>=0.5.0 - - pytest ; extra == 'testing' - - pytest-cov ; extra == 'testing' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/d7/4c/f3b97c7d6008b3a895bbadb2deb44ad3446ae5fe204c72cd540dc222e57d/lbenv-2.4.0-py3-none-any.whl - name: lbenv - version: 2.4.0 - sha256: 5fb13304ea4d2c9f9b9a4f0710d3931ec9cd45f173581afa17a330d2635bed7e - requires_dist: - - lbplatformutils>=4.2.3 - - xenv<1.0.0 - - importlib-resources - - importlib-metadata - - pytest ; extra == 'testing' - - pytest-cov ; extra == 'testing' - - coverage ; extra == 'testing' - requires_python: '>=3.7' -- pypi: https://files.pythonhosted.org/packages/6d/10/b37ac718c5903758fa9058a5182026a4f3b65443196b82c7840389ea0dbd/lbplatformutils-4.6.1-py3-none-any.whl - name: lbplatformutils - version: 4.6.1 - sha256: 92e6dd273e77873ba6cbd302c8b29fde71e5dbb7706f05856e362fb44fd9eee8 - requires_python: '>=3.7,<4.0' -- pypi: https://files.pythonhosted.org/packages/02/64/c86924898062e8217ed914a29458cfde9e4a9b80e4d4cbcca141983ba339/lbprodrun-1.12.4-py3-none-any.whl - name: lbprodrun - version: 1.12.4 - sha256: a2a408f00f31d124dd3c262db7d3aaa4cd022ec9c649b91b792c6be64b7b4c21 - requires_dist: - - click>=8.0 - - lbenv - - pydantic>=1.10 - - typer>=0.4.1 - - packaging - - pyyaml>=6.0 - - lbcondawrappers - - pytest ; extra == 'testing' - - pytest-cov ; extra == 'testing' - - zstandard ; extra == 'testing' - - mypy ; extra == 'mypy' - - types-pyyaml ; extra == 'mypy' - requires_python: '>=3.9' -- conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_101.conda - sha256: 565941ac1f8b0d2f2e8f02827cbca648f4d18cd461afc31f15604cd291b5c5f3 - md5: 12bd9a3f089ee6c9266a37dab82afabd + size: 215070 + timestamp: 1709962013437 +- conda: https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda + sha256: cafeec44494f842ffeca27e9c8b0c27ed714f93ac77ddadc6aaf726b5554ebac + md5: cffd3bdd58090148f4cfcd831f4b26ab depends: - __glibc >=2.17,<3.0.a0 - - zstd >=1.5.7,<1.6.0a0 - constrains: - - binutils_impl_linux-64 2.45.1 - license: GPL-3.0-only - purls: [] - size: 725507 - timestamp: 1770267139900 -- pypi: https://files.pythonhosted.org/packages/29/ce/ed422816fb30ffa3bc11597b30d5deca06b4a1388707a04215da73c65b53/levenshtein-0.27.3-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl - name: levenshtein - version: 0.27.3 - sha256: ce3bbbe92172a08b599d79956182c6b7ab6ec8d4adbe7237417a363b968ad87b - requires_dist: - - rapidfuzz>=3.9.0,<4.0.0 - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/76/2c/bb6ef359e007fe7b6b3195b68a94f4dd3ecd1885ee337ee8fbd4df55996f/levenshtein-0.27.3-cp314-cp314-macosx_11_0_arm64.whl - name: levenshtein - version: 0.27.3 - sha256: 8e5037c4a6f97a238e24aad6f98a1e984348b7931b1b04b6bd02bd4f8238150d - requires_dist: - - rapidfuzz>=3.9.0,<4.0.0 - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/f3/e1/2f705da403f865a5fa3449b155738dc9c53021698fd6926253a9af03180b/levenshtein-0.27.3-cp314-cp314-macosx_10_15_x86_64.whl - name: levenshtein - version: 0.27.3 - sha256: a6728bfae9a86002f0223576675fc7e2a6e7735da47185a1d13d1eaaa73dd4be - requires_dist: - - rapidfuzz>=3.9.0,<4.0.0 - requires_python: '>=3.10' -- pypi: git+https://gitlab.cern.ch/jlisalab/LHCbDIRAC.git?rev=modules-to-cwl-migration#bc5f8f1804107bc8807edcc98a97c346ef61c0e8 - name: lhcbdirac - version: 0.1.dev20470+gbc5f8f180 - requires_dist: - - dirac~=9.1 - - lbplatformutils>=4.6.1 - - lbenv>=2.3.0 - - lbprodrun - - lbcondawrappers - - requests - - pydantic>=2 - - uproot[xrootd]>=5.3 - - pyyaml - - xmltodict - - hyperscan - - levenshtein - - zstandard - - rich - - httpx - - beautifulsoup4 - - python-gitlab - - pandas - - numpy - - lhcbdiracx-client - - lhcbdiracx-core - - lhcbdiracx-cli - - signurlarity - - oracledb ; extra == 'server' - - dirac[server]~=9.1.0 ; extra == 'server' - - psutil ; extra == 'server' - - stomp-py ; extra == 'server' - - suds ; extra == 'server' - - mock ; extra == 'testing' - - pytest-mock ; extra == 'testing' - - pillow ; extra == 'testing' - - pytest ; extra == 'testing' - requires_python: '>=3.11' -- pypi: https://files.pythonhosted.org/packages/7f/37/8ea3555769b6048b5e4ec162cc90fd32e761c0e381ffb3baf888cb0d8a71/lhcbdiracx_api-0.0.8-py3-none-any.whl - name: lhcbdiracx-api - version: 0.0.8 - sha256: 13337f9b98b0907e372e014ee1012d99c7d1f1d8e3877daf96d73b165ca10aca - requires_dist: - - lhcbdiracx-core - - lhcbdiracx-client - - diracx-api==0.0.8 - - diracx-api[types]==0.0.8 ; extra == 'types' - - diracx-api[testing]==0.0.8 ; extra == 'testing' - requires_python: '>=3.11' -- pypi: https://files.pythonhosted.org/packages/68/15/bfb0c717b8f23c16907f3e73e8f56010ccd72e9900a108209665b0d9ed4b/lhcbdiracx_cli-0.0.8-py3-none-any.whl - name: lhcbdiracx-cli - version: 0.0.8 - sha256: 85e357eed0578796f78a5502c2235949dcd7fa456e7efaf1a0b2913f926f1b64 - requires_dist: - - lhcbdiracx-core - - lhcbdiracx-client - - lhcbdiracx-api - - diracx-cli==0.0.8 - - diracx-cli[types]==0.0.8 ; extra == 'types' - - diracx-cli[testing]==0.0.8 ; extra == 'testing' - requires_python: '>=3.11' -- pypi: https://files.pythonhosted.org/packages/2d/88/67602dfa2d7ab5d0518af82db34ab4d70dc2c3029b3ca788299a3be4a96d/lhcbdiracx_client-0.0.8-py3-none-any.whl - name: lhcbdiracx-client - version: 0.0.8 - sha256: 72bea573c481d011d816cbf02e39cee610b4b7aa8b57a2941659036de483907e - requires_dist: - - lhcbdiracx-core - - diracx-client==0.0.8 - - types-requests ; extra == 'types' - - diracx-api[types]==0.0.8 ; extra == 'types' - - diracx-client[testing]==0.0.8 ; extra == 'testing' - - diracx-testing==0.0.8 ; extra == 'testing' - requires_python: '>=3.11' -- pypi: https://files.pythonhosted.org/packages/34/8f/6105afdd8f4e1f3b198d09e4b2622622923d9fa9e077aed852c0bb035a3a/lhcbdiracx_core-0.0.8-py3-none-any.whl - name: lhcbdiracx-core - version: 0.0.8 - sha256: a23f9b343efddb80cb53c3e06c409c65221ff29a339d4aebe336f930d04c7942 - requires_dist: - - diracx-core==0.0.8 - - lhcbdiracx-testing ; extra == 'testing' - - diracx-testing ; extra == 'testing' - - diracx-core[types]==0.0.8 ; extra == 'testing' - - diracx-core[testing]==0.0.8 ; extra == 'types' - - types-cachetools ; extra == 'types' - - types-pyyaml ; extra == 'types' - requires_python: '>=3.11' -- conda: https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-5_h4a7cf45_openblas.conda - build_number: 5 - sha256: 18c72545080b86739352482ba14ba2c4815e19e26a7417ca21a95b76ec8da24c - md5: c160954f7418d7b6e87eaf05a8913fa9 - depends: - - libopenblas >=0.3.30,<0.3.31.0a0 - - libopenblas >=0.3.30,<1.0a0 - constrains: - - mkl <2026 - - liblapack 3.11.0 5*_openblas - - libcblas 3.11.0 5*_openblas - - blas 2.305 openblas - - liblapacke 3.11.0 5*_openblas - license: BSD-3-Clause - license_family: BSD - purls: [] - size: 18213 - timestamp: 1765818813880 -- conda: https://conda.anaconda.org/conda-forge/osx-64/libblas-3.11.0-5_he492b99_openblas.conda - build_number: 5 - sha256: 4754de83feafa6c0b41385f8dab1b13f13476232e16f524564a340871a9fc3bc - md5: 36d2e68a156692cbae776b75d6ca6eae - depends: - - libopenblas >=0.3.30,<0.3.31.0a0 - - libopenblas >=0.3.30,<1.0a0 - constrains: - - liblapack 3.11.0 5*_openblas - - blas 2.305 openblas - - libcblas 3.11.0 5*_openblas - - mkl <2026 - - liblapacke 3.11.0 5*_openblas - license: BSD-3-Clause - license_family: BSD - purls: [] - size: 18476 - timestamp: 1765819054657 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libblas-3.11.0-5_h51639a9_openblas.conda - build_number: 5 - sha256: 620a6278f194dcabc7962277da6835b1e968e46ad0c8e757736255f5ddbfca8d - md5: bcc025e2bbaf8a92982d20863fe1fb69 - depends: - - libopenblas >=0.3.30,<0.3.31.0a0 - - libopenblas >=0.3.30,<1.0a0 + - libgcc >=14 + - libzlib >=1.3.1,<2.0a0 constrains: - - libcblas 3.11.0 5*_openblas - - liblapack 3.11.0 5*_openblas - - liblapacke 3.11.0 5*_openblas - - blas 2.305 openblas - - mkl <2026 - license: BSD-3-Clause + - xorg-libx11 >=1.8.12,<2.0a0 + license: TCL license_family: BSD purls: [] - size: 18546 - timestamp: 1765819094137 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libboost-1.88.0-hd24cca6_7.conda - sha256: dd489228e1916c7720c925248d0ba12803d1dc8b9898be0c51f4ab37bab6ffa5 - md5: d70e4dc6a847d437387d45462fe60cf9 + size: 3301196 + timestamp: 1769460227866 +- conda: https://conda.anaconda.org/conda-forge/linux-64/ukkonen-1.1.0-py314h9891dd4_0.conda + sha256: c84034056dc938c853e4f61e72e5bd37e2ec91927a661fb9762f678cbea52d43 + md5: 5d3c008e54c7f49592fca9c32896a76f depends: - __glibc >=2.17,<3.0.a0 - - bzip2 >=1.0.8,<2.0a0 - - icu >=78.1,<79.0a0 + - cffi - libgcc >=14 - - liblzma >=5.8.1,<6.0a0 - libstdcxx >=14 - - libzlib >=1.3.1,<2.0a0 - - zstd >=1.5.7,<1.6.0a0 - constrains: - - boost-cpp <0.0a0 - license: BSL-1.0 - purls: [] - size: 3072984 - timestamp: 1766347479317 -- conda: https://conda.anaconda.org/conda-forge/osx-64/libboost-1.88.0-h5950822_7.conda - sha256: 4cf91837a0af26996a43538213abe14adf54e07ac9fc8cb3880185f6e086c5df - md5: de6f7fa28d94fa380024444324b15d5f - depends: - - __osx >=10.13 - - bzip2 >=1.0.8,<2.0a0 - - icu >=78.1,<79.0a0 - - libcxx >=19 - - liblzma >=5.8.1,<6.0a0 - - libzlib >=1.3.1,<2.0a0 - - zstd >=1.5.7,<1.6.0a0 - constrains: - - boost-cpp <0.0a0 - license: BSL-1.0 - purls: [] - size: 2091448 - timestamp: 1766348915727 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libboost-1.88.0-h0419b56_7.conda - sha256: d3872915a43512b0404e131d965e6e8c1e2546b13ccfd2463ef72fbfe1456afc - md5: 34e8ce0732bb254bd17f0b9ecea788c2 + - python >=3.14,<3.15.0a0 + - python_abi 3.14.* *_cp314 + license: MIT + license_family: MIT + purls: + - pkg:pypi/ukkonen?source=hash-mapping + size: 15004 + timestamp: 1769438727085 +- conda: https://conda.anaconda.org/conda-forge/linux-64/voms-2.1.0rc3-h25bd2b9_0.conda + sha256: e468adc4ee9de5abbf421d8b4e9463e258840e6e59ded58afe016f28d5aa931c + md5: 5e6a396c2fb7f88c0a87d6fa360e40c7 depends: - - __osx >=11.0 - - bzip2 >=1.0.8,<2.0a0 - - icu >=78.1,<79.0a0 - - libcxx >=19 - - liblzma >=5.8.1,<6.0a0 - - libzlib >=1.3.1,<2.0a0 - - zstd >=1.5.7,<1.6.0a0 + - expat >=2.5.0,<3.0a0 + - gsoap >=2.8.123,<2.8.124.0a0 + - libgcc-ng >=12 + - libstdcxx-ng >=12 + - libzlib >=1.2.13,<2.0.0a0 + - openssl >=3.0.8,<4.0a0 constrains: - - boost-cpp <0.0a0 - license: BSL-1.0 + - voms-clients ==9999999 + license: Apache-2.0 + license_family: Apache purls: [] - size: 1992135 - timestamp: 1766348005115 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libboost-python-1.88.0-py314h3a4f467_7.conda - sha256: a701f2a6afa984b52cfffe51abb5aaf8e6e534082f71e36078f0f4cf54d2e7fe - md5: ed299171ab3525d8f4ed400083105743 + size: 461879 + timestamp: 1676298873445 +- conda: https://conda.anaconda.org/conda-forge/linux-64/xrootd-5.9.1-py314h75aeccf_0.conda + sha256: 2351cace7322d68dd834c276f4cb19bc35a68d90642dd7083b4924bb26a66228 + md5: d9b7e0eeecec187f4344983ba341c2d7 depends: + - openssl + - python + - readline + - libxml2-devel + - krb5 + - zlib + - ncurses - __glibc >=2.17,<3.0.a0 - - libboost 1.88.0 hd24cca6_7 - - libgcc >=14 - libstdcxx >=14 - - numpy >=1.23,<3 - - python >=3.14,<3.15.0a0 + - libgcc >=14 + - libcurl >=8.18.0,<9.0a0 + - scitokens-cpp >=1.2.0,<2.0a0 + - libxcrypt >=4.4.36 + - libuuid >=2.41.3,<3.0a0 + - ncurses >=6.5,<7.0a0 + - openssl >=3.5.4,<4.0a0 - python_abi 3.14.* *_cp314 - constrains: - - py-boost <0.0a0 - - boost <0.0a0 - license: BSL-1.0 - purls: [] - size: 132709 - timestamp: 1766347940966 -- conda: https://conda.anaconda.org/conda-forge/osx-64/libboost-python-1.88.0-py314hee2ba4e_7.conda - sha256: ee37fd8e0293a50de5b2121aa7ca84fa199a4489bde2061df676c5cb4870da5c - md5: e387fe913fb05251520fa4d35e3a6f25 + - readline >=8.3,<9.0a0 + - libzlib >=1.3.1,<2.0a0 + - libxml2 + - libxml2-16 >=2.14.6 + - krb5 >=1.21.3,<1.22.0a0 + license: LGPL-3.0-or-later + license_family: LGPL + purls: + - pkg:pypi/xrootd?source=hash-mapping + size: 4201796 + timestamp: 1769447927303 +- conda: https://conda.anaconda.org/conda-forge/linux-64/yaml-0.2.5-h280c20c_3.conda + sha256: 6d9ea2f731e284e9316d95fa61869fe7bbba33df7929f82693c121022810f4ad + md5: a77f85f77be52ff59391544bfe73390a depends: - - __osx >=10.13 - - libboost 1.88.0 h5950822_7 - - libcxx >=19 - - numpy >=1.23,<3 - - python >=3.14,<3.15.0a0 - - python_abi 3.14.* *_cp314 - constrains: - - boost <0.0a0 - - py-boost <0.0a0 - license: BSL-1.0 + - libgcc >=14 + - __glibc >=2.17,<3.0.a0 + license: MIT + license_family: MIT purls: [] - size: 108601 - timestamp: 1766349368723 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libboost-python-1.88.0-py314hce24fef_7.conda - sha256: 3f6be1bbb56c17e4b362b8b7b80568733e76108f289cb11ca4f14289ed173366 - md5: 545c065df173b77ab97eb6ad190b985e + size: 85189 + timestamp: 1753484064210 +- conda: https://conda.anaconda.org/conda-forge/linux-64/zlib-1.3.1-hb9d3cd8_2.conda + sha256: 5d7c0e5f0005f74112a34a7425179f4eb6e73c92f5d109e6af4ddeca407c92ab + md5: c9f075ab2f33b3bbee9e62d4ad0a6cd8 depends: - - __osx >=11.0 - - libboost 1.88.0 h0419b56_7 - - libcxx >=19 - - numpy >=1.23,<3 - - python >=3.14,<3.15.0a0 - - python >=3.14,<3.15.0a0 *_cp314 - - python_abi 3.14.* *_cp314 - constrains: - - py-boost <0.0a0 - - boost <0.0a0 - license: BSL-1.0 + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + - libzlib 1.3.1 hb9d3cd8_2 + license: Zlib + license_family: Other purls: [] - size: 107891 - timestamp: 1766348725978 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-5_h0358290_openblas.conda - build_number: 5 - sha256: 0cbdcc67901e02dc17f1d19e1f9170610bd828100dc207de4d5b6b8ad1ae7ad8 - md5: 6636a2b6f1a87572df2970d3ebc87cc0 + size: 92286 + timestamp: 1727963153079 +- conda: https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda + sha256: 68f0206ca6e98fea941e5717cec780ed2873ffabc0e1ed34428c061e2c6268c7 + md5: 4a13eeac0b5c8e5b8ab496e6c4ddd829 depends: - - libblas 3.11.0 5_h4a7cf45_openblas - constrains: - - liblapacke 3.11.0 5*_openblas - - blas 2.305 openblas - - liblapack 3.11.0 5*_openblas + - __glibc >=2.17,<3.0.a0 + - libzlib >=1.3.1,<2.0a0 license: BSD-3-Clause license_family: BSD purls: [] - size: 18194 - timestamp: 1765818837135 -- conda: https://conda.anaconda.org/conda-forge/osx-64/libcblas-3.11.0-5_h9b27e0a_openblas.conda - build_number: 5 - sha256: 8077c29ea720bd152be6e6859a3765228cde51301fe62a3b3f505b377c2cb48c - md5: b31d771cbccff686e01a687708a7ca41 + size: 601375 + timestamp: 1764777111296 +- conda: https://conda.anaconda.org/conda-forge/noarch/attrs-25.4.0-pyhcf101f3_1.conda + sha256: c13d5e42d187b1d0255f591b7ce91201d4ed8a5370f0d986707a802c20c9d32f + md5: 537296d57ea995666c68c821b00e360b depends: - - libblas 3.11.0 5_he492b99_openblas - constrains: - - liblapack 3.11.0 5*_openblas - - blas 2.305 openblas - - liblapacke 3.11.0 5*_openblas - license: BSD-3-Clause - license_family: BSD - purls: [] - size: 18484 - timestamp: 1765819073006 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcblas-3.11.0-5_hb0561ab_openblas.conda - build_number: 5 - sha256: 38809c361bbd165ecf83f7f05fae9b791e1baa11e4447367f38ae1327f402fc0 - md5: efd8bd15ca56e9d01748a3beab8404eb + - python >=3.10 + - python + license: MIT + license_family: MIT + purls: + - pkg:pypi/attrs?source=compressed-mapping + size: 64759 + timestamp: 1764875182184 +- conda: https://conda.anaconda.org/conda-forge/noarch/backports.asyncio.runner-1.2.0-pyh5ded981_2.conda + sha256: 2ade43752e8494f110a2cfb9e4d5b1ea29e3dcb037fba63395442d00371e8bf9 + md5: 0fd7e45c862b3305226a992f9f7b204a depends: - - libblas 3.11.0 5_h51639a9_openblas + - python >=3.11 + - python constrains: - - liblapacke 3.11.0 5*_openblas - - liblapack 3.11.0 5*_openblas - - blas 2.305 openblas - license: BSD-3-Clause - license_family: BSD + - python >=3.11 + license: PSF-2.0 + license_family: PSF purls: [] - size: 18548 - timestamp: 1765819108956 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libcurl-8.18.0-h4e3cde8_0.conda - sha256: 5454709d9fb6e9c3dd6423bc284fa7835a7823bfa8323f6e8786cdd555101fab - md5: 0a5563efed19ca4461cf927419b6eb73 + size: 10186 + timestamp: 1753456386827 +- conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.1.4-hbd8a1cb_0.conda + sha256: b5974ec9b50e3c514a382335efa81ed02b05906849827a34061c496f4defa0b2 + md5: bddacf101bb4dd0e51811cb69c7790e2 depends: - - __glibc >=2.17,<3.0.a0 - - krb5 >=1.21.3,<1.22.0a0 - - libgcc >=14 - - libnghttp2 >=1.67.0,<2.0a0 - - libssh2 >=1.11.1,<2.0a0 - - libzlib >=1.3.1,<2.0a0 - - openssl >=3.5.4,<4.0a0 - - zstd >=1.5.7,<1.6.0a0 - license: curl - license_family: MIT + - __unix + license: ISC purls: [] - size: 462942 - timestamp: 1767821743793 -- conda: https://conda.anaconda.org/conda-forge/osx-64/libcurl-8.18.0-h9348e2b_0.conda - sha256: 1a0af3b7929af3c5893ebf50161978f54ae0256abb9532d4efba2735a0688325 - md5: de1910529f64ba4a9ac9005e0be78601 + size: 146519 + timestamp: 1767500828366 +- conda: https://conda.anaconda.org/conda-forge/noarch/cfgv-3.5.0-pyhd8ed1ab_0.conda + sha256: aa589352e61bb221351a79e5946d56916e3c595783994884accdb3b97fe9d449 + md5: 381bd45fb7aa032691f3063aff47e3a1 depends: - - __osx >=10.13 - - krb5 >=1.21.3,<1.22.0a0 - - libnghttp2 >=1.67.0,<2.0a0 - - libssh2 >=1.11.1,<2.0a0 - - libzlib >=1.3.1,<2.0a0 - - openssl >=3.5.4,<4.0a0 - - zstd >=1.5.7,<1.6.0a0 - license: curl + - python >=3.10 + license: MIT license_family: MIT - purls: [] - size: 419089 - timestamp: 1767822218800 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcurl-8.18.0-he38603e_0.conda - sha256: 11c78b3e89bc332933386f0a11ac60d9200afb7a811b9e3bec98aef8d4a6389b - md5: 36190179a799f3aee3c2d20a8a2b970d + purls: + - pkg:pypi/cfgv?source=hash-mapping + size: 13589 + timestamp: 1763607964133 +- conda: https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda + sha256: ab29d57dc70786c1269633ba3dff20288b81664d3ff8d21af995742e2bb03287 + md5: 962b9857ee8e7018c22f2776ffa0b2d7 depends: - - __osx >=11.0 - - krb5 >=1.21.3,<1.22.0a0 - - libnghttp2 >=1.67.0,<2.0a0 - - libssh2 >=1.11.1,<2.0a0 - - libzlib >=1.3.1,<2.0a0 - - openssl >=3.5.4,<4.0a0 - - zstd >=1.5.7,<1.6.0a0 - license: curl - license_family: MIT - purls: [] - size: 402681 - timestamp: 1767822693908 -- conda: https://conda.anaconda.org/conda-forge/osx-64/libcxx-21.1.8-h4fb565c_2.conda - sha256: 2619d471c50c466320e2aea906a4363e34efe181e61346e4453bc68264c5185f - md5: 1ac756454e65fb3fd7bc7de599526e43 - depends: - - __osx >=10.13 - license: Apache-2.0 WITH LLVM-exception - license_family: Apache - purls: [] - size: 571912 - timestamp: 1770237202404 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcxx-21.1.8-h55c6f16_2.conda - sha256: 5fbeb2fc2673f0455af6079abf93faaf27f11a92574ad51565fa1ecac9a4e2aa - md5: 4cb5878bdb9ebfa65b7cdff5445087c5 - depends: - - __osx >=11.0 - license: Apache-2.0 WITH LLVM-exception - license_family: Apache - purls: [] - size: 570068 - timestamp: 1770238262922 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949ede_0.conda - sha256: d789471216e7aba3c184cd054ed61ce3f6dac6f87a50ec69291b9297f8c18724 - md5: c277e0a4d549b03ac1e9d6cbbe3d017b - depends: - - ncurses - - __glibc >=2.17,<3.0.a0 - - libgcc >=13 - - ncurses >=6.5,<7.0a0 - license: BSD-2-Clause - license_family: BSD - purls: [] - size: 134676 - timestamp: 1738479519902 -- conda: https://conda.anaconda.org/conda-forge/osx-64/libedit-3.1.20250104-pl5321ha958ccf_0.conda - sha256: 6cc49785940a99e6a6b8c6edbb15f44c2dd6c789d9c283e5ee7bdfedd50b4cd6 - md5: 1f4ed31220402fcddc083b4bff406868 - depends: - - ncurses - - __osx >=10.13 - - ncurses >=6.5,<7.0a0 - license: BSD-2-Clause + - python >=3.9 + license: BSD-3-Clause license_family: BSD - purls: [] - size: 115563 - timestamp: 1738479554273 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libedit-3.1.20250104-pl5321hafb1f1b_0.conda - sha256: 66aa216a403de0bb0c1340a88d1a06adaff66bae2cfd196731aa24db9859d631 - md5: 44083d2d2c2025afca315c7a172eab2b + purls: + - pkg:pypi/colorama?source=hash-mapping + size: 27011 + timestamp: 1733218222191 +- conda: https://conda.anaconda.org/conda-forge/noarch/distlib-0.4.0-pyhd8ed1ab_0.conda + sha256: 6d977f0b2fc24fee21a9554389ab83070db341af6d6f09285360b2e09ef8b26e + md5: 003b8ba0a94e2f1e117d0bd46aebc901 depends: - - ncurses - - __osx >=11.0 - - ncurses >=6.5,<7.0a0 - license: BSD-2-Clause - license_family: BSD - purls: [] - size: 107691 - timestamp: 1738479560845 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libev-4.33-hd590300_2.conda - sha256: 1cd6048169fa0395af74ed5d8f1716e22c19a81a8a36f934c110ca3ad4dd27b4 - md5: 172bf1cd1ff8629f2b1179945ed45055 + - python >=3.9 + license: Apache-2.0 + license_family: APACHE + purls: + - pkg:pypi/distlib?source=hash-mapping + size: 275642 + timestamp: 1752823081585 +- conda: https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda + sha256: ee6cf346d017d954255bbcbdb424cddea4d14e4ed7e9813e429db1d795d01144 + md5: 8e662bd460bda79b1ea39194e3c4c9ab depends: - - libgcc-ng >=12 - license: BSD-2-Clause - license_family: BSD - purls: [] - size: 112766 - timestamp: 1702146165126 -- conda: https://conda.anaconda.org/conda-forge/osx-64/libev-4.33-h10d778d_2.conda - sha256: 0d238488564a7992942aa165ff994eca540f687753b4f0998b29b4e4d030ff43 - md5: 899db79329439820b7e8f8de41bca902 - license: BSD-2-Clause - license_family: BSD - purls: [] - size: 106663 - timestamp: 1702146352558 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libev-4.33-h93a5062_2.conda - sha256: 95cecb3902fbe0399c3a7e67a5bed1db813e5ab0e22f4023a5e0f722f2cc214f - md5: 36d33e440c31857372a72137f78bacf5 - license: BSD-2-Clause - license_family: BSD - purls: [] - size: 107458 - timestamp: 1702146414478 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.3-hecca717_0.conda - sha256: 1e1b08f6211629cbc2efe7a5bca5953f8f6b3cae0eeb04ca4dacee1bd4e2db2f - md5: 8b09ae86839581147ef2e5c5e229d164 + - python >=3.10 + - typing_extensions >=4.6.0 + license: MIT and PSF-2.0 + purls: + - pkg:pypi/exceptiongroup?source=hash-mapping + size: 21333 + timestamp: 1763918099466 +- conda: https://conda.anaconda.org/conda-forge/noarch/filelock-3.20.3-pyhd8ed1ab_0.conda + sha256: 8b90dc21f00167a7e58abb5141a140bdb31a7c5734fe1361b5f98f4a4183fd32 + md5: 2cfaaccf085c133a477f0a7a8657afe9 depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=14 - constrains: - - expat 2.7.3.* - license: MIT - license_family: MIT - purls: [] - size: 76643 - timestamp: 1763549731408 -- conda: https://conda.anaconda.org/conda-forge/osx-64/libexpat-2.7.3-heffb93a_0.conda - sha256: d11b3a6ce5b2e832f430fd112084533a01220597221bee16d6c7dc3947dffba6 - md5: 222e0732a1d0780a622926265bee14ef + - python >=3.10 + license: Unlicense + purls: + - pkg:pypi/filelock?source=hash-mapping + size: 18661 + timestamp: 1768022315929 +- conda: https://conda.anaconda.org/conda-forge/noarch/identify-2.6.16-pyhd8ed1ab_0.conda + sha256: 6a88cdde151469131df1948839ac2315ada99cf8d38aaacc9a7a5984e9cd8c19 + md5: 8bc5851c415865334882157127e75799 depends: - - __osx >=10.13 - constrains: - - expat 2.7.3.* + - python >=3.10 + - ukkonen license: MIT license_family: MIT - purls: [] - size: 74058 - timestamp: 1763549886493 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libexpat-2.7.3-haf25636_0.conda - sha256: fce22610ecc95e6d149e42a42fbc3cc9d9179bd4eb6232639a60f06e080eec98 - md5: b79875dbb5b1db9a4a22a4520f918e1a + purls: + - pkg:pypi/identify?source=compressed-mapping + size: 79302 + timestamp: 1768295306539 +- conda: https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda + sha256: e1a9e3b1c8fe62dc3932a616c284b5d8cbe3124bbfbedcf4ce5c828cb166ee19 + md5: 9614359868482abba1bd15ce465e3c42 depends: - - __osx >=11.0 - constrains: - - expat 2.7.3.* + - python >=3.10 license: MIT license_family: MIT - purls: [] - size: 67800 - timestamp: 1763549994166 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda - sha256: 31f19b6a88ce40ebc0d5a992c131f57d919f73c0b92cd1617a5bec83f6e961e6 - md5: a360c33a5abe61c07959e449fa1453eb + purls: + - pkg:pypi/iniconfig?source=compressed-mapping + size: 13387 + timestamp: 1760831448842 +- conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-4.26.0-pyhcf101f3_0.conda + sha256: db973a37d75db8e19b5f44bbbdaead0c68dde745407f281e2a7fe4db74ec51d7 + md5: ada41c863af263cc4c5fcbaff7c3e4dc depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=14 + - attrs >=22.2.0 + - jsonschema-specifications >=2023.3.6 + - python >=3.10 + - referencing >=0.28.4 + - rpds-py >=0.25.0 + - python license: MIT license_family: MIT - purls: [] - size: 58592 - timestamp: 1769456073053 -- conda: https://conda.anaconda.org/conda-forge/osx-64/libffi-3.5.2-hd1f9c09_0.conda - sha256: 951958d1792238006fdc6fce7f71f1b559534743b26cc1333497d46e5903a2d6 - md5: 66a0dc7464927d0853b590b6f53ba3ea + purls: + - pkg:pypi/jsonschema?source=compressed-mapping + size: 82356 + timestamp: 1767839954256 +- conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-specifications-2025.9.1-pyhcf101f3_0.conda + sha256: 0a4f3b132f0faca10c89fdf3b60e15abb62ded6fa80aebfc007d05965192aa04 + md5: 439cd0f567d697b20a8f45cb70a1005a depends: - - __osx >=10.13 + - python >=3.10 + - referencing >=0.31.0 + - python license: MIT license_family: MIT - purls: [] - size: 53583 - timestamp: 1769456300951 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libffi-3.5.2-hcf2aa1b_0.conda - sha256: 6686a26466a527585e6a75cc2a242bf4a3d97d6d6c86424a441677917f28bec7 - md5: 43c04d9cb46ef176bb2a4c77e324d599 + purls: + - pkg:pypi/jsonschema-specifications?source=hash-mapping + size: 19236 + timestamp: 1757335715225 +- conda: https://conda.anaconda.org/conda-forge/noarch/mypy_extensions-1.1.0-pyha770c72_0.conda + sha256: 6ed158e4e5dd8f6a10ad9e525631e35cee8557718f83de7a4e3966b1f772c4b1 + md5: e9c622e0d00fa24a6292279af3ab6d06 depends: - - __osx >=11.0 + - python >=3.9 license: MIT license_family: MIT - purls: [] - size: 40979 - timestamp: 1769456747661 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_17.conda - sha256: 43860222cf3abf04ded0cf24541a105aa388e0e1d4d6ca46258e186d4e87ae3e - md5: 3c281169ea25b987311400d7a7e28445 + purls: + - pkg:pypi/mypy-extensions?source=hash-mapping + size: 11766 + timestamp: 1745776666688 +- conda: https://conda.anaconda.org/conda-forge/noarch/nodeenv-1.10.0-pyhd8ed1ab_0.conda + sha256: 4fa40e3e13fc6ea0a93f67dfc76c96190afd7ea4ffc1bac2612d954b42cdc3ee + md5: eb52d14a901e23c39e9e7b4a1a5c015f depends: - - __glibc >=2.17,<3.0.a0 - - _openmp_mutex >=4.5 - constrains: - - libgcc-ng ==15.2.0=*_17 - - libgomp 15.2.0 he0feb66_17 - license: GPL-3.0-only WITH GCC-exception-3.1 - purls: [] - size: 1040478 - timestamp: 1770252533873 -- conda: https://conda.anaconda.org/conda-forge/osx-64/libgcc-15.2.0-h08519bb_17.conda - sha256: c987bcc8fc9c9a689672a0c72942536c1b2ba83bd679971cc927d9f66668855b - md5: 500bac4a846e5001cbf05572df6c3654 + - python >=3.10 + - setuptools + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/nodeenv?source=hash-mapping + size: 40866 + timestamp: 1766261270149 +- conda: https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda + sha256: c1fc0f953048f743385d31c468b4a678b3ad20caffdeaa94bed85ba63049fd58 + md5: b76541e68fea4d511b1ac46a28dcd2c6 depends: - - _openmp_mutex - constrains: - - libgomp 15.2.0 17 - - libgcc-ng ==15.2.0=*_17 - license: GPL-3.0-only WITH GCC-exception-3.1 - purls: [] - size: 423903 - timestamp: 1770252717776 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libgcc-15.2.0-hcbb3090_17.conda - sha256: 07ba27f2ef1ce444ce5c99d0f9590772fc5b58ba73c993477bfad74b17dfaa79 - md5: 65c07cee234440ae4d5d340fc4b2e69a - depends: - - _openmp_mutex - constrains: - - libgomp 15.2.0 17 - - libgcc-ng ==15.2.0=*_17 - license: GPL-3.0-only WITH GCC-exception-3.1 - purls: [] - size: 402928 - timestamp: 1770254186829 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_17.conda - sha256: bdfe50501e4a2d904a5eae65a7ae26e2b7a29b473ab084ad55d96080b966502e - md5: 1478bfa85224a65ab096d69ffd2af1e5 + - python >=3.8 + - python + license: Apache-2.0 + license_family: APACHE + purls: + - pkg:pypi/packaging?source=compressed-mapping + size: 72010 + timestamp: 1769093650580 +- conda: https://conda.anaconda.org/conda-forge/noarch/pathspec-1.0.4-pyhd8ed1ab_0.conda + sha256: 29ea20d0faf20374fcd61c25f6d32fb8e9a2c786a7f1473a0c3ead359470fbe1 + md5: 2908273ac396d2cd210a8127f5f1c0d6 depends: - - libgcc 15.2.0 he0feb66_17 - license: GPL-3.0-only WITH GCC-exception-3.1 - purls: [] - size: 27541 - timestamp: 1770252546553 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_17.conda - sha256: 1604c083dd65bc91e68b6cfe32c8610395088cb96af1acaf71f0dcaf83ac58f7 - md5: a6c682ac611cb1fa4d73478f9e6efb06 + - python >=3.10 + license: MPL-2.0 + license_family: MOZILLA + purls: + - pkg:pypi/pathspec?source=compressed-mapping + size: 53739 + timestamp: 1769677743677 +- conda: https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.5.1-pyhcf101f3_0.conda + sha256: 04c64fb78c520e5c396b6e07bc9082735a5cc28175dbe23138201d0a9441800b + md5: 1bd2e65c8c7ef24f4639ae6e850dacc2 depends: - - libgfortran5 15.2.0 h68bc16d_17 - constrains: - - libgfortran-ng ==15.2.0=*_17 - license: GPL-3.0-only WITH GCC-exception-3.1 - purls: [] - size: 27515 - timestamp: 1770252591906 -- conda: https://conda.anaconda.org/conda-forge/osx-64/libgfortran-15.2.0-h7e5c614_17.conda - sha256: c2b319a051e10501b76115a427ab76aa7c0a23b157b50726bcb572373ffb94c0 - md5: 218faf079bac8521ccf3f8542feeb51d + - python >=3.10 + - python + license: MIT + license_family: MIT + purls: + - pkg:pypi/platformdirs?source=hash-mapping + size: 23922 + timestamp: 1764950726246 +- conda: https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda + sha256: e14aafa63efa0528ca99ba568eaf506eb55a0371d12e6250aaaa61718d2eb62e + md5: d7585b6550ad04c8c5e21097ada2888e depends: - - libgfortran5 15.2.0 hd16e46c_17 - constrains: - - libgfortran-ng ==15.2.0=*_17 - license: GPL-3.0-only WITH GCC-exception-3.1 - purls: [] - size: 139677 - timestamp: 1770252942112 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libgfortran-15.2.0-h07b0088_17.conda - sha256: 7b96f428cb932df8d7c1aa4e433ed29b779dd9571934afdf4f9093a85155a142 - md5: 45ba22eb5381fb602a45233d89ba27ae + - python >=3.9 + - python + license: MIT + license_family: MIT + purls: + - pkg:pypi/pluggy?source=compressed-mapping + size: 25877 + timestamp: 1764896838868 +- conda: https://conda.anaconda.org/conda-forge/noarch/pre-commit-4.5.1-pyha770c72_0.conda + sha256: 5b81b7516d4baf43d0c185896b245fa7384b25dc5615e7baa504b7fa4e07b706 + md5: 7f3ac694319c7eaf81a0325d6405e974 depends: - - libgfortran5 15.2.0 hdae7583_17 - constrains: - - libgfortran-ng ==15.2.0=*_17 - license: GPL-3.0-only WITH GCC-exception-3.1 - purls: [] - size: 139757 - timestamp: 1770254394473 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_17.conda - sha256: b1c77b85da9a3e204de986f59e262268805c6a35dffdf3953f1b98407db2aef3 - md5: 202fdf8cad9eea704c2b0d823d1732bf + - cfgv >=2.0.0 + - identify >=1.0.0 + - nodeenv >=0.11.1 + - python >=3.10 + - pyyaml >=5.1 + - virtualenv >=20.10.0 + license: MIT + license_family: MIT + purls: + - pkg:pypi/pre-commit?source=hash-mapping + size: 200827 + timestamp: 1765937577534 +- conda: https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda + sha256: 79db7928d13fab2d892592223d7570f5061c192f27b9febd1a418427b719acc6 + md5: 12c566707c80111f9799308d9e265aef depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=15.2.0 - constrains: - - libgfortran 15.2.0 - license: GPL-3.0-only WITH GCC-exception-3.1 - purls: [] - size: 2480824 - timestamp: 1770252563579 -- conda: https://conda.anaconda.org/conda-forge/osx-64/libgfortran5-15.2.0-hd16e46c_17.conda - sha256: 464b13f5383bb0e38fecbf6bf5b2feadc12f5f57d7d0fd2d49ac051b10e453d3 - md5: bb0c5b043c41c27f4f73a103c6ad0c7f + - python >=3.9 + - python + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/pycparser?source=hash-mapping + size: 110100 + timestamp: 1733195786147 +- conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda + sha256: 5577623b9f6685ece2697c6eb7511b4c9ac5fb607c9babc2646c811b428fd46a + md5: 6b6ece66ebcae2d5f326c77ef2c5a066 depends: - - libgcc >=15.2.0 - constrains: - - libgfortran 15.2.0 - license: GPL-3.0-only WITH GCC-exception-3.1 - purls: [] - size: 1063057 - timestamp: 1770252727755 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libgfortran5-15.2.0-hdae7583_17.conda - sha256: 9c41ff08f61c953cee13fc3df3c6245741e5a71e453b2c094a6d55b0eeda3669 - md5: c6329d871fb3207e9657c384128f5488 + - python >=3.9 + license: BSD-2-Clause + license_family: BSD + purls: + - pkg:pypi/pygments?source=hash-mapping + size: 889287 + timestamp: 1750615908735 +- conda: https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda + sha256: 9e749fb465a8bedf0184d8b8996992a38de351f7c64e967031944978de03a520 + md5: 2b694bad8a50dc2f712f5368de866480 depends: - - libgcc >=15.2.0 + - pygments >=2.7.2 + - python >=3.10 + - iniconfig >=1.0.1 + - packaging >=22 + - pluggy >=1.5,<2 + - tomli >=1 + - colorama >=0.4 + - exceptiongroup >=1 + - python constrains: - - libgfortran 15.2.0 - license: GPL-3.0-only WITH GCC-exception-3.1 - purls: [] - size: 599374 - timestamp: 1770254196706 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libglib-2.86.3-h6548e54_0.conda - sha256: 82d6c2ee9f548c84220fb30fb1b231c64a53561d6e485447394f0a0eeeffe0e6 - md5: 034bea55a4feef51c98e8449938e9cee + - pytest-faulthandler >=2 + license: MIT + license_family: MIT + purls: + - pkg:pypi/pytest?source=hash-mapping + size: 299581 + timestamp: 1765062031645 +- conda: https://conda.anaconda.org/conda-forge/noarch/pytest-asyncio-1.3.0-pyhcf101f3_0.conda + sha256: e782cf0555e4d54102423ad3421c8122f97a7a7c2d55c677a91e32d7c3e2b059 + md5: 80eccce75e6728e9e728370984bdc6fd depends: - - __glibc >=2.17,<3.0.a0 - - libffi >=3.5.2,<3.6.0a0 - - libgcc >=14 - - libiconv >=1.18,<2.0a0 - - libzlib >=1.3.1,<2.0a0 - - pcre2 >=10.47,<10.48.0a0 - constrains: - - glib 2.86.3 *_0 - license: LGPL-2.1-or-later - purls: [] - size: 3946542 - timestamp: 1765221858705 -- conda: https://conda.anaconda.org/conda-forge/osx-64/libglib-2.86.3-hf241ffe_0.conda - sha256: d205ecdd0873dd92f7b55ac9b266b2eb09236ff5f3b26751579e435bbaed499c - md5: 584ce14b08050d3f1a25ab429b9360bc + - pytest >=8.2,<10 + - python >=3.10 + - typing_extensions >=4.12 + - backports.asyncio.runner >=1.1,<2 + - python + license: Apache-2.0 + license_family: APACHE + purls: + - pkg:pypi/pytest-asyncio?source=hash-mapping + size: 39223 + timestamp: 1762797319837 +- conda: https://conda.anaconda.org/conda-forge/noarch/pytest-mock-3.15.1-pyhd8ed1ab_0.conda + sha256: 2936717381a2740c7bef3d96827c042a3bba3ba1496c59892989296591e3dabb + md5: 0511afbe860b1a653125d77c719ece53 depends: - - __osx >=10.13 - - libffi >=3.5.2,<3.6.0a0 - - libiconv >=1.18,<2.0a0 - - libintl >=0.25.1,<1.0a0 - - libzlib >=1.3.1,<2.0a0 - - pcre2 >=10.47,<10.48.0a0 + - pytest >=6.2.5 + - python >=3.10 + license: MIT + license_family: MIT + purls: + - pkg:pypi/pytest-mock?source=hash-mapping + size: 22968 + timestamp: 1758101248317 +- conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314.conda + build_number: 8 + sha256: ad6d2e9ac39751cc0529dd1566a26751a0bf2542adb0c232533d32e176e21db5 + md5: 0539938c55b6b1a59b560e843ad864a4 constrains: - - glib 2.86.3 *_0 - license: LGPL-2.1-or-later + - python 3.14.* *_cp314 + license: BSD-3-Clause + license_family: BSD purls: [] - size: 3708599 - timestamp: 1765222438844 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libglib-2.86.3-hfe11c1f_0.conda - sha256: 801c1835aa35a4f6e45e2192ad668bd7238d95c90ef8f02c52ce859c20117285 - md5: 057c7247514048ebdaf89373b263ebee + size: 6989 + timestamp: 1752805904792 +- conda: https://conda.anaconda.org/conda-forge/noarch/referencing-0.37.0-pyhcf101f3_0.conda + sha256: 0577eedfb347ff94d0f2fa6c052c502989b028216996b45c7f21236f25864414 + md5: 870293df500ca7e18bedefa5838a22ab depends: - - __osx >=11.0 - - libffi >=3.5.2,<3.6.0a0 - - libiconv >=1.18,<2.0a0 - - libintl >=0.25.1,<1.0a0 - - libzlib >=1.3.1,<2.0a0 - - pcre2 >=10.47,<10.48.0a0 - constrains: - - glib 2.86.3 *_0 - license: LGPL-2.1-or-later + - attrs >=22.2.0 + - python >=3.10 + - rpds-py >=0.7.0 + - typing_extensions >=4.4.0 + - python + license: MIT + license_family: MIT + purls: + - pkg:pypi/referencing?source=hash-mapping + size: 51788 + timestamp: 1760379115194 +- conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-80.10.2-pyh332efcf_0.conda + sha256: f5fcb7854d2b7639a5b1aca41dd0f2d5a69a60bbc313e7f192e2dc385ca52f86 + md5: 7b446fcbb6779ee479debb4fd7453e6c + depends: + - python >=3.10 + license: MIT + license_family: MIT + purls: + - pkg:pypi/setuptools?source=compressed-mapping + size: 678888 + timestamp: 1769601206751 +- conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.0-pyhcf101f3_0.conda + sha256: 62940c563de45790ba0f076b9f2085a842a65662268b02dd136a8e9b1eaf47a8 + md5: 72e780e9aa2d0a3295f59b1874e3768b + depends: + - python >=3.10 + - python + license: MIT + license_family: MIT + purls: + - pkg:pypi/tomli?source=compressed-mapping + size: 21453 + timestamp: 1768146676791 +- conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda + sha256: 032271135bca55aeb156cee361c81350c6f3fb203f57d024d7e5a1fc9ef18731 + md5: 0caa1af407ecff61170c9437a808404d + depends: + - python >=3.10 + - python + license: PSF-2.0 + license_family: PSF + purls: + - pkg:pypi/typing-extensions?source=hash-mapping + size: 51692 + timestamp: 1756220668932 +- conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda + sha256: 1d30098909076af33a35017eed6f2953af1c769e273a0626a04722ac4acaba3c + md5: ad659d0a2b3e47e38d829aa8cad2d610 + license: LicenseRef-Public-Domain purls: [] - size: 3670602 - timestamp: 1765223125237 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_17.conda - sha256: b961b5dd9761907a7179678b58a69bb4fc16b940eb477f635aea3aec0a3f17a6 - md5: 51b78c6a757575c0d12f4401ffc67029 + size: 119135 + timestamp: 1767016325805 +- conda: https://conda.anaconda.org/conda-forge/noarch/virtualenv-20.36.1-pyhd8ed1ab_0.conda + sha256: fa0a21fdcd0a8e6cf64cc8cd349ed6ceb373f09854fd3c4365f0bc4586dccf9a + md5: 6b0259cea8ffa6b66b35bae0ca01c447 depends: - - __glibc >=2.17,<3.0.a0 - license: GPL-3.0-only WITH GCC-exception-3.1 + - distlib >=0.3.7,<1 + - filelock >=3.20.1,<4 + - platformdirs >=3.9.1,<5 + - python >=3.10 + - typing_extensions >=4.13.2 + license: MIT + license_family: MIT + purls: + - pkg:pypi/virtualenv?source=hash-mapping + size: 4404318 + timestamp: 1768069793682 +- conda: https://conda.anaconda.org/conda-forge/osx-64/_openmp_mutex-4.5-7_kmp_llvm.conda + build_number: 7 + sha256: 30006902a9274de8abdad5a9f02ef7c8bb3d69a503486af0c1faee30b023e5b7 + md5: eaac87c21aff3ed21ad9656697bb8326 + depends: + - llvm-openmp >=9.0.1 + license: BSD-3-Clause + license_family: BSD purls: [] - size: 603334 - timestamp: 1770252441199 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libiconv-1.18-h3b78370_2.conda - sha256: c467851a7312765447155e071752d7bf9bf44d610a5687e32706f480aad2833f - md5: 915f5995e94f60e9a4826e0b0920ee88 + size: 8328 + timestamp: 1764092562779 +- conda: https://conda.anaconda.org/conda-forge/osx-64/bzip2-1.0.8-h500dc9f_8.conda + sha256: 8f50b58efb29c710f3cecf2027a8d7325ba769ab10c746eff75cea3ac050b10c + md5: 97c4b3bd8a90722104798175a1bdddbf depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=14 - license: LGPL-2.1-only + - __osx >=10.13 + license: bzip2-1.0.6 + license_family: BSD purls: [] - size: 790176 - timestamp: 1754908768807 -- conda: https://conda.anaconda.org/conda-forge/osx-64/libiconv-1.18-h57a12c2_2.conda - sha256: a1c8cecdf9966921e13f0ae921309a1f415dfbd2b791f2117cf7e8f5e61a48b6 - md5: 210a85a1119f97ea7887188d176db135 + size: 132607 + timestamp: 1757437730085 +- conda: https://conda.anaconda.org/conda-forge/osx-64/c-ares-1.34.6-hb5e19a0_0.conda + sha256: 2f5bc0292d595399df0d168355b4e9820affc8036792d6984bd751fdda2bcaea + md5: fc9a153c57c9f070bebaa7eef30a8f17 + depends: + - __osx >=10.13 + license: MIT + license_family: MIT + purls: [] + size: 186122 + timestamp: 1765215100384 +- conda: https://conda.anaconda.org/conda-forge/osx-64/cffi-2.0.0-py314h8ca4d5a_1.conda + sha256: e2c58cc2451cc96db2a3c8ec34e18889878db1e95cc3e32c85e737e02a7916fb + md5: 71c2caaa13f50fe0ebad0f961aee8073 + depends: + - __osx >=10.13 + - libffi >=3.5.2,<3.6.0a0 + - pycparser + - python >=3.14,<3.15.0a0 + - python_abi 3.14.* *_cp314 + license: MIT + license_family: MIT + purls: + - pkg:pypi/cffi?source=hash-mapping + size: 293633 + timestamp: 1761203106369 +- conda: https://conda.anaconda.org/conda-forge/osx-64/cyrus-sasl-2.1.28-h610c526_0.conda + sha256: beee5d279d48d67ba39f1b8f64bc050238d3d465fb9a53098eba2a85e9286949 + md5: 314cd5e4aefc50fec5ffd80621cfb4f8 + depends: + - __osx >=10.13 + - krb5 >=1.21.3,<1.22.0a0 + - libcxx >=18 + - libntlm >=1.8,<2.0a0 + - openssl >=3.5.0,<4.0a0 + license: BSD-3-Clause-Attribution + license_family: BSD + purls: [] + size: 197689 + timestamp: 1750239254864 +- conda: https://conda.anaconda.org/conda-forge/osx-64/davix-0.8.10-h35d429b_1.conda + sha256: e76f71e61622aedcb8b8e936cf0a595eb44123b3ac355c28e46c48622f6943f5 + md5: 558377132bfd2fe14f6dbd28d644b25c depends: + - openssl + - libcurl + - libxml2-devel + - libcxx >=19 - __osx >=10.13 + - gsoap >=2.8.123,<2.8.124.0a0 + - libxml2 + - libxml2-16 >=2.14.6 + - libzlib >=1.3.1,<2.0a0 + - openssl >=3.5.4,<4.0a0 + - gtest >=1.17.0,<1.17.1.0a0 license: LGPL-2.1-only purls: [] - size: 737846 - timestamp: 1754908900138 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libiconv-1.18-h23cfdf5_2.conda - sha256: de0336e800b2af9a40bdd694b03870ac4a848161b35c8a2325704f123f185f03 - md5: 4d5a7445f0b25b6a3ddbb56e790f5251 + size: 990237 + timestamp: 1764194905133 +- conda: https://conda.anaconda.org/conda-forge/osx-64/dcap-2.47.14-hf4fbb18_2.conda + sha256: a27f5509216f8e329bfa3f17f90ba75ec5042d1804056c556eb369d2b32bb4e1 + md5: ea46df07255b836c340deaab872e4049 + depends: + - gct >=6.2.1705709074,<6.2.1705709075.0a0 + - krb5 >=1.21.2,<1.22.0a0 + - libcxx >=16 + - libzlib >=1.2.13,<2.0.0a0 + - openssl >=3.2.1,<4.0a0 + license: LGPL-2.0-only + license_family: GPL + purls: [] + size: 162986 + timestamp: 1709906839770 +- conda: https://conda.anaconda.org/conda-forge/osx-64/gct-6.2.1705709074-h8d8e280_0.conda + sha256: 02abd54ab941346e41aa65bc32bb51750c24bb559660bc6b5c8710294a489349 + md5: fb76224d23bd06f2dc83791fa56eea23 depends: - __osx >=11.0 - license: LGPL-2.1-only + - libcxx >=16 + - libedit >=3.1.20191231,<3.2.0a0 + - libtool >=2.4.7,<3.0a0 + - libzlib >=1.2.13,<2.0.0a0 + - openssl >=3.2.1,<4.0a0 + - perl + license: Apache-2.0 + license_family: Apache purls: [] - size: 750379 - timestamp: 1754909073836 -- conda: https://conda.anaconda.org/conda-forge/osx-64/libintl-0.25.1-h3184127_1.conda - sha256: 8c352744517bc62d24539d1ecc813b9fdc8a785c780197c5f0b84ec5b0dfe122 - md5: a8e54eefc65645193c46e8b180f62d22 + size: 3229688 + timestamp: 1709825282762 +- conda: https://conda.anaconda.org/conda-forge/osx-64/gfal2-2.23.5-h6ef8084_0.conda + sha256: 82333798f4c4980de18baeed6fca6ffadb46cb149fd492f1d0f6c7c471bfebb7 + md5: 982b40947d8ed9d1e7e56cfc00a0cce3 depends: + - json-c >=0.18,<0.19.0a0 + - libcxx >=19 - __osx >=10.13 - - libiconv >=1.18,<2.0a0 - license: LGPL-2.1-or-later + - libssh2 >=1.11.1,<2.0a0 + - gct >=6.2.1705709074,<6.2.1705709075.0a0 + - libglib >=2.86.3,<3.0a0 + - davix >=0.8.10,<0.9.0a0 + - srm-ifce >=1.24.6,<2.0a0 + - gsoap >=2.8.123,<2.8.124.0a0 + - dcap >=2.47.14,<2.48.0a0 + - gtest >=1.17.0,<1.17.1.0a0 + - openldap >=2.6.10,<2.7.0a0 + - libzlib >=1.3.1,<2.0a0 + - pugixml >=1.15,<1.16.0a0 + - libuuid >=2.41.3,<3.0a0 + - xrootd >=5.8.4,<6.0a0 + license: Apache-2.0 + license_family: APACHE purls: [] - size: 96909 - timestamp: 1753343977382 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libintl-0.25.1-h493aca8_0.conda - sha256: 99d2cebcd8f84961b86784451b010f5f0a795ed1c08f1e7c76fbb3c22abf021a - md5: 5103f6a6b210a3912faf8d7db516918c + size: 814499 + timestamp: 1769072316410 +- conda: https://conda.anaconda.org/conda-forge/osx-64/gsoap-2.8.123-h21ae599_0.tar.bz2 + sha256: 6ddba7cd259edbe80e153dcc6f239f1391ff9277af62b0cf935e1060d74dcedd + md5: b5c0854d2a52f20ea68fa9c29a68b786 depends: - - __osx >=11.0 - - libiconv >=1.18,<2.0a0 - license: LGPL-2.1-or-later + - libcxx >=14.0.4 + - libzlib >=1.2.12,<2.0.0a0 + - openssl >=3.0.5,<4.0a0 + license: GPL-2.0-only + license_family: GPL purls: [] - size: 90957 - timestamp: 1751558394144 -- conda: https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-5_h47877c9_openblas.conda - build_number: 5 - sha256: c723b6599fcd4c6c75dee728359ef418307280fa3e2ee376e14e85e5bbdda053 - md5: b38076eb5c8e40d0106beda6f95d7609 + size: 1844166 + timestamp: 1662007947987 +- conda: https://conda.anaconda.org/conda-forge/osx-64/gtest-1.17.0-h9275861_1.conda + sha256: 95410f5b305170b65a8dca803981f9972051aaad3d7a5af608b94b2c2a56f88a + md5: 00ff8e205f86bf121c07c95f65205713 depends: - - libblas 3.11.0 5_h4a7cf45_openblas + - __osx >=10.13 + - libcxx >=18 constrains: - - blas 2.305 openblas - - liblapacke 3.11.0 5*_openblas - - libcblas 3.11.0 5*_openblas + - gmock 1.17.0 license: BSD-3-Clause license_family: BSD purls: [] - size: 18200 - timestamp: 1765818857876 -- conda: https://conda.anaconda.org/conda-forge/osx-64/liblapack-3.11.0-5_h859234e_openblas.conda - build_number: 5 - sha256: 2c915fe2b3d806d4b82776c882ba66ba3e095e9e2c41cc5c3375bffec6bddfdc - md5: eb5b1c25d4ac30813a6ca950a58710d6 + size: 391059 + timestamp: 1748320150242 +- conda: https://conda.anaconda.org/conda-forge/osx-64/icu-78.2-h14c5de8_0.conda + sha256: f3066beae7fe3002f09c8a412cdf1819f49a2c9a485f720ec11664330cf9f1fe + md5: 30334add4de016489b731c6662511684 depends: - - libblas 3.11.0 5_he492b99_openblas - constrains: - - libcblas 3.11.0 5*_openblas - - blas 2.305 openblas - - liblapacke 3.11.0 5*_openblas - license: BSD-3-Clause - license_family: BSD + - __osx >=10.13 + license: MIT + license_family: MIT purls: [] - size: 18491 - timestamp: 1765819090240 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/liblapack-3.11.0-5_hd9741b5_openblas.conda + size: 12263724 + timestamp: 1767970604977 +- conda: https://conda.anaconda.org/conda-forge/osx-64/json-c-0.18-hc62ec3d_0.conda + sha256: b58f8002318d6b880a98e1b0aa943789b3b0f49334a3bdb9c19b463a0b799cad + md5: 2c5a3c42de607dda0cfa0edd541fd279 + depends: + - __osx >=10.13 + license: MIT + license_family: MIT + purls: [] + size: 71514 + timestamp: 1726487153769 +- conda: https://conda.anaconda.org/conda-forge/osx-64/krb5-1.21.3-h37d8d59_0.conda + sha256: 83b52685a4ce542772f0892a0f05764ac69d57187975579a0835ff255ae3ef9c + md5: d4765c524b1d91567886bde656fb514b + depends: + - __osx >=10.13 + - libcxx >=16 + - libedit >=3.1.20191231,<3.2.0a0 + - libedit >=3.1.20191231,<4.0a0 + - openssl >=3.3.1,<4.0a0 + license: MIT + license_family: MIT + purls: [] + size: 1185323 + timestamp: 1719463492984 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libblas-3.11.0-5_he492b99_openblas.conda build_number: 5 - sha256: 735a6e6f7d7da6f718b6690b7c0a8ae4815afb89138aa5793abe78128e951dbb - md5: ca9d752201b7fa1225bca036ee300f2b + sha256: 4754de83feafa6c0b41385f8dab1b13f13476232e16f524564a340871a9fc3bc + md5: 36d2e68a156692cbae776b75d6ca6eae depends: - - libblas 3.11.0 5_h51639a9_openblas + - libopenblas >=0.3.30,<0.3.31.0a0 + - libopenblas >=0.3.30,<1.0a0 constrains: - - libcblas 3.11.0 5*_openblas + - liblapack 3.11.0 5*_openblas - blas 2.305 openblas + - libcblas 3.11.0 5*_openblas + - mkl <2026 - liblapacke 3.11.0 5*_openblas license: BSD-3-Clause license_family: BSD purls: [] - size: 18551 - timestamp: 1765819121855 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libltdl-2.4.3a-h5888daf_0.conda - sha256: 7620c6425d4491e17083106ca49624448fc16186c30a93cf2b58f862bba416d1 - md5: 8e5de39cab514fa908fcaa7ba37a8738 - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=13 - license: LGPL-2.0-or-later - license_family: LGPL - purls: [] - size: 38472 - timestamp: 1740593829307 -- conda: https://conda.anaconda.org/conda-forge/osx-64/libltdl-2.4.3a-h240833e_0.conda - sha256: 7fef7479b1d39fdee1764c3228ef5688a309c723e4ca33907c24ec309180a216 - md5: 4e6e81b4795bccb19fa94fef42d88f1b + size: 18476 + timestamp: 1765819054657 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libboost-1.88.0-h5950822_7.conda + sha256: 4cf91837a0af26996a43538213abe14adf54e07ac9fc8cb3880185f6e086c5df + md5: de6f7fa28d94fa380024444324b15d5f depends: - __osx >=10.13 - license: LGPL-2.0-or-later - license_family: LGPL - purls: [] - size: 36971 - timestamp: 1740593983760 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libltdl-2.4.3a-h286801f_0.conda - sha256: 69cdd97f0a31b2b1e8a8bd8ebc03c6042d2ba589721d2eead3d7815d801cafdd - md5: db358e8493bd213b5650b9f9e1d0d355 - depends: - - __osx >=11.0 - license: LGPL-2.0-or-later - license_family: LGPL - purls: [] - size: 37328 - timestamp: 1740594040504 -- conda: https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.2-hb03c661_0.conda - sha256: 755c55ebab181d678c12e49cced893598f2bab22d582fbbf4d8b83c18be207eb - md5: c7c83eecbb72d88b940c249af56c8b17 - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=14 + - bzip2 >=1.0.8,<2.0a0 + - icu >=78.1,<79.0a0 + - libcxx >=19 + - liblzma >=5.8.1,<6.0a0 + - libzlib >=1.3.1,<2.0a0 + - zstd >=1.5.7,<1.6.0a0 constrains: - - xz 5.8.2.* - license: 0BSD + - boost-cpp <0.0a0 + license: BSL-1.0 purls: [] - size: 113207 - timestamp: 1768752626120 -- conda: https://conda.anaconda.org/conda-forge/osx-64/liblzma-5.8.2-h11316ed_0.conda - sha256: 7ab3c98abd3b5d5ec72faa8d9f5d4b50dcee4970ed05339bc381861199dabb41 - md5: 688a0c3d57fa118b9c97bf7e471ab46c + size: 2091448 + timestamp: 1766348915727 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libboost-python-1.88.0-py314hee2ba4e_7.conda + sha256: ee37fd8e0293a50de5b2121aa7ca84fa199a4489bde2061df676c5cb4870da5c + md5: e387fe913fb05251520fa4d35e3a6f25 depends: - __osx >=10.13 + - libboost 1.88.0 h5950822_7 + - libcxx >=19 + - numpy >=1.23,<3 + - python >=3.14,<3.15.0a0 + - python_abi 3.14.* *_cp314 constrains: - - xz 5.8.2.* - license: 0BSD + - boost <0.0a0 + - py-boost <0.0a0 + license: BSL-1.0 purls: [] - size: 105482 - timestamp: 1768753411348 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/liblzma-5.8.2-h8088a28_0.conda - sha256: 7bfc7ffb2d6a9629357a70d4eadeadb6f88fa26ebc28f606b1c1e5e5ed99dc7e - md5: 009f0d956d7bfb00de86901d16e486c7 + size: 108601 + timestamp: 1766349368723 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libcblas-3.11.0-5_h9b27e0a_openblas.conda + build_number: 5 + sha256: 8077c29ea720bd152be6e6859a3765228cde51301fe62a3b3f505b377c2cb48c + md5: b31d771cbccff686e01a687708a7ca41 depends: - - __osx >=11.0 + - libblas 3.11.0 5_he492b99_openblas constrains: - - xz 5.8.2.* - license: 0BSD + - liblapack 3.11.0 5*_openblas + - blas 2.305 openblas + - liblapacke 3.11.0 5*_openblas + license: BSD-3-Clause + license_family: BSD purls: [] - size: 92242 - timestamp: 1768752982486 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb03c661_1.conda - sha256: fe171ed5cf5959993d43ff72de7596e8ac2853e9021dec0344e583734f1e0843 - md5: 2c21e66f50753a083cbe6b80f38268fa + size: 18484 + timestamp: 1765819073006 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libcurl-8.18.0-h9348e2b_0.conda + sha256: 1a0af3b7929af3c5893ebf50161978f54ae0256abb9532d4efba2735a0688325 + md5: de1910529f64ba4a9ac9005e0be78601 depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=14 - license: BSD-2-Clause - license_family: BSD + - __osx >=10.13 + - krb5 >=1.21.3,<1.22.0a0 + - libnghttp2 >=1.67.0,<2.0a0 + - libssh2 >=1.11.1,<2.0a0 + - libzlib >=1.3.1,<2.0a0 + - openssl >=3.5.4,<4.0a0 + - zstd >=1.5.7,<1.6.0a0 + license: curl + license_family: MIT purls: [] - size: 92400 - timestamp: 1769482286018 -- conda: https://conda.anaconda.org/conda-forge/osx-64/libmpdec-4.0.0-hf3981d6_1.conda - sha256: 1096c740109386607938ab9f09a7e9bca06d86770a284777586d6c378b8fb3fd - md5: ec88ba8a245855935b871a7324373105 + size: 419089 + timestamp: 1767822218800 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libcxx-21.1.8-h4fb565c_2.conda + sha256: 2619d471c50c466320e2aea906a4363e34efe181e61346e4453bc68264c5185f + md5: 1ac756454e65fb3fd7bc7de599526e43 + depends: + - __osx >=10.13 + license: Apache-2.0 WITH LLVM-exception + license_family: Apache + purls: [] + size: 571912 + timestamp: 1770237202404 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libedit-3.1.20250104-pl5321ha958ccf_0.conda + sha256: 6cc49785940a99e6a6b8c6edbb15f44c2dd6c789d9c283e5ee7bdfedd50b4cd6 + md5: 1f4ed31220402fcddc083b4bff406868 depends: + - ncurses - __osx >=10.13 + - ncurses >=6.5,<7.0a0 license: BSD-2-Clause license_family: BSD purls: [] - size: 79899 - timestamp: 1769482558610 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libmpdec-4.0.0-h84a0fba_1.conda - sha256: 1089c7f15d5b62c622625ec6700732ece83be8b705da8c6607f4dabb0c4bd6d2 - md5: 57c4be259f5e0b99a5983799a228ae55 - depends: - - __osx >=11.0 + size: 115563 + timestamp: 1738479554273 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libev-4.33-h10d778d_2.conda + sha256: 0d238488564a7992942aa165ff994eca540f687753b4f0998b29b4e4d030ff43 + md5: 899db79329439820b7e8f8de41bca902 license: BSD-2-Clause license_family: BSD purls: [] - size: 73690 - timestamp: 1769482560514 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libnghttp2-1.67.0-had1ee68_0.conda - sha256: a4a7dab8db4dc81c736e9a9b42bdfd97b087816e029e221380511960ac46c690 - md5: b499ce4b026493a13774bcf0f4c33849 + size: 106663 + timestamp: 1702146352558 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libexpat-2.7.3-heffb93a_0.conda + sha256: d11b3a6ce5b2e832f430fd112084533a01220597221bee16d6c7dc3947dffba6 + md5: 222e0732a1d0780a622926265bee14ef depends: - - __glibc >=2.17,<3.0.a0 - - c-ares >=1.34.5,<2.0a0 - - libev >=4.33,<4.34.0a0 - - libev >=4.33,<5.0a0 - - libgcc >=14 - - libstdcxx >=14 - - libzlib >=1.3.1,<2.0a0 - - openssl >=3.5.2,<4.0a0 + - __osx >=10.13 + constrains: + - expat 2.7.3.* license: MIT license_family: MIT purls: [] - size: 666600 - timestamp: 1756834976695 -- conda: https://conda.anaconda.org/conda-forge/osx-64/libnghttp2-1.67.0-h3338091_0.conda - sha256: c48d7e1cc927aef83ff9c48ae34dd1d7495c6ccc1edc4a3a6ba6aff1624be9ac - md5: e7630cef881b1174d40f3e69a883e55f + size: 74058 + timestamp: 1763549886493 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libffi-3.5.2-hd1f9c09_0.conda + sha256: 951958d1792238006fdc6fce7f71f1b559534743b26cc1333497d46e5903a2d6 + md5: 66a0dc7464927d0853b590b6f53ba3ea depends: - __osx >=10.13 - - c-ares >=1.34.5,<2.0a0 - - libcxx >=19 - - libev >=4.33,<4.34.0a0 - - libev >=4.33,<5.0a0 - - libzlib >=1.3.1,<2.0a0 - - openssl >=3.5.2,<4.0a0 license: MIT license_family: MIT purls: [] - size: 605680 - timestamp: 1756835898134 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libnghttp2-1.67.0-hc438710_0.conda - sha256: a07cb53b5ffa2d5a18afc6fd5a526a5a53dd9523fbc022148bd2f9395697c46d - md5: a4b4dd73c67df470d091312ab87bf6ae - depends: - - __osx >=11.0 - - c-ares >=1.34.5,<2.0a0 + size: 53583 + timestamp: 1769456300951 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libgcc-15.2.0-h08519bb_17.conda + sha256: c987bcc8fc9c9a689672a0c72942536c1b2ba83bd679971cc927d9f66668855b + md5: 500bac4a846e5001cbf05572df6c3654 + depends: + - _openmp_mutex + constrains: + - libgomp 15.2.0 17 + - libgcc-ng ==15.2.0=*_17 + license: GPL-3.0-only WITH GCC-exception-3.1 + purls: [] + size: 423903 + timestamp: 1770252717776 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libgfortran-15.2.0-h7e5c614_17.conda + sha256: c2b319a051e10501b76115a427ab76aa7c0a23b157b50726bcb572373ffb94c0 + md5: 218faf079bac8521ccf3f8542feeb51d + depends: + - libgfortran5 15.2.0 hd16e46c_17 + constrains: + - libgfortran-ng ==15.2.0=*_17 + license: GPL-3.0-only WITH GCC-exception-3.1 + purls: [] + size: 139677 + timestamp: 1770252942112 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libgfortran5-15.2.0-hd16e46c_17.conda + sha256: 464b13f5383bb0e38fecbf6bf5b2feadc12f5f57d7d0fd2d49ac051b10e453d3 + md5: bb0c5b043c41c27f4f73a103c6ad0c7f + depends: + - libgcc >=15.2.0 + constrains: + - libgfortran 15.2.0 + license: GPL-3.0-only WITH GCC-exception-3.1 + purls: [] + size: 1063057 + timestamp: 1770252727755 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libglib-2.86.3-hf241ffe_0.conda + sha256: d205ecdd0873dd92f7b55ac9b266b2eb09236ff5f3b26751579e435bbaed499c + md5: 584ce14b08050d3f1a25ab429b9360bc + depends: + - __osx >=10.13 + - libffi >=3.5.2,<3.6.0a0 + - libiconv >=1.18,<2.0a0 + - libintl >=0.25.1,<1.0a0 + - libzlib >=1.3.1,<2.0a0 + - pcre2 >=10.47,<10.48.0a0 + constrains: + - glib 2.86.3 *_0 + license: LGPL-2.1-or-later + purls: [] + size: 3708599 + timestamp: 1765222438844 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libiconv-1.18-h57a12c2_2.conda + sha256: a1c8cecdf9966921e13f0ae921309a1f415dfbd2b791f2117cf7e8f5e61a48b6 + md5: 210a85a1119f97ea7887188d176db135 + depends: + - __osx >=10.13 + license: LGPL-2.1-only + purls: [] + size: 737846 + timestamp: 1754908900138 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libintl-0.25.1-h3184127_1.conda + sha256: 8c352744517bc62d24539d1ecc813b9fdc8a785c780197c5f0b84ec5b0dfe122 + md5: a8e54eefc65645193c46e8b180f62d22 + depends: + - __osx >=10.13 + - libiconv >=1.18,<2.0a0 + license: LGPL-2.1-or-later + purls: [] + size: 96909 + timestamp: 1753343977382 +- conda: https://conda.anaconda.org/conda-forge/osx-64/liblapack-3.11.0-5_h859234e_openblas.conda + build_number: 5 + sha256: 2c915fe2b3d806d4b82776c882ba66ba3e095e9e2c41cc5c3375bffec6bddfdc + md5: eb5b1c25d4ac30813a6ca950a58710d6 + depends: + - libblas 3.11.0 5_he492b99_openblas + constrains: + - libcblas 3.11.0 5*_openblas + - blas 2.305 openblas + - liblapacke 3.11.0 5*_openblas + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 18491 + timestamp: 1765819090240 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libltdl-2.4.3a-h240833e_0.conda + sha256: 7fef7479b1d39fdee1764c3228ef5688a309c723e4ca33907c24ec309180a216 + md5: 4e6e81b4795bccb19fa94fef42d88f1b + depends: + - __osx >=10.13 + license: LGPL-2.0-or-later + license_family: LGPL + purls: [] + size: 36971 + timestamp: 1740593983760 +- conda: https://conda.anaconda.org/conda-forge/osx-64/liblzma-5.8.2-h11316ed_0.conda + sha256: 7ab3c98abd3b5d5ec72faa8d9f5d4b50dcee4970ed05339bc381861199dabb41 + md5: 688a0c3d57fa118b9c97bf7e471ab46c + depends: + - __osx >=10.13 + constrains: + - xz 5.8.2.* + license: 0BSD + purls: [] + size: 105482 + timestamp: 1768753411348 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libmpdec-4.0.0-hf3981d6_1.conda + sha256: 1096c740109386607938ab9f09a7e9bca06d86770a284777586d6c378b8fb3fd + md5: ec88ba8a245855935b871a7324373105 + depends: + - __osx >=10.13 + license: BSD-2-Clause + license_family: BSD + purls: [] + size: 79899 + timestamp: 1769482558610 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libnghttp2-1.67.0-h3338091_0.conda + sha256: c48d7e1cc927aef83ff9c48ae34dd1d7495c6ccc1edc4a3a6ba6aff1624be9ac + md5: e7630cef881b1174d40f3e69a883e55f + depends: + - __osx >=10.13 + - c-ares >=1.34.5,<2.0a0 - libcxx >=19 - libev >=4.33,<4.34.0a0 - libev >=4.33,<5.0a0 @@ -3569,18 +2704,8 @@ packages: license: MIT license_family: MIT purls: [] - size: 575454 - timestamp: 1756835746393 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libntlm-1.8-hb9d3cd8_0.conda - sha256: 3b3f19ced060013c2dd99d9d46403be6d319d4601814c772a3472fe2955612b0 - md5: 7c7927b404672409d9917d49bff5f2d6 - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=13 - license: LGPL-2.1-or-later - purls: [] - size: 33418 - timestamp: 1734670021371 + size: 605680 + timestamp: 1756835898134 - conda: https://conda.anaconda.org/conda-forge/osx-64/libntlm-1.8-h6e16a3a_0.conda sha256: 2ab918f7cc00852d70088e0b9e49fda4ef95229126cf3c52a8297686938385f2 md5: 23d706dbe90b54059ad86ff826677f39 @@ -3590,30 +2715,6 @@ packages: purls: [] size: 33742 timestamp: 1734670081910 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libntlm-1.8-h5505292_0.conda - sha256: ea8c680924d957e12270dca549620327d5e986f23c4bd5f45627167ca6ef7a3b - md5: c90c1d3bd778f5ec0d4bb4ef36cbd5b6 - depends: - - __osx >=11.0 - license: LGPL-2.1-or-later - purls: [] - size: 31099 - timestamp: 1734670168822 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.30-pthreads_h94d23a6_4.conda - sha256: 199d79c237afb0d4780ccd2fbf829cea80743df60df4705202558675e07dd2c5 - md5: be43915efc66345cccb3c310b6ed0374 - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=14 - - libgfortran - - libgfortran5 >=14.3.0 - constrains: - - openblas >=0.3.30,<0.3.31.0a0 - license: BSD-3-Clause - license_family: BSD - purls: [] - size: 5927939 - timestamp: 1763114673331 - conda: https://conda.anaconda.org/conda-forge/osx-64/libopenblas-0.3.30-openmp_h6006d49_4.conda sha256: ba642353f7f41ab2d2eb6410fbe522238f0f4483bcd07df30b3222b4454ee7cd md5: 9241a65e6e9605e4581a2a8005d7f789 @@ -3629,33 +2730,6 @@ packages: purls: [] size: 6268795 timestamp: 1763117623665 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libopenblas-0.3.30-openmp_ha158390_4.conda - sha256: ebbbc089b70bcde87c4121a083c724330f02a690fb9d7c6cd18c30f1b12504fa - md5: a6f6d3a31bb29e48d37ce65de54e2df0 - depends: - - __osx >=11.0 - - libgfortran - - libgfortran5 >=14.3.0 - - llvm-openmp >=19.1.7 - constrains: - - openblas >=0.3.30,<0.3.31.0a0 - license: BSD-3-Clause - license_family: BSD - purls: [] - size: 4284132 - timestamp: 1768547079205 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.2-hf4e2dac_0.conda - sha256: 04596fcee262a870e4b7c9807224680ff48d4d0cc0dac076a602503d3dc6d217 - md5: da5be73701eecd0e8454423fd6ffcf30 - depends: - - __glibc >=2.17,<3.0.a0 - - icu >=78.2,<79.0a0 - - libgcc >=14 - - libzlib >=1.3.1,<2.0a0 - license: blessing - purls: [] - size: 942808 - timestamp: 1768147973361 - conda: https://conda.anaconda.org/conda-forge/osx-64/libsqlite-3.51.2-hb99441e_0.conda sha256: 710a7ea27744199023c92e66ad005de7f8db9cf83f10d5a943d786f0dac53b7c md5: d910105ce2b14dfb2b32e92ec7653420 @@ -3666,30 +2740,6 @@ packages: purls: [] size: 987506 timestamp: 1768148247615 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsqlite-3.51.2-h1ae2325_0.conda - sha256: 6e9b9f269732cbc4698c7984aa5b9682c168e2a8d1e0406e1ff10091ca046167 - md5: 4b0bf313c53c3e89692f020fb55d5f2c - depends: - - __osx >=11.0 - - icu >=78.2,<79.0a0 - - libzlib >=1.3.1,<2.0a0 - license: blessing - purls: [] - size: 909777 - timestamp: 1768148320535 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libssh2-1.11.1-hcf80075_0.conda - sha256: fa39bfd69228a13e553bd24601332b7cfeb30ca11a3ca50bb028108fe90a7661 - md5: eecce068c7e4eddeb169591baac20ac4 - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=13 - - libzlib >=1.3.1,<2.0a0 - - openssl >=3.5.0,<4.0a0 - license: BSD-3-Clause - license_family: BSD - purls: [] - size: 304790 - timestamp: 1745608545575 - conda: https://conda.anaconda.org/conda-forge/osx-64/libssh2-1.11.1-hed3591d_0.conda sha256: 00654ba9e5f73aa1f75c1f69db34a19029e970a4aeb0fa8615934d8e9c369c3c md5: a6cb15db1c2dc4d3a5f6cf3772e09e81 @@ -3702,50 +2752,6 @@ packages: purls: [] size: 284216 timestamp: 1745608575796 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libssh2-1.11.1-h1590b86_0.conda - sha256: 8bfe837221390ffc6f111ecca24fa12d4a6325da0c8d131333d63d6c37f27e0a - md5: b68e8f66b94b44aaa8de4583d3d4cc40 - depends: - - libzlib >=1.3.1,<2.0a0 - - openssl >=3.5.0,<4.0a0 - license: BSD-3-Clause - license_family: BSD - purls: [] - size: 279193 - timestamp: 1745608793272 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_17.conda - sha256: 50c48cd3716a2e58e8e2e02edc78fef2d08fffe1e3b1ed40eb5f87e7e2d07889 - md5: 24c2fe35fa45cd71214beba6f337c071 - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc 15.2.0 he0feb66_17 - constrains: - - libstdcxx-ng ==15.2.0=*_17 - license: GPL-3.0-only WITH GCC-exception-3.1 - purls: [] - size: 5852406 - timestamp: 1770252584235 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_17.conda - sha256: ca3fb322dab3373946b1064da686ec076f5b1b9caf0a2823dad00d0b0f704928 - md5: ea12f5a6bf12c88c06750d9803e1a570 - depends: - - libstdcxx 15.2.0 h934c35e_17 - license: GPL-3.0-only WITH GCC-exception-3.1 - purls: [] - size: 27573 - timestamp: 1770252638797 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libtool-2.5.4-h5888daf_0.conda - sha256: c8245c70ba5b075e0cd61f430afbda00b60931603ed4ea31ce89e7fe930e4e3d - md5: 90697d80c181414aa3472199e136a04e - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=13 - - libltdl 2.4.3a h5888daf_0 - license: GPL-2.0-or-later - license_family: GPL - purls: [] - size: 415044 - timestamp: 1740593851157 - conda: https://conda.anaconda.org/conda-forge/osx-64/libtool-2.5.4-h240833e_0.conda sha256: 82afff0db640a8063db9d77a9c6d185bb5ffb8af0dd75cc15e6d5a4d9a64132c md5: 99cc5d8f880c8662e28c004a5cda6046 @@ -3757,28 +2763,6 @@ packages: purls: [] size: 414982 timestamp: 1740594046036 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libtool-2.5.4-h286801f_0.conda - sha256: e23da9c94975f3b0251b4e81ff70e0631702e103278038157cc4dfe4c2f3d851 - md5: bdd3ba2e9c5d24fa4341521df822f0c7 - depends: - - __osx >=11.0 - - libltdl 2.4.3a h286801f_0 - license: GPL-2.0-or-later - license_family: GPL - purls: [] - size: 414678 - timestamp: 1740594107488 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.3-h5347b49_0.conda - sha256: 1a7539cfa7df00714e8943e18de0b06cceef6778e420a5ee3a2a145773758aee - md5: db409b7c1720428638e7c0d509d3e1b5 - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=14 - license: BSD-3-Clause - license_family: BSD - purls: [] - size: 40311 - timestamp: 1766271528534 - conda: https://conda.anaconda.org/conda-forge/osx-64/libuuid-2.41.3-h3fe7000_0.conda sha256: 2f464c8c24fe8e6a96c7856c5fcc2a9e43689d24e98ddbeb2f9ef6b55d4289fa md5: 781317c18cbc0d1a08e37ccbd674b8e2 @@ -3789,25 +2773,6 @@ packages: purls: [] size: 35548 timestamp: 1766271548035 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libuuid-2.41.3-h0053d0f_0.conda - sha256: 28b4a4ef050413e7793dfb935e675a9f57423e20ea98f4c0b165d1386b05f93b - md5: 5e4c76ba638d70a2e1ba9ed34dc4dced - depends: - - __osx >=11.0 - license: BSD-3-Clause - license_family: BSD - purls: [] - size: 36727 - timestamp: 1766271567403 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libxcrypt-4.4.36-hd590300_1.conda - sha256: 6ae68e0b86423ef188196fff6207ed0c8195dd84273cb5623b85aa08033a410c - md5: 5aa797f8787fe7a17d1b0821485b5adc - depends: - - libgcc-ng >=12 - license: LGPL-2.1-or-later - purls: [] - size: 100393 - timestamp: 1702724383534 - conda: https://conda.anaconda.org/conda-forge/osx-64/libxcrypt-4.4.36-h10d778d_1.conda sha256: 7f438b1491326da20433b486efdbdfac3fe7b105676f44bcd4fb9a306a773b5c md5: c4497a698d8b932569aff7e1c15765de @@ -3815,76 +2780,6 @@ packages: purls: [] size: 97816 timestamp: 1702724522480 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libxcrypt-4.4.36-h93a5062_1.conda - sha256: 4c7884834f261a4b7d7d8bc9cfb9940f0a4bc5582a21624f386973bb254c7560 - md5: 7d2e687b217d4de0fa7064b4de3e0be8 - license: LGPL-2.1-or-later - purls: [] - size: 99413 - timestamp: 1702724499136 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.15.1-he237659_1.conda - sha256: 047be059033c394bd32ae5de66ce389824352120b3a7c0eff980195f7ed80357 - md5: 417955234eccd8f252b86a265ccdab7f - depends: - - __glibc >=2.17,<3.0.a0 - - icu >=78.1,<79.0a0 - - libgcc >=14 - - libiconv >=1.18,<2.0a0 - - liblzma >=5.8.1,<6.0a0 - - libxml2-16 2.15.1 hca6bf5a_1 - - libzlib >=1.3.1,<2.0a0 - license: MIT - license_family: MIT - purls: [] - size: 45402 - timestamp: 1766327161688 -- conda: https://conda.anaconda.org/conda-forge/osx-64/libxml2-2.15.1-h24ca049_1.conda - sha256: 24ecb3a3eed2b17cec150714210067cafc522dec111750cbc44f5921df1ffec3 - md5: c58fc83257ad06634b9c935099ef2680 - depends: - - __osx >=10.13 - - icu >=78.1,<79.0a0 - - libiconv >=1.18,<2.0a0 - - liblzma >=5.8.1,<6.0a0 - - libxml2-16 2.15.1 he456531_1 - - libzlib >=1.3.1,<2.0a0 - license: MIT - license_family: MIT - purls: [] - size: 40016 - timestamp: 1766327339623 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libxml2-2.15.1-h8d039ee_1.conda - sha256: 59f96fa27cce6a9a27414c5bb301eedda1a1b85cd0d8f5d68f77e46b86e7c95f - md5: fd804ee851e20faca4fecc7df0901d07 - depends: - - __osx >=11.0 - - icu >=78.1,<79.0a0 - - libiconv >=1.18,<2.0a0 - - liblzma >=5.8.1,<6.0a0 - - libxml2-16 2.15.1 h5ef1a60_1 - - libzlib >=1.3.1,<2.0a0 - license: MIT - license_family: MIT - purls: [] - size: 40607 - timestamp: 1766327501392 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libxml2-16-2.15.1-hca6bf5a_1.conda - sha256: 8331284bf9ae641b70cdc0e5866502dd80055fc3b9350979c74bb1d192e8e09e - md5: 3fdd8d99683da9fe279c2f4cecd1e048 - depends: - - __glibc >=2.17,<3.0.a0 - - icu >=78.1,<79.0a0 - - libgcc >=14 - - libiconv >=1.18,<2.0a0 - - liblzma >=5.8.1,<6.0a0 - - libzlib >=1.3.1,<2.0a0 - constrains: - - libxml2 2.15.1 - license: MIT - license_family: MIT - purls: [] - size: 555747 - timestamp: 1766327145986 - conda: https://conda.anaconda.org/conda-forge/osx-64/libxml2-16-2.15.1-he456531_1.conda sha256: eff0894cd82f2e055ea761773eb80bfaacdd13fbdd427a80fe0c5b00bf777762 md5: 6cd21078a491bdf3fdb7482e1680ef63 @@ -3901,39 +2796,21 @@ packages: purls: [] size: 494450 timestamp: 1766327317287 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libxml2-16-2.15.1-h5ef1a60_1.conda - sha256: 2d5ab15113b0ba21f4656d387d26ab59e4fbaf3027f5e58a2a4fe370821eb106 - md5: 7eed1026708e26ee512f43a04d9d0027 - depends: - - __osx >=11.0 - - icu >=78.1,<79.0a0 - - libiconv >=1.18,<2.0a0 - - liblzma >=5.8.1,<6.0a0 - - libzlib >=1.3.1,<2.0a0 - constrains: - - libxml2 2.15.1 - license: MIT - license_family: MIT - purls: [] - size: 464886 - timestamp: 1766327479416 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libxml2-devel-2.15.1-he237659_1.conda - sha256: 6621eb70375ff867c7c6606c216139e47eade8dfad78bcf7bdd0a62dc87d629f - md5: 644b2a3a92ba0bb8e2aa671dd831e793 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libxml2-2.15.1-h24ca049_1.conda + sha256: 24ecb3a3eed2b17cec150714210067cafc522dec111750cbc44f5921df1ffec3 + md5: c58fc83257ad06634b9c935099ef2680 depends: - - __glibc >=2.17,<3.0.a0 + - __osx >=10.13 - icu >=78.1,<79.0a0 - - libgcc >=14 - libiconv >=1.18,<2.0a0 - liblzma >=5.8.1,<6.0a0 - - libxml2 2.15.1 he237659_1 - - libxml2-16 2.15.1 hca6bf5a_1 + - libxml2-16 2.15.1 he456531_1 - libzlib >=1.3.1,<2.0a0 license: MIT license_family: MIT purls: [] - size: 79680 - timestamp: 1766327176426 + size: 40016 + timestamp: 1766327339623 - conda: https://conda.anaconda.org/conda-forge/osx-64/libxml2-devel-2.15.1-h24ca049_1.conda sha256: 5db52eae7357f89c16d08ab21ec89b35a7361e1d7be277716505e9764fe37eb8 md5: cc1c67f0676478f972e26c5649ea68ac @@ -3950,35 +2827,6 @@ packages: purls: [] size: 79886 timestamp: 1766327359472 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libxml2-devel-2.15.1-h8d039ee_1.conda - sha256: a51ac5f66270b5f21b6669d705531208ab599a8744c7e60c1638229e22c8267d - md5: 8975a4d0277920627000f0126c3c2b48 - depends: - - __osx >=11.0 - - icu >=78.1,<79.0a0 - - libiconv >=1.18,<2.0a0 - - liblzma >=5.8.1,<6.0a0 - - libxml2 2.15.1 h8d039ee_1 - - libxml2-16 2.15.1 h5ef1a60_1 - - libzlib >=1.3.1,<2.0a0 - license: MIT - license_family: MIT - purls: [] - size: 79725 - timestamp: 1766327519923 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda - sha256: d4bfe88d7cb447768e31650f06257995601f89076080e76df55e3112d4e47dc4 - md5: edb0dca6bc32e4f4789199455a1dbeb8 - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=13 - constrains: - - zlib 1.3.1 *_2 - license: Zlib - license_family: Other - purls: [] - size: 60963 - timestamp: 1727963148474 - conda: https://conda.anaconda.org/conda-forge/osx-64/libzlib-1.3.1-hd23fc13_2.conda sha256: 8412f96504fc5993a63edf1e211d042a1fd5b1d51dedec755d2058948fcced09 md5: 003a54a4e32b02f7355b50a837e699da @@ -3991,18 +2839,6 @@ packages: purls: [] size: 57133 timestamp: 1727963183990 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libzlib-1.3.1-h8359307_2.conda - sha256: ce34669eadaba351cd54910743e6a2261b67009624dbc7daeeafdef93616711b - md5: 369964e85dc26bfe78f41399b366c435 - depends: - - __osx >=11.0 - constrains: - - zlib 1.3.1 *_2 - license: Zlib - license_family: Other - purls: [] - size: 46438 - timestamp: 1727963202283 - conda: https://conda.anaconda.org/conda-forge/osx-64/llvm-openmp-21.1.8-h472b3d1_0.conda sha256: 2a41885f44cbc1546ff26369924b981efa37a29d20dc5445b64539ba240739e6 md5: e2d811e9f464dd67398b4ce1f9c7c872 @@ -4016,71 +2852,6 @@ packages: purls: [] size: 311405 timestamp: 1765965194247 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/llvm-openmp-21.1.8-h4a912ad_0.conda - sha256: 56bcd20a0a44ddd143b6ce605700fdf876bcf5c509adc50bf27e76673407a070 - md5: 206ad2df1b5550526e386087bef543c7 - depends: - - __osx >=11.0 - constrains: - - openmp 21.1.8|21.1.8.* - - intel-openmp <0.0a0 - license: Apache-2.0 WITH LLVM-exception - license_family: APACHE - purls: [] - size: 285974 - timestamp: 1765964756583 -- pypi: https://files.pythonhosted.org/packages/b3/68/aa714515d65090fcbcc9a1f3debd5a644b14aad11e59238f42f00bd4b298/logzero-1.7.0-py2.py3-none-any.whl - name: logzero - version: 1.7.0 - sha256: 23eb1f717a2736f9ab91ca0d43160fd2c996ad49ae6bad34652d47aba908769d - requires_dist: - - colorama ; sys_platform == 'win32' -- pypi: https://files.pythonhosted.org/packages/03/15/d4a377b385ab693ce97b472fe0c77c2b16ec79590e688b3ccc71fba19884/lxml-6.0.2-cp314-cp314-macosx_10_13_universal2.whl - name: lxml - version: 6.0.2 - sha256: b0c732aa23de8f8aec23f4b580d1e52905ef468afb4abeafd3fec77042abb6fe - requires_dist: - - cssselect>=0.7 ; extra == 'cssselect' - - html5lib ; extra == 'html5' - - beautifulsoup4 ; extra == 'htmlsoup' - - lxml-html-clean ; extra == 'html-clean' - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/29/9c/47293c58cc91769130fbf85531280e8cc7868f7fbb6d92f4670071b9cb3e/lxml-6.0.2-cp314-cp314-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl - name: lxml - version: 6.0.2 - sha256: 98a5e1660dc7de2200b00d53fa00bcd3c35a3608c305d45a7bbcaf29fa16e83d - requires_dist: - - cssselect>=0.7 ; extra == 'cssselect' - - html5lib ; extra == 'html5' - - beautifulsoup4 ; extra == 'htmlsoup' - - lxml-html-clean ; extra == 'html-clean' - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/c8/e8/c128e37589463668794d503afaeb003987373c5f94d667124ffd8078bbd9/lxml-6.0.2-cp314-cp314-macosx_10_13_x86_64.whl - name: lxml - version: 6.0.2 - sha256: 4468e3b83e10e0317a89a33d28f7aeba1caa4d1a6fd457d115dd4ffe90c5931d - requires_dist: - - cssselect>=0.7 ; extra == 'cssselect' - - html5lib ; extra == 'html5' - - beautifulsoup4 ; extra == 'htmlsoup' - - lxml-html-clean ; extra == 'html-clean' - requires_python: '>=3.8' -- conda: https://conda.anaconda.org/conda-forge/linux-64/m2crypto-0.45.1-py314haf11619_2.conda - sha256: f923b3fcc7875c24e21d6de6841fdacc150ca87146aa2a0ebcf39c0c9e7572fd - md5: edaeb576dc4f23f2063787f62da70fef - depends: - - openssl - - python - - __glibc >=2.17,<3.0.a0 - - libgcc >=14 - - openssl >=3.5.2,<4.0a0 - - python_abi 3.14.* *_cp314 - license: MIT - license_family: MIT - purls: - - pkg:pypi/m2crypto?source=hash-mapping - size: 413718 - timestamp: 1757689047646 - conda: https://conda.anaconda.org/conda-forge/osx-64/m2crypto-0.45.1-py314h90001a5_2.conda sha256: 9a574e31526783c5a8b60146623f5169eb15c213aa1ceefb86e1516ea7fd23c1 md5: d2b9b83d3c3681c4478de1ab9a951506 @@ -4096,125 +2867,9 @@ packages: - pkg:pypi/m2crypto?source=hash-mapping size: 396129 timestamp: 1757689123635 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/m2crypto-0.45.1-py314hdb6fb3f_2.conda - sha256: d5eaf9498468368f651c6bc72bec90c1441b2dd91f17112c1d0a32082abab8fb - md5: 8cae6040ec4477c78304682f18f950f5 - depends: - - openssl - - python - - __osx >=11.0 - - python 3.14.* *_cp314 - - openssl >=3.5.2,<4.0a0 - - python_abi 3.14.* *_cp314 - license: MIT - license_family: MIT - purls: - - pkg:pypi/m2crypto?source=hash-mapping - size: 395003 - timestamp: 1757689131892 -- pypi: https://files.pythonhosted.org/packages/94/54/e7d793b573f298e1c9013b8c4dade17d481164aa517d1d7148619c2cedbf/markdown_it_py-4.0.0-py3-none-any.whl - name: markdown-it-py - version: 4.0.0 - sha256: 87327c59b172c5011896038353a81343b6754500a08cd7a4973bb48c6d578147 - requires_dist: - - mdurl~=0.1 - - psutil ; extra == 'benchmarking' - - pytest ; extra == 'benchmarking' - - pytest-benchmark ; extra == 'benchmarking' - - commonmark~=0.9 ; extra == 'compare' - - markdown~=3.4 ; extra == 'compare' - - mistletoe~=1.0 ; extra == 'compare' - - mistune~=3.0 ; extra == 'compare' - - panflute~=2.3 ; extra == 'compare' - - markdown-it-pyrs ; extra == 'compare' - - linkify-it-py>=1,<3 ; extra == 'linkify' - - mdit-py-plugins>=0.5.0 ; extra == 'plugins' - - gprof2dot ; extra == 'profiling' - - mdit-py-plugins>=0.5.0 ; extra == 'rtd' - - myst-parser ; extra == 'rtd' - - pyyaml ; extra == 'rtd' - - sphinx ; extra == 'rtd' - - sphinx-copybutton ; extra == 'rtd' - - sphinx-design ; extra == 'rtd' - - sphinx-book-theme~=1.0 ; extra == 'rtd' - - jupyter-sphinx ; extra == 'rtd' - - ipykernel ; extra == 'rtd' - - coverage ; extra == 'testing' - - pytest ; extra == 'testing' - - pytest-cov ; extra == 'testing' - - pytest-regressions ; extra == 'testing' - - requests ; extra == 'testing' - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl - name: mdurl - version: 0.1.2 - sha256: 84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8 - requires_python: '>=3.7' -- pypi: https://files.pythonhosted.org/packages/7a/f0/8282d9641415e9e33df173516226b404d367a0fc55e1a60424a152913abc/mistune-3.1.4-py3-none-any.whl - name: mistune - version: 3.1.4 - sha256: 93691da911e5d9d2e23bc54472892aff676df27a75274962ff9edc210364266d - requires_dist: - - typing-extensions ; python_full_version < '3.11' - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/1b/9f/38ff9e57a2eade7bf9dfee5eae17f39fc0e998658050279cbb14d97d36d9/msgpack-1.1.2-cp314-cp314-macosx_11_0_arm64.whl - name: msgpack - version: 1.1.2 - sha256: 6c15b7d74c939ebe620dd8e559384be806204d73b4f9356320632d783d1f7939 - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/22/71/201105712d0a2ff07b7873ed3c220292fb2ea5120603c00c4b634bcdafb3/msgpack-1.1.2-cp314-cp314-macosx_10_13_x86_64.whl - name: msgpack - version: 1.1.2 - sha256: e23ce8d5f7aa6ea6d2a2b326b4ba46c985dbb204523759984430db7114f8aa00 - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/2f/40/dc34d1a8d5f1e51fc64640b62b191684da52ca469da9cd74e84936ffa4a6/msgpack-1.1.2-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - name: msgpack - version: 1.1.2 - sha256: 180759d89a057eab503cf62eeec0aa61c4ea1200dee709f3a8e9397dbb3b6931 - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/d5/22/492f2246bb5b534abd44804292e81eeaf835388901f0c574bac4eeec73c5/multidict-6.7.1-cp314-cp314-macosx_10_15_x86_64.whl - name: multidict - version: 6.7.1 - sha256: a407f13c188f804c759fc6a9f88286a565c242a76b27626594c133b82883b5c2 - requires_dist: - - typing-extensions>=4.1.0 ; python_full_version < '3.11' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/f1/4f/733c48f270565d78b4544f2baddc2fb2a245e5a8640254b12c36ac7ac68e/multidict-6.7.1-cp314-cp314-macosx_11_0_arm64.whl - name: multidict - version: 6.7.1 - sha256: 0e161ddf326db5577c3a4cc2d8648f81456e8a20d40415541587a71620d7a7d1 - requires_dist: - - typing-extensions>=4.1.0 ; python_full_version < '3.11' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/fe/3b/8ec5074bcfc450fe84273713b4b0a0dd47c0249358f5d82eb8104ffe2520/multidict-6.7.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - name: multidict - version: 6.7.1 - sha256: 7eee46ccb30ff48a1e35bb818cc90846c6be2b68240e42a78599166722cea709 - requires_dist: - - typing-extensions>=4.1.0 ; python_full_version < '3.11' - requires_python: '>=3.9' -- conda: https://conda.anaconda.org/conda-forge/linux-64/mypy-1.19.1-py314h5bd0f2a_0.conda - sha256: 4e607095b92cac2ec6dbb8de348d8e006408291c9c2805926f01e4a30e94edbb - md5: 0490f2b08d179719201fdb9514d67157 - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=14 - - mypy_extensions >=1.0.0 - - pathspec >=0.9.0 - - psutil >=4.0 - - python >=3.14,<3.15.0a0 - - python-librt >=0.6.2 - - python_abi 3.14.* *_cp314 - - typing_extensions >=4.6.0 - license: MIT - license_family: MIT - purls: - - pkg:pypi/mypy?source=hash-mapping - size: 18632958 - timestamp: 1765795548407 -- conda: https://conda.anaconda.org/conda-forge/osx-64/mypy-1.19.1-py314h6482030_0.conda - sha256: b36d3a5728413d18dedfecdfd0248647b21f3e725547c03ef245bc1c08da98f8 - md5: 62c7130c7f42ab43c9d1d64bbc7c2f3e +- conda: https://conda.anaconda.org/conda-forge/osx-64/mypy-1.19.1-py314h6482030_0.conda + sha256: b36d3a5728413d18dedfecdfd0248647b21f3e725547c03ef245bc1c08da98f8 + md5: 62c7130c7f42ab43c9d1d64bbc7c2f3e depends: - __osx >=10.13 - mypy_extensions >=1.0.0 @@ -4230,46 +2885,6 @@ packages: - pkg:pypi/mypy?source=hash-mapping size: 12043718 timestamp: 1765796036801 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/mypy-1.19.1-py314hbdd0d06_0.conda - sha256: c5c9a691dc00ce9a726426f971fbe21d0501ec8c6228513b945210898f26c761 - md5: 584f58048dc4af70f6c647b40a7049a6 - depends: - - __osx >=11.0 - - mypy_extensions >=1.0.0 - - pathspec >=0.9.0 - - psutil >=4.0 - - python >=3.14,<3.15.0a0 - - python >=3.14,<3.15.0a0 *_cp314 - - python-librt >=0.6.2 - - python_abi 3.14.* *_cp314 - - typing_extensions >=4.6.0 - license: MIT - license_family: MIT - purls: - - pkg:pypi/mypy?source=hash-mapping - size: 11320681 - timestamp: 1765795843941 -- conda: https://conda.anaconda.org/conda-forge/noarch/mypy_extensions-1.1.0-pyha770c72_0.conda - sha256: 6ed158e4e5dd8f6a10ad9e525631e35cee8557718f83de7a4e3966b1f772c4b1 - md5: e9c622e0d00fa24a6292279af3ab6d06 - depends: - - python >=3.9 - license: MIT - license_family: MIT - purls: - - pkg:pypi/mypy-extensions?source=hash-mapping - size: 11766 - timestamp: 1745776666688 -- conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda - sha256: 3fde293232fa3fca98635e1167de6b7c7fda83caf24b9d6c91ec9eefb4f4d586 - md5: 47e340acb35de30501a76c7c799c41d7 - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=13 - license: X11 AND BSD-3-Clause - purls: [] - size: 891641 - timestamp: 1738195959188 - conda: https://conda.anaconda.org/conda-forge/osx-64/ncurses-6.5-h0622a9a_3.conda sha256: ea4a5d27ded18443749aefa49dc79f6356da8506d508b5296f60b8d51e0c4bd9 md5: ced34dd9929f491ca6dab6a2927aff25 @@ -4279,90 +2894,6 @@ packages: purls: [] size: 822259 timestamp: 1738196181298 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/ncurses-6.5-h5e97a16_3.conda - sha256: 2827ada40e8d9ca69a153a45f7fd14f32b2ead7045d3bbb5d10964898fe65733 - md5: 068d497125e4bf8a66bf707254fff5ae - depends: - - __osx >=11.0 - license: X11 AND BSD-3-Clause - purls: [] - size: 797030 - timestamp: 1738196177597 -- pypi: https://files.pythonhosted.org/packages/9e/c9/b2622292ea83fbb4ec318f5b9ab867d0a28ab43c5717bb85b0a5f6b3b0a4/networkx-3.6.1-py3-none-any.whl - name: networkx - version: 3.6.1 - sha256: d47fbf302e7d9cbbb9e2555a0d267983d2aa476bac30e90dfbe5669bd57f3762 - requires_dist: - - asv ; extra == 'benchmarking' - - virtualenv ; extra == 'benchmarking' - - numpy>=1.25 ; extra == 'default' - - scipy>=1.11.2 ; extra == 'default' - - matplotlib>=3.8 ; extra == 'default' - - pandas>=2.0 ; extra == 'default' - - pre-commit>=4.1 ; extra == 'developer' - - mypy>=1.15 ; extra == 'developer' - - sphinx>=8.0 ; extra == 'doc' - - pydata-sphinx-theme>=0.16 ; extra == 'doc' - - sphinx-gallery>=0.18 ; extra == 'doc' - - numpydoc>=1.8.0 ; extra == 'doc' - - pillow>=10 ; extra == 'doc' - - texext>=0.6.7 ; extra == 'doc' - - myst-nb>=1.1 ; extra == 'doc' - - intersphinx-registry ; extra == 'doc' - - osmnx>=2.0.0 ; extra == 'example' - - momepy>=0.7.2 ; extra == 'example' - - contextily>=1.6 ; extra == 'example' - - seaborn>=0.13 ; extra == 'example' - - cairocffi>=1.7 ; extra == 'example' - - igraph>=0.11 ; extra == 'example' - - scikit-learn>=1.5 ; extra == 'example' - - iplotx>=0.9.0 ; extra == 'example' - - lxml>=4.6 ; extra == 'extra' - - pygraphviz>=1.14 ; extra == 'extra' - - pydot>=3.0.1 ; extra == 'extra' - - sympy>=1.10 ; extra == 'extra' - - build>=0.10 ; extra == 'release' - - twine>=4.0 ; extra == 'release' - - wheel>=0.40 ; extra == 'release' - - changelist==0.5 ; extra == 'release' - - pytest>=7.2 ; extra == 'test' - - pytest-cov>=4.0 ; extra == 'test' - - pytest-xdist>=3.0 ; extra == 'test' - - pytest-mpl ; extra == 'test-extras' - - pytest-randomly ; extra == 'test-extras' - requires_python: '>=3.11,!=3.14.1' -- conda: https://conda.anaconda.org/conda-forge/noarch/nodeenv-1.10.0-pyhd8ed1ab_0.conda - sha256: 4fa40e3e13fc6ea0a93f67dfc76c96190afd7ea4ffc1bac2612d954b42cdc3ee - md5: eb52d14a901e23c39e9e7b4a1a5c015f - depends: - - python >=3.10 - - setuptools - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/nodeenv?source=hash-mapping - size: 40866 - timestamp: 1766261270149 -- conda: https://conda.anaconda.org/conda-forge/linux-64/numpy-2.4.2-py314h2b28147_1.conda - sha256: 1d8377c8001c15ed12c2713b723213474b435706ab9d34ede69795d64af9e94d - md5: 4ea6b620fdf24a1a0bc4f1c7134dfafb - depends: - - python - - libstdcxx >=14 - - libgcc >=14 - - __glibc >=2.17,<3.0.a0 - - libcblas >=3.9.0,<4.0a0 - - python_abi 3.14.* *_cp314 - - libblas >=3.9.0,<4.0a0 - - liblapack >=3.9.0,<4.0a0 - constrains: - - numpy-base <0a0 - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/numpy?source=compressed-mapping - size: 8926994 - timestamp: 1770098474394 - conda: https://conda.anaconda.org/conda-forge/osx-64/numpy-2.4.2-py314hfc4c462_1.conda sha256: 13adde755c5daa6ae7d7dafcf64d0ba9d8b6aa249601eb163121953bccf6f030 md5: 891bda68803fbbcf08d37f94981b650a @@ -4382,44 +2913,9 @@ packages: - pkg:pypi/numpy?source=hash-mapping size: 8150788 timestamp: 1770098404066 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/numpy-2.4.2-py314hae46ccb_1.conda - sha256: 43b5ed0ead36e5133ee8462916d23284f0bce0e5f266fa4bd31a020a6cc22f14 - md5: 0f0ddf0575b98d91cda9e3ca9eaeb9a2 - depends: - - python - - __osx >=11.0 - - python 3.14.* *_cp314 - - libcxx >=19 - - libblas >=3.9.0,<4.0a0 - - liblapack >=3.9.0,<4.0a0 - - python_abi 3.14.* *_cp314 - - libcblas >=3.9.0,<4.0a0 - constrains: - - numpy-base <0a0 - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/numpy?source=hash-mapping - size: 6992958 - timestamp: 1770098398327 -- conda: https://conda.anaconda.org/conda-forge/linux-64/openldap-2.6.10-he970967_0.conda - sha256: cb0b07db15e303e6f0a19646807715d28f1264c6350309a559702f4f34f37892 - md5: 2e5bf4f1da39c0b32778561c3c4e5878 - depends: - - __glibc >=2.17,<3.0.a0 - - cyrus-sasl >=2.1.27,<3.0a0 - - krb5 >=1.21.3,<1.22.0a0 - - libgcc >=13 - - libstdcxx >=13 - - openssl >=3.5.0,<4.0a0 - license: OLDAP-2.8 - license_family: BSD - purls: [] - size: 780253 - timestamp: 1748010165522 -- conda: https://conda.anaconda.org/conda-forge/osx-64/openldap-2.6.10-hd8a590d_0.conda - sha256: 70b8c1ffc06629c3ef824d337ab75df28c50a05293a4c544b03ff41d82c37c73 - md5: 60bd9b6c1e5208ff2f4a39ab3eabdee8 +- conda: https://conda.anaconda.org/conda-forge/osx-64/openldap-2.6.10-hd8a590d_0.conda + sha256: 70b8c1ffc06629c3ef824d337ab75df28c50a05293a4c544b03ff41d82c37c73 + md5: 60bd9b6c1e5208ff2f4a39ab3eabdee8 depends: - __osx >=10.13 - cyrus-sasl >=2.1.27,<3.0a0 @@ -4431,32 +2927,6 @@ packages: purls: [] size: 777643 timestamp: 1748010635431 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/openldap-2.6.10-hbe55e7a_0.conda - sha256: 08d859836b81296c16f74336c3a9a455b23d57ce1d7c2b0b3e1b7a07f984c677 - md5: 6fd5d73c63b5d37d9196efb4f044af76 - depends: - - __osx >=11.0 - - cyrus-sasl >=2.1.27,<3.0a0 - - krb5 >=1.21.3,<1.22.0a0 - - libcxx >=18 - - openssl >=3.5.0,<4.0a0 - license: OLDAP-2.8 - license_family: BSD - purls: [] - size: 843597 - timestamp: 1748010484231 -- conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.1-h35e630c_1.conda - sha256: 44c877f8af015332a5d12f5ff0fb20ca32f896526a7d0cdb30c769df1144fb5c - md5: f61eb8cd60ff9057122a3d338b99c00f - depends: - - __glibc >=2.17,<3.0.a0 - - ca-certificates - - libgcc >=14 - license: Apache-2.0 - license_family: Apache - purls: [] - size: 3164551 - timestamp: 1769555830639 - conda: https://conda.anaconda.org/conda-forge/osx-64/openssl-3.6.1-hb6871ef_1.conda sha256: e02e5639b0e4d6d4fcf0f3b082642844fb5a37316f5b0a1126c6271347462e90 md5: 30bb8d08b99b9a7600d39efb3559fff0 @@ -4468,1751 +2938,2995 @@ packages: purls: [] size: 2777136 timestamp: 1769557662405 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.6.1-hd24854e_1.conda - sha256: 361f5c5e60052abc12bdd1b50d7a1a43e6a6653aab99a2263bf2288d709dcf67 - md5: f4f6ad63f98f64191c3e77c5f5f29d76 +- conda: https://conda.anaconda.org/conda-forge/osx-64/pcre2-10.47-h13923f0_0.conda + sha256: 8d64a9d36073346542e5ea042ef8207a45a0069a2e65ce3323ee3146db78134c + md5: 08f970fb2b75f5be27678e077ebedd46 depends: - - __osx >=11.0 - - ca-certificates - license: Apache-2.0 - license_family: Apache + - __osx >=10.13 + - bzip2 >=1.0.8,<2.0a0 + - libzlib >=1.3.1,<2.0a0 + license: BSD-3-Clause + license_family: BSD purls: [] - size: 3104268 - timestamp: 1769556384749 -- pypi: https://files.pythonhosted.org/packages/76/3e/c0b690253f0b82d86e99949af13533363acfb5432ecb5d53dd5b3bce9c34/orjson-3.11.9-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - name: orjson - version: 3.11.9 - sha256: aaea64f3f467d22e70eeed68bdccb3bc4f83f650446c4a03c59f2cba28a108db - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/8e/eb/5da01e356015aee6ecfa1187ced87aef51364e306f5e695dd52719bf0e78/orjson-3.11.9-cp314-cp314-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl - name: orjson - version: 3.11.9 - sha256: b6ef1979adc4bc243523f1a2ba91418030a8e29b0a99cbe7e0e2d6807d4dce6e - requires_python: '>=3.10' -- conda: https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda - sha256: c1fc0f953048f743385d31c468b4a678b3ad20caffdeaa94bed85ba63049fd58 - md5: b76541e68fea4d511b1ac46a28dcd2c6 + size: 1106584 + timestamp: 1763655837207 +- conda: https://conda.anaconda.org/conda-forge/osx-64/perl-5.32.1-7_h10d778d_perl5.conda + build_number: 7 + sha256: 8ebd35e2940055a93135b9fd11bef3662cecef72d6ee651f68d64a2f349863c7 + md5: dc442e0885c3a6b65e61c61558161a9e + license: GPL-1.0-or-later OR Artistic-1.0-Perl + purls: [] + size: 12334471 + timestamp: 1703311001432 +- conda: https://conda.anaconda.org/conda-forge/osx-64/psutil-7.2.2-py314hd330473_0.conda + sha256: 3194ce0d94c810cb1809da851261be34e1cae72ca345445b29e61766b38ee6cc + md5: d465805e603072c341554159939be5b8 + depends: + - python + - __osx >=10.13 + - python_abi 3.14.* *_cp314 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/psutil?source=hash-mapping + size: 242816 + timestamp: 1769678225798 +- conda: https://conda.anaconda.org/conda-forge/osx-64/pugixml-1.15-h46091d4_0.conda + sha256: d22fd205d2db21c835e233c30e91e348735e18418c35327b0406d2d917e39a90 + md5: 7a1ad34efe728093c36a76afeaf30586 + depends: + - __osx >=10.13 + - libcxx >=18 + license: MIT + license_family: MIT + purls: [] + size: 97559 + timestamp: 1736601483485 +- conda: https://conda.anaconda.org/conda-forge/osx-64/python-3.14.3-h4f44bb5_100_cp314.conda + build_number: 100 + sha256: cad6d156c5b27510f5c1bc74905534311456350357485a01e4a7c90a2554b998 + md5: b35e4ee0c1832ba9f8669f88983d44c5 + depends: + - __osx >=10.13 + - bzip2 >=1.0.8,<2.0a0 + - libexpat >=2.7.3,<3.0a0 + - libffi >=3.5.2,<3.6.0a0 + - liblzma >=5.8.2,<6.0a0 + - libmpdec >=4.0.0,<5.0a0 + - libsqlite >=3.51.2,<4.0a0 + - libzlib >=1.3.1,<2.0a0 + - ncurses >=6.5,<7.0a0 + - openssl >=3.5.5,<4.0a0 + - python_abi 3.14.* *_cp314 + - readline >=8.3,<9.0a0 + - tk >=8.6.13,<8.7.0a0 + - tzdata + - zstd >=1.5.7,<1.6.0a0 + license: Python-2.0 + purls: [] + size: 14395564 + timestamp: 1770272199897 + python_site_packages_path: lib/python3.14/site-packages +- conda: https://conda.anaconda.org/conda-forge/osx-64/python-gfal2-1.13.1-py314hd08135f_2.conda + sha256: d803ed5f41c9442955fc8ee1ba5333ae318d2e8b0284a83f4f32c483fb9386f0 + md5: b1350b323ee5397d92ddfe2842d63025 depends: - - python >=3.8 - python + - __osx >=10.13 + - libcxx >=19 + - python_abi 3.14.* *_cp314 + - libboost-python >=1.88.0,<1.89.0a0 + - gfal2 >=2.23.5,<2.24.0a0 + - libglib >=2.86.3,<3.0a0 license: Apache-2.0 license_family: APACHE purls: - - pkg:pypi/packaging?source=compressed-mapping - size: 72010 - timestamp: 1769093650580 -- pypi: https://files.pythonhosted.org/packages/15/88/3cdd54fa279341afa10acf8d2b503556b1375245dccc9315659f795dd2e9/pandas-3.0.2-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl - name: pandas - version: 3.0.2 - sha256: deeca1b5a931fdf0c2212c8a659ade6d3b1edc21f0914ce71ef24456ca7a6535 - requires_dist: - - numpy>=1.26.0 ; python_full_version < '3.14' - - numpy>=2.3.3 ; python_full_version >= '3.14' - - python-dateutil>=2.8.2 - - tzdata ; sys_platform == 'win32' - - tzdata ; sys_platform == 'emscripten' - - hypothesis>=6.116.0 ; extra == 'test' - - pytest>=8.3.4 ; extra == 'test' - - pytest-xdist>=3.6.1 ; extra == 'test' - - pyarrow>=13.0.0 ; extra == 'pyarrow' - - bottleneck>=1.4.2 ; extra == 'performance' - - numba>=0.60.0 ; extra == 'performance' - - numexpr>=2.10.2 ; extra == 'performance' - - scipy>=1.14.1 ; extra == 'computation' - - xarray>=2024.10.0 ; extra == 'computation' - - fsspec>=2024.10.0 ; extra == 'fss' - - s3fs>=2024.10.0 ; extra == 'aws' - - gcsfs>=2024.10.0 ; extra == 'gcp' - - odfpy>=1.4.1 ; extra == 'excel' - - openpyxl>=3.1.5 ; extra == 'excel' - - python-calamine>=0.3.0 ; extra == 'excel' - - pyxlsb>=1.0.10 ; extra == 'excel' - - xlrd>=2.0.1 ; extra == 'excel' - - xlsxwriter>=3.2.0 ; extra == 'excel' - - pyarrow>=13.0.0 ; extra == 'parquet' - - pyarrow>=13.0.0 ; extra == 'feather' - - pyiceberg>=0.8.1 ; extra == 'iceberg' - - tables>=3.10.1 ; extra == 'hdf5' - - pyreadstat>=1.2.8 ; extra == 'spss' - - sqlalchemy>=2.0.36 ; extra == 'postgresql' - - psycopg2>=2.9.10 ; extra == 'postgresql' - - adbc-driver-postgresql>=1.2.0 ; extra == 'postgresql' - - sqlalchemy>=2.0.36 ; extra == 'mysql' - - pymysql>=1.1.1 ; extra == 'mysql' - - sqlalchemy>=2.0.36 ; extra == 'sql-other' - - adbc-driver-postgresql>=1.2.0 ; extra == 'sql-other' - - adbc-driver-sqlite>=1.2.0 ; extra == 'sql-other' - - beautifulsoup4>=4.12.3 ; extra == 'html' - - html5lib>=1.1 ; extra == 'html' - - lxml>=5.3.0 ; extra == 'html' - - lxml>=5.3.0 ; extra == 'xml' - - matplotlib>=3.9.3 ; extra == 'plot' - - jinja2>=3.1.5 ; extra == 'output-formatting' - - tabulate>=0.9.0 ; extra == 'output-formatting' - - pyqt5>=5.15.9 ; extra == 'clipboard' - - qtpy>=2.4.2 ; extra == 'clipboard' - - zstandard>=0.23.0 ; extra == 'compression' - - pytz>=2024.2 ; extra == 'timezone' - - adbc-driver-postgresql>=1.2.0 ; extra == 'all' - - adbc-driver-sqlite>=1.2.0 ; extra == 'all' - - beautifulsoup4>=4.12.3 ; extra == 'all' - - bottleneck>=1.4.2 ; extra == 'all' - - fastparquet>=2024.11.0 ; extra == 'all' - - fsspec>=2024.10.0 ; extra == 'all' - - gcsfs>=2024.10.0 ; extra == 'all' - - html5lib>=1.1 ; extra == 'all' - - hypothesis>=6.116.0 ; extra == 'all' - - jinja2>=3.1.5 ; extra == 'all' - - lxml>=5.3.0 ; extra == 'all' - - matplotlib>=3.9.3 ; extra == 'all' - - numba>=0.60.0 ; extra == 'all' - - numexpr>=2.10.2 ; extra == 'all' - - odfpy>=1.4.1 ; extra == 'all' - - openpyxl>=3.1.5 ; extra == 'all' - - psycopg2>=2.9.10 ; extra == 'all' - - pyarrow>=13.0.0 ; extra == 'all' - - pyiceberg>=0.8.1 ; extra == 'all' - - pymysql>=1.1.1 ; extra == 'all' - - pyqt5>=5.15.9 ; extra == 'all' - - pyreadstat>=1.2.8 ; extra == 'all' - - pytest>=8.3.4 ; extra == 'all' - - pytest-xdist>=3.6.1 ; extra == 'all' - - python-calamine>=0.3.0 ; extra == 'all' - - pytz>=2024.2 ; extra == 'all' - - pyxlsb>=1.0.10 ; extra == 'all' - - qtpy>=2.4.2 ; extra == 'all' - - scipy>=1.14.1 ; extra == 'all' - - s3fs>=2024.10.0 ; extra == 'all' - - sqlalchemy>=2.0.36 ; extra == 'all' - - tables>=3.10.1 ; extra == 'all' - - tabulate>=0.9.0 ; extra == 'all' - - xarray>=2024.10.0 ; extra == 'all' - - xlrd>=2.0.1 ; extra == 'all' - - xlsxwriter>=3.2.0 ; extra == 'all' - - zstandard>=0.23.0 ; extra == 'all' - requires_python: '>=3.11' -- pypi: https://files.pythonhosted.org/packages/95/25/bdb9326c3b5455f8d4d3549fce7abcf967259de146fe2cf7a82368141948/pandas-3.0.2-cp314-cp314-macosx_11_0_arm64.whl - name: pandas - version: 3.0.2 - sha256: 0555c5882688a39317179ab4a0ed41d3ebc8812ab14c69364bbee8fb7a3f6288 - requires_dist: - - numpy>=1.26.0 ; python_full_version < '3.14' - - numpy>=2.3.3 ; python_full_version >= '3.14' - - python-dateutil>=2.8.2 - - tzdata ; sys_platform == 'win32' - - tzdata ; sys_platform == 'emscripten' - - hypothesis>=6.116.0 ; extra == 'test' - - pytest>=8.3.4 ; extra == 'test' - - pytest-xdist>=3.6.1 ; extra == 'test' - - pyarrow>=13.0.0 ; extra == 'pyarrow' - - bottleneck>=1.4.2 ; extra == 'performance' - - numba>=0.60.0 ; extra == 'performance' - - numexpr>=2.10.2 ; extra == 'performance' - - scipy>=1.14.1 ; extra == 'computation' - - xarray>=2024.10.0 ; extra == 'computation' - - fsspec>=2024.10.0 ; extra == 'fss' - - s3fs>=2024.10.0 ; extra == 'aws' - - gcsfs>=2024.10.0 ; extra == 'gcp' - - odfpy>=1.4.1 ; extra == 'excel' - - openpyxl>=3.1.5 ; extra == 'excel' - - python-calamine>=0.3.0 ; extra == 'excel' - - pyxlsb>=1.0.10 ; extra == 'excel' - - xlrd>=2.0.1 ; extra == 'excel' - - xlsxwriter>=3.2.0 ; extra == 'excel' - - pyarrow>=13.0.0 ; extra == 'parquet' - - pyarrow>=13.0.0 ; extra == 'feather' - - pyiceberg>=0.8.1 ; extra == 'iceberg' - - tables>=3.10.1 ; extra == 'hdf5' - - pyreadstat>=1.2.8 ; extra == 'spss' - - sqlalchemy>=2.0.36 ; extra == 'postgresql' - - psycopg2>=2.9.10 ; extra == 'postgresql' - - adbc-driver-postgresql>=1.2.0 ; extra == 'postgresql' - - sqlalchemy>=2.0.36 ; extra == 'mysql' - - pymysql>=1.1.1 ; extra == 'mysql' - - sqlalchemy>=2.0.36 ; extra == 'sql-other' - - adbc-driver-postgresql>=1.2.0 ; extra == 'sql-other' - - adbc-driver-sqlite>=1.2.0 ; extra == 'sql-other' - - beautifulsoup4>=4.12.3 ; extra == 'html' - - html5lib>=1.1 ; extra == 'html' - - lxml>=5.3.0 ; extra == 'html' - - lxml>=5.3.0 ; extra == 'xml' - - matplotlib>=3.9.3 ; extra == 'plot' - - jinja2>=3.1.5 ; extra == 'output-formatting' - - tabulate>=0.9.0 ; extra == 'output-formatting' - - pyqt5>=5.15.9 ; extra == 'clipboard' - - qtpy>=2.4.2 ; extra == 'clipboard' - - zstandard>=0.23.0 ; extra == 'compression' - - pytz>=2024.2 ; extra == 'timezone' - - adbc-driver-postgresql>=1.2.0 ; extra == 'all' - - adbc-driver-sqlite>=1.2.0 ; extra == 'all' - - beautifulsoup4>=4.12.3 ; extra == 'all' - - bottleneck>=1.4.2 ; extra == 'all' - - fastparquet>=2024.11.0 ; extra == 'all' - - fsspec>=2024.10.0 ; extra == 'all' - - gcsfs>=2024.10.0 ; extra == 'all' - - html5lib>=1.1 ; extra == 'all' - - hypothesis>=6.116.0 ; extra == 'all' - - jinja2>=3.1.5 ; extra == 'all' - - lxml>=5.3.0 ; extra == 'all' - - matplotlib>=3.9.3 ; extra == 'all' - - numba>=0.60.0 ; extra == 'all' - - numexpr>=2.10.2 ; extra == 'all' - - odfpy>=1.4.1 ; extra == 'all' - - openpyxl>=3.1.5 ; extra == 'all' - - psycopg2>=2.9.10 ; extra == 'all' - - pyarrow>=13.0.0 ; extra == 'all' - - pyiceberg>=0.8.1 ; extra == 'all' - - pymysql>=1.1.1 ; extra == 'all' - - pyqt5>=5.15.9 ; extra == 'all' - - pyreadstat>=1.2.8 ; extra == 'all' - - pytest>=8.3.4 ; extra == 'all' - - pytest-xdist>=3.6.1 ; extra == 'all' - - python-calamine>=0.3.0 ; extra == 'all' - - pytz>=2024.2 ; extra == 'all' - - pyxlsb>=1.0.10 ; extra == 'all' - - qtpy>=2.4.2 ; extra == 'all' - - scipy>=1.14.1 ; extra == 'all' - - s3fs>=2024.10.0 ; extra == 'all' - - sqlalchemy>=2.0.36 ; extra == 'all' - - tables>=3.10.1 ; extra == 'all' - - tabulate>=0.9.0 ; extra == 'all' - - xarray>=2024.10.0 ; extra == 'all' - - xlrd>=2.0.1 ; extra == 'all' - - xlsxwriter>=3.2.0 ; extra == 'all' - - zstandard>=0.23.0 ; extra == 'all' - requires_python: '>=3.11' -- pypi: https://files.pythonhosted.org/packages/bb/40/c6ea527147c73b24fc15c891c3fcffe9c019793119c5742b8784a062c7db/pandas-3.0.2-cp314-cp314-macosx_10_15_x86_64.whl - name: pandas - version: 3.0.2 - sha256: db0dbfd2a6cdf3770aa60464d50333d8f3d9165b2f2671bcc299b72de5a6677b - requires_dist: - - numpy>=1.26.0 ; python_full_version < '3.14' - - numpy>=2.3.3 ; python_full_version >= '3.14' - - python-dateutil>=2.8.2 - - tzdata ; sys_platform == 'win32' - - tzdata ; sys_platform == 'emscripten' - - hypothesis>=6.116.0 ; extra == 'test' - - pytest>=8.3.4 ; extra == 'test' - - pytest-xdist>=3.6.1 ; extra == 'test' - - pyarrow>=13.0.0 ; extra == 'pyarrow' - - bottleneck>=1.4.2 ; extra == 'performance' - - numba>=0.60.0 ; extra == 'performance' - - numexpr>=2.10.2 ; extra == 'performance' - - scipy>=1.14.1 ; extra == 'computation' - - xarray>=2024.10.0 ; extra == 'computation' - - fsspec>=2024.10.0 ; extra == 'fss' - - s3fs>=2024.10.0 ; extra == 'aws' - - gcsfs>=2024.10.0 ; extra == 'gcp' - - odfpy>=1.4.1 ; extra == 'excel' - - openpyxl>=3.1.5 ; extra == 'excel' - - python-calamine>=0.3.0 ; extra == 'excel' - - pyxlsb>=1.0.10 ; extra == 'excel' - - xlrd>=2.0.1 ; extra == 'excel' - - xlsxwriter>=3.2.0 ; extra == 'excel' - - pyarrow>=13.0.0 ; extra == 'parquet' - - pyarrow>=13.0.0 ; extra == 'feather' - - pyiceberg>=0.8.1 ; extra == 'iceberg' - - tables>=3.10.1 ; extra == 'hdf5' - - pyreadstat>=1.2.8 ; extra == 'spss' - - sqlalchemy>=2.0.36 ; extra == 'postgresql' - - psycopg2>=2.9.10 ; extra == 'postgresql' - - adbc-driver-postgresql>=1.2.0 ; extra == 'postgresql' - - sqlalchemy>=2.0.36 ; extra == 'mysql' - - pymysql>=1.1.1 ; extra == 'mysql' - - sqlalchemy>=2.0.36 ; extra == 'sql-other' - - adbc-driver-postgresql>=1.2.0 ; extra == 'sql-other' - - adbc-driver-sqlite>=1.2.0 ; extra == 'sql-other' - - beautifulsoup4>=4.12.3 ; extra == 'html' - - html5lib>=1.1 ; extra == 'html' - - lxml>=5.3.0 ; extra == 'html' - - lxml>=5.3.0 ; extra == 'xml' - - matplotlib>=3.9.3 ; extra == 'plot' - - jinja2>=3.1.5 ; extra == 'output-formatting' - - tabulate>=0.9.0 ; extra == 'output-formatting' - - pyqt5>=5.15.9 ; extra == 'clipboard' - - qtpy>=2.4.2 ; extra == 'clipboard' - - zstandard>=0.23.0 ; extra == 'compression' - - pytz>=2024.2 ; extra == 'timezone' - - adbc-driver-postgresql>=1.2.0 ; extra == 'all' - - adbc-driver-sqlite>=1.2.0 ; extra == 'all' - - beautifulsoup4>=4.12.3 ; extra == 'all' - - bottleneck>=1.4.2 ; extra == 'all' - - fastparquet>=2024.11.0 ; extra == 'all' - - fsspec>=2024.10.0 ; extra == 'all' - - gcsfs>=2024.10.0 ; extra == 'all' - - html5lib>=1.1 ; extra == 'all' - - hypothesis>=6.116.0 ; extra == 'all' - - jinja2>=3.1.5 ; extra == 'all' - - lxml>=5.3.0 ; extra == 'all' - - matplotlib>=3.9.3 ; extra == 'all' - - numba>=0.60.0 ; extra == 'all' - - numexpr>=2.10.2 ; extra == 'all' - - odfpy>=1.4.1 ; extra == 'all' - - openpyxl>=3.1.5 ; extra == 'all' - - psycopg2>=2.9.10 ; extra == 'all' - - pyarrow>=13.0.0 ; extra == 'all' - - pyiceberg>=0.8.1 ; extra == 'all' - - pymysql>=1.1.1 ; extra == 'all' - - pyqt5>=5.15.9 ; extra == 'all' - - pyreadstat>=1.2.8 ; extra == 'all' - - pytest>=8.3.4 ; extra == 'all' - - pytest-xdist>=3.6.1 ; extra == 'all' - - python-calamine>=0.3.0 ; extra == 'all' - - pytz>=2024.2 ; extra == 'all' - - pyxlsb>=1.0.10 ; extra == 'all' - - qtpy>=2.4.2 ; extra == 'all' - - scipy>=1.14.1 ; extra == 'all' - - s3fs>=2024.10.0 ; extra == 'all' - - sqlalchemy>=2.0.36 ; extra == 'all' - - tables>=3.10.1 ; extra == 'all' - - tabulate>=0.9.0 ; extra == 'all' - - xarray>=2024.10.0 ; extra == 'all' - - xlrd>=2.0.1 ; extra == 'all' - - xlsxwriter>=3.2.0 ; extra == 'all' - - zstandard>=0.23.0 ; extra == 'all' - requires_python: '>=3.11' -- pypi: https://files.pythonhosted.org/packages/a9/90/a744336f5af32c433bd09af7854599682a383b37cfd78f7de263de6ad6cb/paramiko-4.0.0-py3-none-any.whl - name: paramiko - version: 4.0.0 - sha256: 0e20e00ac666503bf0b4eda3b6d833465a2b7aff2e2b3d79a8bba5ef144ee3b9 - requires_dist: - - bcrypt>=3.2 - - cryptography>=3.3 - - invoke>=2.0 - - pynacl>=1.5 - - pyasn1>=0.1.7 ; extra == 'gssapi' - - gssapi>=1.4.1 ; sys_platform != 'win32' and extra == 'gssapi' - - pywin32>=2.1.8 ; sys_platform == 'win32' and extra == 'gssapi' - requires_python: '>=3.9' -- conda: https://conda.anaconda.org/conda-forge/noarch/pathspec-1.0.4-pyhd8ed1ab_0.conda - sha256: 29ea20d0faf20374fcd61c25f6d32fb8e9a2c786a7f1473a0c3ead359470fbe1 - md5: 2908273ac396d2cd210a8127f5f1c0d6 + - pkg:pypi/gfal2-python?source=hash-mapping + size: 191311 + timestamp: 1769083258369 +- conda: https://conda.anaconda.org/conda-forge/osx-64/python-librt-0.7.8-py314hd330473_0.conda + sha256: 9cbd3910f22d3c44a1635cc2646df218eedb4b97dc232db6f24ea4f93d271755 + md5: 2d35a795767f06747bba198e529c31c7 depends: - - python >=3.10 - license: MPL-2.0 - license_family: MOZILLA + - python + - __osx >=10.13 + - python_abi 3.14.* *_cp314 + license: MIT + license_family: MIT purls: - - pkg:pypi/pathspec?source=compressed-mapping - size: 53739 - timestamp: 1769677743677 -- conda: https://conda.anaconda.org/conda-forge/linux-64/pcre2-10.47-haa7fec5_0.conda - sha256: 5e6f7d161356fefd981948bea5139c5aa0436767751a6930cb1ca801ebb113ff - md5: 7a3bff861a6583f1889021facefc08b1 + - pkg:pypi/librt?source=hash-mapping + size: 57536 + timestamp: 1768406920191 +- conda: https://conda.anaconda.org/conda-forge/osx-64/pyyaml-6.0.3-py314h10d0514_1.conda + sha256: aef010899d642b24de6ccda3bc49ef008f8fddf7bad15ebce9bdebeae19a4599 + md5: ebd224b733573c50d2bfbeacb5449417 depends: - - __glibc >=2.17,<3.0.a0 - - bzip2 >=1.0.8,<2.0a0 - - libgcc >=14 - - libzlib >=1.3.1,<2.0a0 - license: BSD-3-Clause - license_family: BSD - purls: [] - size: 1222481 - timestamp: 1763655398280 -- conda: https://conda.anaconda.org/conda-forge/osx-64/pcre2-10.47-h13923f0_0.conda - sha256: 8d64a9d36073346542e5ea042ef8207a45a0069a2e65ce3323ee3146db78134c - md5: 08f970fb2b75f5be27678e077ebedd46 + - __osx >=10.13 + - python >=3.14,<3.15.0a0 + - python_abi 3.14.* *_cp314 + - yaml >=0.2.5,<0.3.0a0 + license: MIT + license_family: MIT + purls: + - pkg:pypi/pyyaml?source=hash-mapping + size: 191947 + timestamp: 1770226344240 +- conda: https://conda.anaconda.org/conda-forge/osx-64/readline-8.3-h68b038d_0.conda + sha256: 4614af680aa0920e82b953fece85a03007e0719c3399f13d7de64176874b80d5 + md5: eefd65452dfe7cce476a519bece46704 depends: - __osx >=10.13 - - bzip2 >=1.0.8,<2.0a0 - - libzlib >=1.3.1,<2.0a0 - license: BSD-3-Clause - license_family: BSD + - ncurses >=6.5,<7.0a0 + license: GPL-3.0-only + license_family: GPL purls: [] - size: 1106584 - timestamp: 1763655837207 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/pcre2-10.47-h30297fc_0.conda - sha256: 5e2e443f796f2fd92adf7978286a525fb768c34e12b1ee9ded4000a41b2894ba - md5: 9b4190c4055435ca3502070186eba53a + size: 317819 + timestamp: 1765813692798 +- conda: https://conda.anaconda.org/conda-forge/osx-64/rpds-py-0.30.0-py314ha7b6dee_0.conda + sha256: 368a758ba6f4fb3c6c9a0d25c090807553af5b3dc937a2180ff047fe8ebf6820 + md5: 816cb6c142c86de627fe7ffa1affddb2 depends: - - __osx >=11.0 - - bzip2 >=1.0.8,<2.0a0 - - libzlib >=1.3.1,<2.0a0 - license: BSD-3-Clause - license_family: BSD - purls: [] - size: 850231 - timestamp: 1763655726735 -- conda: https://conda.anaconda.org/conda-forge/linux-64/perl-5.32.1-7_hd590300_perl5.conda - build_number: 7 - sha256: 9ec32b6936b0e37bcb0ed34f22ec3116e75b3c0964f9f50ecea5f58734ed6ce9 - md5: f2cfec9406850991f4e3d960cc9e3321 - depends: - - libgcc-ng >=12 - - libxcrypt >=4.4.36 - license: GPL-1.0-or-later OR Artistic-1.0-Perl - purls: [] - size: 13344463 - timestamp: 1703310653947 -- conda: https://conda.anaconda.org/conda-forge/osx-64/perl-5.32.1-7_h10d778d_perl5.conda - build_number: 7 - sha256: 8ebd35e2940055a93135b9fd11bef3662cecef72d6ee651f68d64a2f349863c7 - md5: dc442e0885c3a6b65e61c61558161a9e - license: GPL-1.0-or-later OR Artistic-1.0-Perl - purls: [] - size: 12334471 - timestamp: 1703311001432 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/perl-5.32.1-7_h4614cfb_perl5.conda - build_number: 7 - sha256: b0c55040d2994fd6bf2f83786561d92f72306d982d6ea12889acad24a9bf43b8 - md5: ba3cbe93f99e896765422cc5f7c3a79e - license: GPL-1.0-or-later OR Artistic-1.0-Perl - purls: [] - size: 14439531 - timestamp: 1703311335652 -- pypi: https://files.pythonhosted.org/packages/9e/c3/059298687310d527a58bb01f3b1965787ee3b40dce76752eda8b44e9a2c5/pexpect-4.9.0-py2.py3-none-any.whl - name: pexpect - version: 4.9.0 - sha256: 7236d1e080e4936be2dc3e326cec0af72acf9212a7e1d060210e70a47e253523 - requires_dist: - - ptyprocess>=0.5 -- conda: https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.5.1-pyhcf101f3_0.conda - sha256: 04c64fb78c520e5c396b6e07bc9082735a5cc28175dbe23138201d0a9441800b - md5: 1bd2e65c8c7ef24f4639ae6e850dacc2 - depends: - - python >=3.10 - python + - __osx >=10.13 + - python_abi 3.14.* *_cp314 + constrains: + - __osx >=10.13 license: MIT license_family: MIT purls: - - pkg:pypi/platformdirs?source=hash-mapping - size: 23922 - timestamp: 1764950726246 -- conda: https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda - sha256: e14aafa63efa0528ca99ba568eaf506eb55a0371d12e6250aaaa61718d2eb62e - md5: d7585b6550ad04c8c5e21097ada2888e + - pkg:pypi/rpds-py?source=hash-mapping + size: 362381 + timestamp: 1764543188314 +- conda: https://conda.anaconda.org/conda-forge/osx-64/ruff-0.15.0-h5930b28_0.conda + noarch: python + sha256: de9f76a00b86053d340cb0cc43f119c9d917f870e71b0320e4fd6d7e00c74657 + md5: a48352b21637abd3e40822c4e6eb5c56 depends: - - python >=3.9 - python + - __osx >=10.13 + constrains: + - __osx >=10.13 license: MIT license_family: MIT purls: - - pkg:pypi/pluggy?source=compressed-mapping - size: 25877 - timestamp: 1764896838868 -- conda: https://conda.anaconda.org/conda-forge/noarch/pre-commit-4.5.1-pyha770c72_0.conda - sha256: 5b81b7516d4baf43d0c185896b245fa7384b25dc5615e7baa504b7fa4e07b706 - md5: 7f3ac694319c7eaf81a0325d6405e974 + - pkg:pypi/ruff?source=compressed-mapping + size: 9136186 + timestamp: 1770153825397 +- conda: https://conda.anaconda.org/conda-forge/osx-64/scitokens-cpp-1.3.0-hcb75e18_0.conda + sha256: d44f4ba1470d3e13c8f36c0086d5cbca97f3dbc05a0ed384be31ec56e79de3f0 + md5: 086d476a1c59a3984ef460bfb292425d depends: - - cfgv >=2.0.0 - - identify >=1.0.0 - - nodeenv >=0.11.1 - - python >=3.10 - - pyyaml >=5.1 - - virtualenv >=20.10.0 - license: MIT - license_family: MIT - purls: - - pkg:pypi/pre-commit?source=hash-mapping - size: 200827 - timestamp: 1765937577534 -- pypi: https://files.pythonhosted.org/packages/84/03/0d3ce49e2505ae70cf43bc5bb3033955d2fc9f932163e84dc0779cc47f48/prompt_toolkit-3.0.52-py3-none-any.whl - name: prompt-toolkit - version: 3.0.52 - sha256: 9aac639a3bbd33284347de5ad8d68ecc044b91a762dc39b7c21095fcd6a19955 - requires_dist: - - wcwidth - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/65/9b/03b04e7d82a5f54fb16113d839f5ea1ede58a61e90edf515f6577c66fa8f/propcache-0.4.1-cp314-cp314-macosx_10_13_x86_64.whl - name: propcache - version: 0.4.1 - sha256: c0d4b719b7da33599dfe3b22d3db1ef789210a0597bc650b7cee9c77c2be8c5c - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/b2/f2/889ad4b2408f72fe1a4f6a19491177b30ea7bf1a0fd5f17050ca08cfc882/propcache-0.4.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - name: propcache - version: 0.4.1 - sha256: 8326e144341460402713f91df60ade3c999d601e7eb5ff8f6f7862d54de0610d - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/b2/fa/89a8ef0468d5833a23fff277b143d0573897cf75bd56670a6d28126c7d68/propcache-0.4.1-cp314-cp314-macosx_11_0_arm64.whl - name: propcache - version: 0.4.1 - sha256: 9f302f4783709a78240ebc311b793f123328716a60911d667e0c036bc5dcbded - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/8e/fb/2c4c618185be2bda327f9dacd16b3122cc938809f19df7be840595d0e584/prov-1.5.1-py2.py3-none-any.whl - name: prov - version: 1.5.1 - sha256: 5c930cbbd05424aa3066d336dc31d314dd9fa0280caeab064288e592ed716bea - requires_dist: - - lxml - - networkx - - python-dateutil - - rdflib>=4.2.1 - - six>=1.9.0 - - pydot>=1.2.0 ; extra == 'dot' -- conda: https://conda.anaconda.org/conda-forge/linux-64/psutil-7.2.2-py314h0f05182_0.conda - sha256: f15574ed6c8c8ed8c15a0c5a00102b1efe8b867c0bd286b498cd98d95bd69ae5 - md5: 4f225a966cfee267a79c5cb6382bd121 + - __osx >=10.13 + - libcurl >=8.18.0,<9.0a0 + - libcxx >=19 + - libsqlite >=3.51.2,<4.0a0 + - openssl >=3.5.5,<4.0a0 + license: Apache-2.0 + license_family: APACHE + purls: [] + size: 184130 + timestamp: 1769697263474 +- conda: https://conda.anaconda.org/conda-forge/osx-64/srm-ifce-1.24.6-h73c9bdb_2.conda + sha256: 2004682e917722b471d9b9817ee3f14aa47b3832d4087f4f7f8b9965ecdae22a + md5: aea203ab9df6dc991bc26552617ccc66 depends: - - python - - libgcc >=14 - - __glibc >=2.17,<3.0.a0 - - python_abi 3.14.* *_cp314 - license: BSD-3-Clause + - gct >=6.2.1705709074,<6.2.1705709075.0a0 + - gsoap >=2.8.123,<2.8.124.0a0 + - libcxx >=16 + - libglib >=2.78.4,<3.0a0 + - openssl >=3.2.1,<4.0a0 + license: Apache-2.0 + license_family: Apache + purls: [] + size: 175433 + timestamp: 1709962268470 +- conda: https://conda.anaconda.org/conda-forge/osx-64/tk-8.6.13-h7142dee_3.conda + sha256: 7f0d9c320288532873e2d8486c331ec6d87919c9028208d3f6ac91dc8f99a67b + md5: 6e6efb7463f8cef69dbcb4c2205bf60e + depends: + - __osx >=10.13 + - libzlib >=1.3.1,<2.0a0 + license: TCL license_family: BSD - purls: - - pkg:pypi/psutil?source=compressed-mapping - size: 231303 - timestamp: 1769678156552 -- conda: https://conda.anaconda.org/conda-forge/osx-64/psutil-7.2.2-py314hd330473_0.conda - sha256: 3194ce0d94c810cb1809da851261be34e1cae72ca345445b29e61766b38ee6cc - md5: d465805e603072c341554159939be5b8 + purls: [] + size: 3282953 + timestamp: 1769460532442 +- conda: https://conda.anaconda.org/conda-forge/osx-64/ukkonen-1.1.0-py314h473ef84_0.conda + sha256: a77214fabb930c5332dece5407973c0c1c711298bf687976a0b6a9207b758e12 + md5: 08a26dd1ba8fc9681d6b5256b2895f8e depends: - - python - __osx >=10.13 + - cffi + - libcxx >=19 + - python >=3.14,<3.15.0a0 - python_abi 3.14.* *_cp314 - license: BSD-3-Clause - license_family: BSD + license: MIT + license_family: MIT purls: - - pkg:pypi/psutil?source=hash-mapping - size: 242816 - timestamp: 1769678225798 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/psutil-7.2.2-py314ha14b1ff_0.conda - sha256: e0f31c053eb11803d63860c213b2b1b57db36734f5f84a3833606f7c91fedff9 - md5: fc4c7ab223873eee32080d51600ce7e7 + - pkg:pypi/ukkonen?source=hash-mapping + size: 14286 + timestamp: 1769439103231 +- conda: https://conda.anaconda.org/conda-forge/osx-64/xrootd-5.9.1-py314hb36820e_0.conda + sha256: 85669c3b2ba7186b7f1b5c6440c09b16ab1d52424ece1d1eb145afb9237b3011 + md5: a6cf55d7323840b381a89b36f0947e96 depends: + - openssl - python - - __osx >=11.0 - - python 3.14.* *_cp314 + - readline + - libxml2-devel + - krb5 + - zlib + - ncurses + - libcxx >=19 + - __osx >=10.13 + - libcurl >=8.18.0,<9.0a0 + - libxml2 + - libxml2-16 >=2.14.6 + - readline >=8.3,<9.0a0 - python_abi 3.14.* *_cp314 - license: BSD-3-Clause - license_family: BSD + - libzlib >=1.3.1,<2.0a0 + - libxcrypt >=4.4.36 + - krb5 >=1.21.3,<1.22.0a0 + - ncurses >=6.5,<7.0a0 + - openssl >=3.5.4,<4.0a0 + - scitokens-cpp >=1.2.0,<2.0a0 + license: LGPL-3.0-or-later + license_family: LGPL purls: - - pkg:pypi/psutil?source=hash-mapping - size: 245502 - timestamp: 1769678303655 -- pypi: https://files.pythonhosted.org/packages/22/a6/858897256d0deac81a172289110f31629fc4cee19b6f01283303e18c8db3/ptyprocess-0.7.0-py2.py3-none-any.whl - name: ptyprocess - version: 0.7.0 - sha256: 4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35 -- conda: https://conda.anaconda.org/conda-forge/linux-64/pugixml-1.15-h3f63f65_0.conda - sha256: 23c98a5000356e173568dc5c5770b53393879f946f3ace716bbdefac2a8b23d2 - md5: b11a4c6bf6f6f44e5e143f759ffa2087 + - pkg:pypi/xrootd?source=hash-mapping + size: 3529962 + timestamp: 1769447937537 +- conda: https://conda.anaconda.org/conda-forge/osx-64/yaml-0.2.5-h4132b18_3.conda + sha256: a335161bfa57b64e6794c3c354e7d49449b28b8d8a7c4ed02bf04c3f009953f9 + md5: a645bb90997d3fc2aea0adf6517059bd depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=13 - - libstdcxx >=13 + - __osx >=10.13 license: MIT license_family: MIT purls: [] - size: 118488 - timestamp: 1736601364156 -- conda: https://conda.anaconda.org/conda-forge/osx-64/pugixml-1.15-h46091d4_0.conda - sha256: d22fd205d2db21c835e233c30e91e348735e18418c35327b0406d2d917e39a90 - md5: 7a1ad34efe728093c36a76afeaf30586 + size: 79419 + timestamp: 1753484072608 +- conda: https://conda.anaconda.org/conda-forge/osx-64/zlib-1.3.1-hd23fc13_2.conda + sha256: 219edbdfe7f073564375819732cbf7cc0d7c7c18d3f546a09c2dfaf26e4d69f3 + md5: c989e0295dcbdc08106fe5d9e935f0b9 depends: - __osx >=10.13 - - libcxx >=18 - license: MIT - license_family: MIT + - libzlib 1.3.1 hd23fc13_2 + license: Zlib + license_family: Other purls: [] - size: 97559 - timestamp: 1736601483485 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/pugixml-1.15-hd3d436d_0.conda - sha256: 5ad8d036040b095f85d23c70624d3e5e1e4c00bc5cea97831542f2dcae294ec9 - md5: b9a4004e46de7aeb005304a13b35cb94 - depends: - - __osx >=11.0 - - libcxx >=18 - license: MIT - license_family: MIT + size: 88544 + timestamp: 1727963189976 +- conda: https://conda.anaconda.org/conda-forge/osx-64/zstd-1.5.7-h3eecb57_6.conda + sha256: 47101a4055a70a4876ffc87b750ab2287b67eca793f21c8224be5e1ee6394d3f + md5: 727109b184d680772e3122f40136d5ca + depends: + - __osx >=10.13 + - libzlib >=1.3.1,<2.0a0 + license: BSD-3-Clause + license_family: BSD purls: [] - size: 91283 - timestamp: 1736601509593 -- pypi: https://files.pythonhosted.org/packages/44/b5/a96872e5184f354da9c84ae119971a0a4c221fe9b27a4d94bd43f2596727/pyasn1-0.6.2-py3-none-any.whl - name: pyasn1 - version: 0.6.2 - sha256: 1eb26d860996a18e9b6ed05e7aae0e9fc21619fcee6af91cca9bad4fbea224bf - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/47/8d/d529b5d697919ba8c11ad626e835d4039be708a35b0d22de83a269a6682c/pyasn1_modules-0.4.2-py3-none-any.whl - name: pyasn1-modules - version: 0.4.2 - sha256: 29253a9207ce32b64c3ac6600edc75368f98473906e8fd1043bd6b5b1de2c14a - requires_dist: - - pyasn1>=0.6.1,<0.7.0 - requires_python: '>=3.8' -- conda: https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda - sha256: 79db7928d13fab2d892592223d7570f5061c192f27b9febd1a418427b719acc6 - md5: 12c566707c80111f9799308d9e265aef + size: 528148 + timestamp: 1764777156963 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/_openmp_mutex-4.5-7_kmp_llvm.conda + build_number: 7 + sha256: 7acaa2e0782cad032bdaf756b536874346ac1375745fb250e9bdd6a48a7ab3cd + md5: a44032f282e7d2acdeb1c240308052dd depends: - - python >=3.9 - - python + - llvm-openmp >=9.0.1 license: BSD-3-Clause license_family: BSD - purls: - - pkg:pypi/pycparser?source=hash-mapping - size: 110100 - timestamp: 1733195786147 -- pypi: https://files.pythonhosted.org/packages/5a/87/b70ad306ebb6f9b585f114d0ac2137d792b48be34d732d60e597c2f8465a/pydantic-2.12.5-py3-none-any.whl - name: pydantic - version: 2.12.5 - sha256: e561593fccf61e8a20fc46dfc2dfe075b8be7d0188df33f221ad1f0139180f9d - requires_dist: - - annotated-types>=0.6.0 - - pydantic-core==2.41.5 - - typing-extensions>=4.14.1 - - typing-inspection>=0.4.2 - - email-validator>=2.0.0 ; extra == 'email' - - tzdata ; python_full_version >= '3.9' and sys_platform == 'win32' and extra == 'timezone' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/4c/d2/ef2074dc020dd6e109611a8be4449b98cd25e1b9b8a303c2f0fca2f2bcf7/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - name: pydantic-core - version: 2.41.5 - sha256: 22f0fb8c1c583a3b6f24df2470833b40207e907b90c928cc8d3594b76f874375 - requires_dist: - - typing-extensions>=4.14.1 - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/74/1a/145646e5687e8d9a1e8d09acb278c8535ebe9e972e1f162ed338a622f193/pydantic_core-2.41.5-cp314-cp314-macosx_11_0_arm64.whl - name: pydantic-core - version: 2.41.5 - sha256: 1d1d9764366c73f996edd17abb6d9d7649a7eb690006ab6adbda117717099b14 - requires_dist: - - typing-extensions>=4.14.1 - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/ea/28/46b7c5c9635ae96ea0fbb779e271a38129df2550f763937659ee6c5dbc65/pydantic_core-2.41.5-cp314-cp314-macosx_10_12_x86_64.whl - name: pydantic-core - version: 2.41.5 - sha256: 3f37a19d7ebcdd20b96485056ba9e8b304e27d9904d233d7b1015db320e51f0a - requires_dist: - - typing-extensions>=4.14.1 - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/c1/60/5d4751ba3f4a40a6891f24eec885f51afd78d208498268c734e256fb13c4/pydantic_settings-2.12.0-py3-none-any.whl - name: pydantic-settings - version: 2.12.0 - sha256: fddb9fd99a5b18da837b29710391e945b1e30c135477f484084ee513adb93809 - requires_dist: - - pydantic>=2.7.0 - - python-dotenv>=0.21.0 - - typing-inspection>=0.4.0 - - boto3-stubs[secretsmanager] ; extra == 'aws-secrets-manager' - - boto3>=1.35.0 ; extra == 'aws-secrets-manager' - - azure-identity>=1.16.0 ; extra == 'azure-key-vault' - - azure-keyvault-secrets>=4.8.0 ; extra == 'azure-key-vault' - - google-cloud-secret-manager>=2.23.1 ; extra == 'gcp-secret-manager' - - tomli>=2.0.1 ; extra == 'toml' - - pyyaml>=6.0.1 ; extra == 'yaml' - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/7e/32/a7125fb28c4261a627f999d5fb4afff25b523800faed2c30979949d6facd/pydot-4.0.1-py3-none-any.whl - name: pydot - version: 4.0.1 - sha256: 869c0efadd2708c0be1f916eb669f3d664ca684bc57ffb7ecc08e70d5e93fee6 - requires_dist: - - pyparsing>=3.1.0 - - ruff ; extra == 'lint' - - mypy ; extra == 'types' - - pydot[lint] ; extra == 'dev' - - pydot[types] ; extra == 'dev' - - chardet ; extra == 'dev' - - parameterized ; extra == 'dev' - - pydot[dev] ; extra == 'tests' - - tox ; extra == 'tests' - - pytest ; extra == 'tests' - - pytest-cov ; extra == 'tests' - - pytest-xdist[psutil] ; extra == 'tests' - - zest-releaser[recommended] ; extra == 'release' - requires_python: '>=3.8' -- conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda - sha256: 5577623b9f6685ece2697c6eb7511b4c9ac5fb607c9babc2646c811b428fd46a - md5: 6b6ece66ebcae2d5f326c77ef2c5a066 + purls: [] + size: 8325 + timestamp: 1764092507920 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/bzip2-1.0.8-hd037594_8.conda + sha256: b456200636bd5fecb2bec63f7e0985ad2097cf1b83d60ce0b6968dffa6d02aa1 + md5: 58fd217444c2a5701a44244faf518206 depends: - - python >=3.9 - license: BSD-2-Clause + - __osx >=11.0 + license: bzip2-1.0.6 license_family: BSD - purls: - - pkg:pypi/pygments?source=hash-mapping - size: 889287 - timestamp: 1750615908735 -- pypi: https://files.pythonhosted.org/packages/6f/01/c26ce75ba460d5cd503da9e13b21a33804d38c2165dec7b716d06b13010c/pyjwt-2.11.0-py3-none-any.whl - name: pyjwt - version: 2.11.0 - sha256: 94a6bde30eb5c8e04fee991062b534071fd1439ef58d2adc9ccb823e7bcd0469 - requires_dist: - - cryptography>=3.4.0 ; extra == 'crypto' - - coverage[toml]==7.10.7 ; extra == 'dev' - - cryptography>=3.4.0 ; extra == 'dev' - - pre-commit ; extra == 'dev' - - pytest>=8.4.2,<9.0.0 ; extra == 'dev' - - sphinx ; extra == 'dev' - - sphinx-rtd-theme ; extra == 'dev' - - zope-interface ; extra == 'dev' - - sphinx ; extra == 'docs' - - sphinx-rtd-theme ; extra == 'docs' - - zope-interface ; extra == 'docs' - - coverage[toml]==7.10.7 ; extra == 'tests' - - pytest>=8.4.2,<9.0.0 ; extra == 'tests' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/3e/d0/f301f83ac8dbe53442c5a43f6a39016f94f754d7a9815a875b65e218a307/pynacl-1.6.2-cp38-abi3-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl - name: pynacl - version: 1.6.2 - sha256: 8a66d6fb6ae7661c58995f9c6435bda2b1e68b54b598a6a10247bfcdadac996c - requires_dist: - - cffi>=1.4.1 ; python_full_version < '3.9' and platform_python_implementation != 'PyPy' - - cffi>=2.0.0 ; python_full_version >= '3.9' and platform_python_implementation != 'PyPy' - - pytest>=7.4.0 ; extra == 'tests' - - pytest-cov>=2.10.1 ; extra == 'tests' - - pytest-xdist>=3.5.0 ; extra == 'tests' - - hypothesis>=3.27.0 ; extra == 'tests' - - sphinx<7 ; extra == 'docs' - - sphinx-rtd-theme ; extra == 'docs' - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/be/7b/4845bbf88e94586ec47a432da4e9107e3fc3ce37eb412b1398630a37f7dd/pynacl-1.6.2-cp38-abi3-macosx_10_10_universal2.whl - name: pynacl - version: 1.6.2 - sha256: c949ea47e4206af7c8f604b8278093b674f7c79ed0d4719cc836902bf4517465 - requires_dist: - - cffi>=1.4.1 ; python_full_version < '3.9' and platform_python_implementation != 'PyPy' - - cffi>=2.0.0 ; python_full_version >= '3.9' and platform_python_implementation != 'PyPy' - - pytest>=7.4.0 ; extra == 'tests' - - pytest-cov>=2.10.1 ; extra == 'tests' - - pytest-xdist>=3.5.0 ; extra == 'tests' - - hypothesis>=3.27.0 ; extra == 'tests' - - sphinx<7 ; extra == 'docs' - - sphinx-rtd-theme ; extra == 'docs' - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/10/bd/c038d7cc38edc1aa5bf91ab8068b63d4308c66c4c8bb3cbba7dfbc049f9c/pyparsing-3.3.2-py3-none-any.whl - name: pyparsing - version: 3.3.2 - sha256: 850ba148bd908d7e2411587e247a1e4f0327839c40e2e5e6d05a007ecc69911d - requires_dist: - - railroad-diagrams ; extra == 'diagrams' - - jinja2 ; extra == 'diagrams' - requires_python: '>=3.9' -- conda: https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda - sha256: 9e749fb465a8bedf0184d8b8996992a38de351f7c64e967031944978de03a520 - md5: 2b694bad8a50dc2f712f5368de866480 + purls: [] + size: 125061 + timestamp: 1757437486465 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/c-ares-1.34.6-hc919400_0.conda + sha256: 2995f2aed4e53725e5efbc28199b46bf311c3cab2648fc4f10c2227d6d5fa196 + md5: bcb3cba70cf1eec964a03b4ba7775f01 depends: - - pygments >=2.7.2 - - python >=3.10 - - iniconfig >=1.0.1 - - packaging >=22 - - pluggy >=1.5,<2 - - tomli >=1 - - colorama >=0.4 - - exceptiongroup >=1 - - python - constrains: - - pytest-faulthandler >=2 + - __osx >=11.0 license: MIT license_family: MIT - purls: - - pkg:pypi/pytest?source=hash-mapping - size: 299581 - timestamp: 1765062031645 -- conda: https://conda.anaconda.org/conda-forge/noarch/pytest-asyncio-1.3.0-pyhcf101f3_0.conda - sha256: e782cf0555e4d54102423ad3421c8122f97a7a7c2d55c677a91e32d7c3e2b059 - md5: 80eccce75e6728e9e728370984bdc6fd - depends: - - pytest >=8.2,<10 - - python >=3.10 - - typing_extensions >=4.12 - - backports.asyncio.runner >=1.1,<2 - - python - license: Apache-2.0 - license_family: APACHE - purls: - - pkg:pypi/pytest-asyncio?source=hash-mapping - size: 39223 - timestamp: 1762797319837 -- conda: https://conda.anaconda.org/conda-forge/noarch/pytest-mock-3.15.1-pyhd8ed1ab_0.conda - sha256: 2936717381a2740c7bef3d96827c042a3bba3ba1496c59892989296591e3dabb - md5: 0511afbe860b1a653125d77c719ece53 + purls: [] + size: 180327 + timestamp: 1765215064054 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/cffi-2.0.0-py314h44086f9_1.conda + sha256: 5b5ee5de01eb4e4fd2576add5ec9edfc654fbaf9293e7b7ad2f893a67780aa98 + md5: 10dd19e4c797b8f8bdb1ec1fbb6821d7 depends: - - pytest >=6.2.5 - - python >=3.10 + - __osx >=11.0 + - libffi >=3.5.2,<3.6.0a0 + - pycparser + - python >=3.14,<3.15.0a0 + - python >=3.14,<3.15.0a0 *_cp314 + - python_abi 3.14.* *_cp314 license: MIT license_family: MIT purls: - - pkg:pypi/pytest-mock?source=hash-mapping - size: 22968 - timestamp: 1758101248317 -- conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.14.3-h32b2ec7_100_cp314.conda - build_number: 100 - sha256: ff087b19d158644d3b0708eca10a5e40d692cdc8e95f53715f4490c6959f3768 - md5: b40594d5da041824087eebe12228af42 + - pkg:pypi/cffi?source=hash-mapping + size: 292983 + timestamp: 1761203354051 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/cyrus-sasl-2.1.28-ha1cbb27_0.conda + sha256: 7de03254fa5421e7ec2347c830a59530fb5356022ee0dc26ec1cef0be1de0911 + md5: 2867ea6551e97e53a81787fd967162b1 depends: - - __glibc >=2.17,<3.0.a0 - - bzip2 >=1.0.8,<2.0a0 - - ld_impl_linux-64 >=2.36.1 - - libexpat >=2.7.3,<3.0a0 - - libffi >=3.5.2,<3.6.0a0 - - libgcc >=14 - - liblzma >=5.8.2,<6.0a0 - - libmpdec >=4.0.0,<5.0a0 - - libsqlite >=3.51.2,<4.0a0 - - libuuid >=2.41.3,<3.0a0 - - libzlib >=1.3.1,<2.0a0 - - ncurses >=6.5,<7.0a0 - - openssl >=3.5.5,<4.0a0 - - python_abi 3.14.* *_cp314 - - readline >=8.3,<9.0a0 - - tk >=8.6.13,<8.7.0a0 - - tzdata - - zstd >=1.5.7,<1.6.0a0 - license: Python-2.0 + - __osx >=11.0 + - krb5 >=1.21.3,<1.22.0a0 + - libcxx >=18 + - libntlm >=1.8,<2.0a0 + - openssl >=3.5.0,<4.0a0 + license: BSD-3-Clause-Attribution + license_family: BSD purls: [] - size: 36529771 - timestamp: 1770271970971 - python_site_packages_path: lib/python3.14/site-packages -- conda: https://conda.anaconda.org/conda-forge/osx-64/python-3.14.3-h4f44bb5_100_cp314.conda - build_number: 100 - sha256: cad6d156c5b27510f5c1bc74905534311456350357485a01e4a7c90a2554b998 - md5: b35e4ee0c1832ba9f8669f88983d44c5 + size: 193732 + timestamp: 1750239236574 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/davix-0.8.10-h0b7473d_1.conda + sha256: de0e457af62183ef91e7b92d172da9887d1bd21f1f85122656c47d79199c49ec + md5: 59f9ecae2150f2e7feaeb72349923965 depends: - - __osx >=10.13 - - bzip2 >=1.0.8,<2.0a0 - - libexpat >=2.7.3,<3.0a0 - - libffi >=3.5.2,<3.6.0a0 - - liblzma >=5.8.2,<6.0a0 - - libmpdec >=4.0.0,<5.0a0 - - libsqlite >=3.51.2,<4.0a0 + - openssl + - libcurl + - libxml2-devel + - libcxx >=19 + - __osx >=11.0 + - gtest >=1.17.0,<1.17.1.0a0 + - openssl >=3.5.4,<4.0a0 + - libxml2 + - libxml2-16 >=2.14.6 - libzlib >=1.3.1,<2.0a0 - - ncurses >=6.5,<7.0a0 - - openssl >=3.5.5,<4.0a0 - - python_abi 3.14.* *_cp314 - - readline >=8.3,<9.0a0 - - tk >=8.6.13,<8.7.0a0 - - tzdata - - zstd >=1.5.7,<1.6.0a0 - license: Python-2.0 + - gsoap >=2.8.123,<2.8.124.0a0 + license: LGPL-2.1-only purls: [] - size: 14395564 - timestamp: 1770272199897 - python_site_packages_path: lib/python3.14/site-packages -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/python-3.14.3-h4c637c5_100_cp314.conda - build_number: 100 - sha256: 05f63767b548e9dd1d4d3b5978721703b376ce451c7dfaba8ba3ca020e11bc76 - md5: 97852749b58606ffe363c2cc491cfce1 + size: 926053 + timestamp: 1764194930352 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/dcap-2.47.14-h33e0366_2.conda + sha256: fd0c392617be15682341deaa473637a73361964ce3154539833e69390d4cccfc + md5: 5d4e4cda1dcbe3c2503e2440be7c1954 depends: - - __osx >=11.0 - - bzip2 >=1.0.8,<2.0a0 - - libexpat >=2.7.3,<3.0a0 - - libffi >=3.5.2,<3.6.0a0 - - liblzma >=5.8.2,<6.0a0 - - libmpdec >=4.0.0,<5.0a0 - - libsqlite >=3.51.2,<4.0a0 - - libzlib >=1.3.1,<2.0a0 - - ncurses >=6.5,<7.0a0 - - openssl >=3.5.5,<4.0a0 - - python_abi 3.14.* *_cp314 - - readline >=8.3,<9.0a0 - - tk >=8.6.13,<8.7.0a0 - - tzdata - - zstd >=1.5.7,<1.6.0a0 - license: Python-2.0 + - gct >=6.2.1705709074,<6.2.1705709075.0a0 + - krb5 >=1.21.2,<1.22.0a0 + - libcxx >=16 + - libzlib >=1.2.13,<2.0.0a0 + - openssl >=3.2.1,<4.0a0 + license: LGPL-2.0-only + license_family: GPL purls: [] - size: 13553519 - timestamp: 1770271668429 - python_site_packages_path: lib/python3.14/site-packages -- pypi: https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl - name: python-dateutil - version: 2.9.0.post0 - sha256: a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427 - requires_dist: - - six>=1.5 - requires_python: '>=2.7,!=3.0.*,!=3.1.*,!=3.2.*' -- pypi: https://files.pythonhosted.org/packages/14/1b/a298b06749107c305e1fe0f814c6c74aea7b2f1e10989cb30f544a1b3253/python_dotenv-1.2.1-py3-none-any.whl - name: python-dotenv - version: 1.2.1 - sha256: b81ee9561e9ca4004139c6cbba3a238c32b03e4894671e181b671e8cb8425d61 - requires_dist: - - click>=5.0 ; extra == 'cli' - requires_python: '>=3.9' -- conda: https://conda.anaconda.org/conda-forge/linux-64/python-gfal2-1.13.1-py314h1571e64_2.conda - sha256: a549f56ae1e753ffba31b69f42889a9e45112f572a538c2d2c21d114da7aca39 - md5: 5f47942674eda34dbd006be72b036e6b + size: 171436 + timestamp: 1709906737580 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/gct-6.2.1705709074-h07e554c_0.conda + sha256: eaadb01056b490a777e9dfa7fc6f176f41cbb4ae07e434513de680fc561c64f3 + md5: 4703e9e9400e3824297171fd972ce97a depends: - - python - - libgcc >=14 - - __glibc >=2.17,<3.0.a0 - - libstdcxx >=14 - - libboost-python >=1.88.0,<1.89.0a0 - - libglib >=2.86.3,<3.0a0 - - gfal2 >=2.23.5,<2.24.0a0 - - python_abi 3.14.* *_cp314 + - libcxx >=16 + - libedit >=3.1.20191231,<3.2.0a0 + - libtool >=2.4.7,<3.0a0 + - libzlib >=1.2.13,<2.0.0a0 + - openssl >=3.2.1,<4.0a0 + - perl license: Apache-2.0 - license_family: APACHE - purls: - - pkg:pypi/gfal2-python?source=hash-mapping - size: 201775 - timestamp: 1769083114809 -- conda: https://conda.anaconda.org/conda-forge/osx-64/python-gfal2-1.13.1-py314hd08135f_2.conda - sha256: d803ed5f41c9442955fc8ee1ba5333ae318d2e8b0284a83f4f32c483fb9386f0 - md5: b1350b323ee5397d92ddfe2842d63025 + license_family: Apache + purls: [] + size: 3410291 + timestamp: 1709824989090 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/gfal2-2.23.5-h46ca294_0.conda + sha256: 86f943d3531e3636a458c25f9bc11ace03bea4a745f90867cb3d9607f932bd0f + md5: f6fbc5578b64a47c78cc2e7b5b58ffe5 depends: - - python - - __osx >=10.13 + - json-c >=0.18,<0.19.0a0 - libcxx >=19 - - python_abi 3.14.* *_cp314 - - libboost-python >=1.88.0,<1.89.0a0 - - gfal2 >=2.23.5,<2.24.0a0 + - __osx >=11.0 + - srm-ifce >=1.24.6,<2.0a0 + - gsoap >=2.8.123,<2.8.124.0a0 + - davix >=0.8.10,<0.9.0a0 + - dcap >=2.47.14,<2.48.0a0 + - openldap >=2.6.10,<2.7.0a0 - libglib >=2.86.3,<3.0a0 + - xrootd >=5.8.4,<6.0a0 + - libuuid >=2.41.3,<3.0a0 + - gtest >=1.17.0,<1.17.1.0a0 + - libssh2 >=1.11.1,<2.0a0 + - gct >=6.2.1705709074,<6.2.1705709075.0a0 + - libzlib >=1.3.1,<2.0a0 + - pugixml >=1.15,<1.16.0a0 license: Apache-2.0 license_family: APACHE - purls: - - pkg:pypi/gfal2-python?source=hash-mapping - size: 191311 - timestamp: 1769083258369 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/python-gfal2-1.13.1-py314h5c1db39_2.conda - sha256: a94056439b953daed560227e6128a3fcf55fdb8f18f9b36793a29c1b64c16391 - md5: 7e203553047ba0626fdbb8e86e6a89d2 + purls: [] + size: 756388 + timestamp: 1769072357132 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/gsoap-2.8.123-hfb11b17_0.tar.bz2 + sha256: c0cb7fc084ecf7a522044010d755ee697b878e82a8f579db29bf36c473ae18ba + md5: e01fe9aa10adaca07d0b9bcd073fab52 + depends: + - libcxx >=14.0.4 + - libzlib >=1.2.12,<2.0.0a0 + - openssl >=3.0.5,<4.0a0 + license: GPL-2.0-only + license_family: GPL + purls: [] + size: 1907483 + timestamp: 1662008204245 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/gtest-1.17.0-ha393de7_1.conda + sha256: 441fb779db5f14eff8997ddde88c90c30ab64ea8bd4c219b76724e4d3d736c76 + md5: f277a9eb8063fe7c4e33d91b8296fb0c depends: - - python - - libcxx >=19 - __osx >=11.0 - - python 3.14.* *_cp314 - - gfal2 >=2.23.5,<2.24.0a0 - - python_abi 3.14.* *_cp314 - - libboost-python >=1.88.0,<1.89.0a0 - - libglib >=2.86.3,<3.0a0 - license: Apache-2.0 - license_family: APACHE - purls: - - pkg:pypi/gfal2-python?source=hash-mapping - size: 185917 - timestamp: 1769083275804 -- pypi: https://files.pythonhosted.org/packages/38/ee/a61bb562bdf6f0bc6c51cdcf80ab5503cbb4b2f5053fa4b054cc0a56e48a/python_gitlab-8.2.0-py3-none-any.whl - name: python-gitlab - version: 8.2.0 - sha256: 884618d4d60beadb21bb0c5f0cca46e70c6e501784f136bf0b6f85f5bc15ce62 - requires_dist: - - requests>=2.32.0 - - requests-toolbelt>=1.0.0 - - argcomplete>=1.10.0,<3 ; extra == 'autocompletion' - - pyyaml>=6.0.1 ; extra == 'yaml' - - gql[httpx]>=3.5.0,<5 ; extra == 'graphql' - requires_python: '>=3.10.0' -- conda: https://conda.anaconda.org/conda-forge/linux-64/python-librt-0.7.8-py314h0f05182_0.conda - sha256: 7c4615367e1d8bee1e98abcfccd742fb0c382a150f21cb592a66af69063eae43 - md5: 1cdbb8798d700d90f33998d41baed1ec + - libcxx >=18 + constrains: + - gmock 1.17.0 + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 378391 + timestamp: 1748320218212 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/icu-78.2-h38cb7af_0.conda + sha256: d4cefbca587429d1192509edc52c88de52bc96c2447771ddc1f8bee928aed5ef + md5: 1e93aca311da0210e660d2247812fa02 depends: - - python - - __glibc >=2.17,<3.0.a0 - - libgcc >=14 - - python_abi 3.14.* *_cp314 + - __osx >=11.0 license: MIT license_family: MIT - purls: - - pkg:pypi/librt?source=hash-mapping - size: 64072 - timestamp: 1768406896488 -- conda: https://conda.anaconda.org/conda-forge/osx-64/python-librt-0.7.8-py314hd330473_0.conda - sha256: 9cbd3910f22d3c44a1635cc2646df218eedb4b97dc232db6f24ea4f93d271755 - md5: 2d35a795767f06747bba198e529c31c7 + purls: [] + size: 12358010 + timestamp: 1767970350308 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/json-c-0.18-he4178ee_0.conda + sha256: 73179a1cd0b45c09d4f631cb359d9e755e6e573c5d908df42006728e0bf8297c + md5: 94f14ef6157687c30feb44e1abecd577 depends: - - python - - __osx >=10.13 - - python_abi 3.14.* *_cp314 + - __osx >=11.0 license: MIT license_family: MIT - purls: - - pkg:pypi/librt?source=hash-mapping - size: 57536 - timestamp: 1768406920191 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/python-librt-0.7.8-py314ha14b1ff_0.conda - sha256: 3af72999955913d5f1f1eec62ff5080ff14e44435f527e273e310a5e3e7682d9 - md5: 89c4e1720ff541a874b45fe06b4e1e1e + purls: [] + size: 73715 + timestamp: 1726487214495 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/krb5-1.21.3-h237132a_0.conda + sha256: 4442f957c3c77d69d9da3521268cad5d54c9033f1a73f99cde0a3658937b159b + md5: c6dc8a0fdec13a0565936655c33069a1 depends: - - python - __osx >=11.0 - - python 3.14.* *_cp314 - - python_abi 3.14.* *_cp314 + - libcxx >=16 + - libedit >=3.1.20191231,<3.2.0a0 + - libedit >=3.1.20191231,<4.0a0 + - openssl >=3.3.1,<4.0a0 license: MIT license_family: MIT - purls: - - pkg:pypi/librt?source=hash-mapping - size: 65713 - timestamp: 1768407001203 -- conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314.conda - build_number: 8 - sha256: ad6d2e9ac39751cc0529dd1566a26751a0bf2542adb0c232533d32e176e21db5 - md5: 0539938c55b6b1a59b560e843ad864a4 + purls: [] + size: 1155530 + timestamp: 1719463474401 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libblas-3.11.0-5_h51639a9_openblas.conda + build_number: 5 + sha256: 620a6278f194dcabc7962277da6835b1e968e46ad0c8e757736255f5ddbfca8d + md5: bcc025e2bbaf8a92982d20863fe1fb69 + depends: + - libopenblas >=0.3.30,<0.3.31.0a0 + - libopenblas >=0.3.30,<1.0a0 constrains: - - python 3.14.* *_cp314 + - libcblas 3.11.0 5*_openblas + - liblapack 3.11.0 5*_openblas + - liblapacke 3.11.0 5*_openblas + - blas 2.305 openblas + - mkl <2026 license: BSD-3-Clause license_family: BSD purls: [] - size: 6989 - timestamp: 1752805904792 -- pypi: https://files.pythonhosted.org/packages/81/c4/34e93fe5f5429d7570ec1fa436f1986fb1f00c3e0f43a589fe2bbcd22c3f/pytz-2025.2-py2.py3-none-any.whl - name: pytz - version: '2025.2' - sha256: 5ddf76296dd8c44c26eb8f4b6f35488f3ccbf6fbbd7adee0b7262d43f0ec2f00 -- conda: https://conda.anaconda.org/conda-forge/linux-64/pyyaml-6.0.3-py314h67df5f8_1.conda - sha256: b318fb070c7a1f89980ef124b80a0b5ccf3928143708a85e0053cde0169c699d - md5: 2035f68f96be30dc60a5dfd7452c7941 - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=14 - - python >=3.14,<3.15.0a0 - - python_abi 3.14.* *_cp314 - - yaml >=0.2.5,<0.3.0a0 - license: MIT - license_family: MIT - purls: - - pkg:pypi/pyyaml?source=compressed-mapping - size: 202391 - timestamp: 1770223462836 -- conda: https://conda.anaconda.org/conda-forge/osx-64/pyyaml-6.0.3-py314h10d0514_1.conda - sha256: aef010899d642b24de6ccda3bc49ef008f8fddf7bad15ebce9bdebeae19a4599 - md5: ebd224b733573c50d2bfbeacb5449417 + size: 18546 + timestamp: 1765819094137 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libboost-1.88.0-h0419b56_7.conda + sha256: d3872915a43512b0404e131d965e6e8c1e2546b13ccfd2463ef72fbfe1456afc + md5: 34e8ce0732bb254bd17f0b9ecea788c2 depends: - - __osx >=10.13 - - python >=3.14,<3.15.0a0 - - python_abi 3.14.* *_cp314 - - yaml >=0.2.5,<0.3.0a0 - license: MIT - license_family: MIT - purls: - - pkg:pypi/pyyaml?source=hash-mapping - size: 191947 - timestamp: 1770226344240 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyyaml-6.0.3-py314h6e9b3f0_1.conda - sha256: 95f385f9606e30137cf0b5295f63855fd22223a4cf024d306cf9098ea1c4a252 - md5: dcf51e564317816cb8d546891019b3ab + - __osx >=11.0 + - bzip2 >=1.0.8,<2.0a0 + - icu >=78.1,<79.0a0 + - libcxx >=19 + - liblzma >=5.8.1,<6.0a0 + - libzlib >=1.3.1,<2.0a0 + - zstd >=1.5.7,<1.6.0a0 + constrains: + - boost-cpp <0.0a0 + license: BSL-1.0 + purls: [] + size: 1992135 + timestamp: 1766348005115 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libboost-python-1.88.0-py314hce24fef_7.conda + sha256: 3f6be1bbb56c17e4b362b8b7b80568733e76108f289cb11ca4f14289ed173366 + md5: 545c065df173b77ab97eb6ad190b985e depends: - __osx >=11.0 + - libboost 1.88.0 h0419b56_7 + - libcxx >=19 + - numpy >=1.23,<3 - python >=3.14,<3.15.0a0 - python >=3.14,<3.15.0a0 *_cp314 - python_abi 3.14.* *_cp314 - - yaml >=0.2.5,<0.3.0a0 - license: MIT + constrains: + - py-boost <0.0a0 + - boost <0.0a0 + license: BSL-1.0 + purls: [] + size: 107891 + timestamp: 1766348725978 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcblas-3.11.0-5_hb0561ab_openblas.conda + build_number: 5 + sha256: 38809c361bbd165ecf83f7f05fae9b791e1baa11e4447367f38ae1327f402fc0 + md5: efd8bd15ca56e9d01748a3beab8404eb + depends: + - libblas 3.11.0 5_h51639a9_openblas + constrains: + - liblapacke 3.11.0 5*_openblas + - liblapack 3.11.0 5*_openblas + - blas 2.305 openblas + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 18548 + timestamp: 1765819108956 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcurl-8.18.0-he38603e_0.conda + sha256: 11c78b3e89bc332933386f0a11ac60d9200afb7a811b9e3bec98aef8d4a6389b + md5: 36190179a799f3aee3c2d20a8a2b970d + depends: + - __osx >=11.0 + - krb5 >=1.21.3,<1.22.0a0 + - libnghttp2 >=1.67.0,<2.0a0 + - libssh2 >=1.11.1,<2.0a0 + - libzlib >=1.3.1,<2.0a0 + - openssl >=3.5.4,<4.0a0 + - zstd >=1.5.7,<1.6.0a0 + license: curl license_family: MIT - purls: - - pkg:pypi/pyyaml?source=compressed-mapping - size: 189475 - timestamp: 1770223788648 -- pypi: https://files.pythonhosted.org/packages/2d/e1/c2141f1840a41e07ad2db6f724945f8f8ff3065463899a22939152dd6e09/rapidfuzz-3.14.5-cp314-cp314-macosx_11_0_arm64.whl - name: rapidfuzz - version: 3.14.5 - sha256: 0298d357e2bc59d572da4db0bc631009b6f8f6c9bc8c11e99a12b833f16b6575 - requires_dist: - - numpy ; extra == 'all' - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/81/41/aa3ffb3355e62e1bf91f6599b3092e866bc88487a07c524004943c7676df/rapidfuzz-3.14.5-cp314-cp314-macosx_10_15_x86_64.whl - name: rapidfuzz - version: 3.14.5 - sha256: 1a31cc6d7d03e7318a0974c038959c59e19c752b81115f2e9138b3331cd64d45 - requires_dist: - - numpy ; extra == 'all' - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/c8/85/9535df0b78ba51f478c9ce7eb6d1f85535cc31fe356773b48fd9d3e563ca/rapidfuzz-3.14.5-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl - name: rapidfuzz - version: 3.14.5 - sha256: 4900143d82071bdda533b00300c40b14b963ff826b3642cc463b6dd0f036585e - requires_dist: - - numpy ; extra == 'all' - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/b9/20/35d2baebacf357b562bd081936b66cd845775442973cb033a377fd639a84/rdflib-7.5.0-py3-none-any.whl - name: rdflib - version: 7.5.0 - sha256: b011dfc40d0fc8a44252e906dcd8fc806a7859bc231be190c37e9568a31ac572 - requires_dist: - - berkeleydb>=18.1.0,<19.0.0 ; extra == 'berkeleydb' - - html5rdf>=1.2,<2 ; extra == 'html' - - httpx>=0.28.1,<0.29.0 ; extra == 'rdf4j' - - isodate>=0.7.2,<1.0.0 ; python_full_version < '3.11' - - lxml>=4.3,<6.0 ; extra == 'lxml' - - networkx>=2,<4 ; extra == 'networkx' - - orjson>=3.9.14,<4 ; extra == 'orjson' - - pyparsing>=2.1.0,<4 - requires_python: '>=3.8.1' -- conda: https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda - sha256: 12ffde5a6f958e285aa22c191ca01bbd3d6e710aa852e00618fa6ddc59149002 - md5: d7d95fc8287ea7bf33e0e7116d2b95ec + purls: [] + size: 402681 + timestamp: 1767822693908 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcxx-21.1.8-h55c6f16_2.conda + sha256: 5fbeb2fc2673f0455af6079abf93faaf27f11a92574ad51565fa1ecac9a4e2aa + md5: 4cb5878bdb9ebfa65b7cdff5445087c5 depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=14 - - ncurses >=6.5,<7.0a0 - license: GPL-3.0-only - license_family: GPL + - __osx >=11.0 + license: Apache-2.0 WITH LLVM-exception + license_family: Apache purls: [] - size: 345073 - timestamp: 1765813471974 -- conda: https://conda.anaconda.org/conda-forge/osx-64/readline-8.3-h68b038d_0.conda - sha256: 4614af680aa0920e82b953fece85a03007e0719c3399f13d7de64176874b80d5 - md5: eefd65452dfe7cce476a519bece46704 + size: 570068 + timestamp: 1770238262922 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libedit-3.1.20250104-pl5321hafb1f1b_0.conda + sha256: 66aa216a403de0bb0c1340a88d1a06adaff66bae2cfd196731aa24db9859d631 + md5: 44083d2d2c2025afca315c7a172eab2b depends: - - __osx >=10.13 + - ncurses + - __osx >=11.0 - ncurses >=6.5,<7.0a0 - license: GPL-3.0-only - license_family: GPL + license: BSD-2-Clause + license_family: BSD purls: [] - size: 317819 - timestamp: 1765813692798 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/readline-8.3-h46df422_0.conda - sha256: a77010528efb4b548ac2a4484eaf7e1c3907f2aec86123ed9c5212ae44502477 - md5: f8381319127120ce51e081dce4865cf4 + size: 107691 + timestamp: 1738479560845 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libev-4.33-h93a5062_2.conda + sha256: 95cecb3902fbe0399c3a7e67a5bed1db813e5ab0e22f4023a5e0f722f2cc214f + md5: 36d33e440c31857372a72137f78bacf5 + license: BSD-2-Clause + license_family: BSD + purls: [] + size: 107458 + timestamp: 1702146414478 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libexpat-2.7.3-haf25636_0.conda + sha256: fce22610ecc95e6d149e42a42fbc3cc9d9179bd4eb6232639a60f06e080eec98 + md5: b79875dbb5b1db9a4a22a4520f918e1a depends: - __osx >=11.0 - - ncurses >=6.5,<7.0a0 - license: GPL-3.0-only - license_family: GPL + constrains: + - expat 2.7.3.* + license: MIT + license_family: MIT purls: [] - size: 313930 - timestamp: 1765813902568 -- conda: https://conda.anaconda.org/conda-forge/noarch/referencing-0.37.0-pyhcf101f3_0.conda - sha256: 0577eedfb347ff94d0f2fa6c052c502989b028216996b45c7f21236f25864414 - md5: 870293df500ca7e18bedefa5838a22ab + size: 67800 + timestamp: 1763549994166 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libffi-3.5.2-hcf2aa1b_0.conda + sha256: 6686a26466a527585e6a75cc2a242bf4a3d97d6d6c86424a441677917f28bec7 + md5: 43c04d9cb46ef176bb2a4c77e324d599 depends: - - attrs >=22.2.0 - - python >=3.10 - - rpds-py >=0.7.0 - - typing_extensions >=4.4.0 - - python + - __osx >=11.0 license: MIT license_family: MIT - purls: - - pkg:pypi/referencing?source=hash-mapping - size: 51788 - timestamp: 1760379115194 -- pypi: https://files.pythonhosted.org/packages/1e/db/4254e3eabe8020b458f1a747140d32277ec7a271daf1d235b70dc0b4e6e3/requests-2.32.5-py3-none-any.whl - name: requests - version: 2.32.5 - sha256: 2462f94637a34fd532264295e186976db0f5d453d1cdd31473c85a6a161affb6 - requires_dist: - - charset-normalizer>=2,<4 - - idna>=2.5,<4 - - urllib3>=1.21.1,<3 - - certifi>=2017.4.17 - - pysocks>=1.5.6,!=1.5.7 ; extra == 'socks' - - chardet>=3.0.2,<6 ; extra == 'use-chardet-on-py3' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/3f/51/d4db610ef29373b879047326cbf6fa98b6c1969d6f6dc423279de2b1be2c/requests_toolbelt-1.0.0-py2.py3-none-any.whl - name: requests-toolbelt - version: 1.0.0 - sha256: cccfdd665f0a24fcf4726e690f65639d272bb0637b9b92dfd91a5568ccf6bd06 - requires_dist: - - requests>=2.0.1,<3.0.0 - requires_python: '>=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*' -- pypi: https://files.pythonhosted.org/packages/ef/45/615f5babd880b4bd7d405cc0dc348234c5ffb6ed1ea33e152ede08b2072d/rich-14.3.2-py3-none-any.whl - name: rich - version: 14.3.2 - sha256: 08e67c3e90884651da3239ea668222d19bea7b589149d8014a21c633420dbb69 - requires_dist: - - ipywidgets>=7.5.1,<9 ; extra == 'jupyter' - - markdown-it-py>=2.2.0 - - pygments>=2.13.0,<3.0.0 - requires_python: '>=3.8.0' -- pypi: https://files.pythonhosted.org/packages/04/80/97b6f357ac458d9ad9872cc3183ca09ef7439ac89e030ea43053ba1294b6/rich_argparse-1.7.2-py3-none-any.whl - name: rich-argparse - version: 1.7.2 - sha256: 0559b1f47a19bbeb82bf15f95a057f99bcbbc98385532f57937f9fc57acc501a - requires_dist: - - rich>=11.0.0 - requires_python: '>=3.8' -- conda: https://conda.anaconda.org/conda-forge/linux-64/rpds-py-0.30.0-py314h2e6c369_0.conda - sha256: e53b0cbf3b324eaa03ca1fe1a688fdf4ab42cea9c25270b0a7307d8aaaa4f446 - md5: c1c368b5437b0d1a68f372ccf01cb133 + purls: [] + size: 40979 + timestamp: 1769456747661 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libgcc-15.2.0-hcbb3090_17.conda + sha256: 07ba27f2ef1ce444ce5c99d0f9590772fc5b58ba73c993477bfad74b17dfaa79 + md5: 65c07cee234440ae4d5d340fc4b2e69a depends: - - python - - libgcc >=14 - - __glibc >=2.17,<3.0.a0 - - python_abi 3.14.* *_cp314 + - _openmp_mutex constrains: - - __glibc >=2.17 - license: MIT - license_family: MIT - purls: - - pkg:pypi/rpds-py?source=hash-mapping - size: 376121 - timestamp: 1764543122774 -- conda: https://conda.anaconda.org/conda-forge/osx-64/rpds-py-0.30.0-py314ha7b6dee_0.conda - sha256: 368a758ba6f4fb3c6c9a0d25c090807553af5b3dc937a2180ff047fe8ebf6820 - md5: 816cb6c142c86de627fe7ffa1affddb2 + - libgomp 15.2.0 17 + - libgcc-ng ==15.2.0=*_17 + license: GPL-3.0-only WITH GCC-exception-3.1 + purls: [] + size: 402928 + timestamp: 1770254186829 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libgfortran-15.2.0-h07b0088_17.conda + sha256: 7b96f428cb932df8d7c1aa4e433ed29b779dd9571934afdf4f9093a85155a142 + md5: 45ba22eb5381fb602a45233d89ba27ae depends: - - python - - __osx >=10.13 - - python_abi 3.14.* *_cp314 + - libgfortran5 15.2.0 hdae7583_17 constrains: - - __osx >=10.13 - license: MIT - license_family: MIT - purls: - - pkg:pypi/rpds-py?source=hash-mapping - size: 362381 - timestamp: 1764543188314 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/rpds-py-0.30.0-py314haad56a0_0.conda - sha256: e161dd97403b8b8a083d047369a5cf854557dba1204d29e2f0250f5ac4403925 - md5: 76a4f88d1b7748c477abf3c341edc64c + - libgfortran-ng ==15.2.0=*_17 + license: GPL-3.0-only WITH GCC-exception-3.1 + purls: [] + size: 139757 + timestamp: 1770254394473 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libgfortran5-15.2.0-hdae7583_17.conda + sha256: 9c41ff08f61c953cee13fc3df3c6245741e5a71e453b2c094a6d55b0eeda3669 + md5: c6329d871fb3207e9657c384128f5488 + depends: + - libgcc >=15.2.0 + constrains: + - libgfortran 15.2.0 + license: GPL-3.0-only WITH GCC-exception-3.1 + purls: [] + size: 599374 + timestamp: 1770254196706 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libglib-2.86.3-hfe11c1f_0.conda + sha256: 801c1835aa35a4f6e45e2192ad668bd7238d95c90ef8f02c52ce859c20117285 + md5: 057c7247514048ebdaf89373b263ebee depends: - - python - __osx >=11.0 - - python 3.14.* *_cp314 - - python_abi 3.14.* *_cp314 + - libffi >=3.5.2,<3.6.0a0 + - libiconv >=1.18,<2.0a0 + - libintl >=0.25.1,<1.0a0 + - libzlib >=1.3.1,<2.0a0 + - pcre2 >=10.47,<10.48.0a0 constrains: + - glib 2.86.3 *_0 + license: LGPL-2.1-or-later + purls: [] + size: 3670602 + timestamp: 1765223125237 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libiconv-1.18-h23cfdf5_2.conda + sha256: de0336e800b2af9a40bdd694b03870ac4a848161b35c8a2325704f123f185f03 + md5: 4d5a7445f0b25b6a3ddbb56e790f5251 + depends: - __osx >=11.0 - license: MIT - license_family: MIT - purls: - - pkg:pypi/rpds-py?source=hash-mapping - size: 350976 - timestamp: 1764543169524 -- pypi: https://files.pythonhosted.org/packages/af/fe/b6045c782f1fd1ae317d2a6ca1884857ce5c20f59befe6ab25a8603c43a7/ruamel_yaml-0.18.17-py3-none-any.whl - name: ruamel-yaml - version: 0.18.17 - sha256: 9c8ba9eb3e793efdf924b60d521820869d5bf0cb9c6f1b82d82de8295e290b9d - requires_dist: - - ruamel-yaml-clib>=0.2.15 ; python_full_version < '3.15' and platform_python_implementation == 'CPython' - - ruamel-yaml-jinja2>=0.2 ; extra == 'jinja2' - - ryd ; extra == 'docs' - - mercurial>5.7 ; extra == 'docs' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/3e/bd/ab8459c8bb759c14a146990bf07f632c1cbec0910d4853feeee4be2ab8bb/ruamel_yaml_clib-0.2.15-cp314-cp314-macosx_10_15_x86_64.whl - name: ruamel-yaml-clib - version: 0.2.15 - sha256: 753faf20b3a5906faf1fc50e4ddb8c074cb9b251e00b14c18b28492f933ac8ef - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/69/f2/c4cec0a30f1955510fde498aac451d2e52b24afdbcb00204d3a951b772c3/ruamel_yaml_clib-0.2.15-cp314-cp314-macosx_11_0_arm64.whl - name: ruamel-yaml-clib - version: 0.2.15 - sha256: 480894aee0b29752560a9de46c0e5f84a82602f2bc5c6cde8db9a345319acfdf - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/a1/5c/8b56b08db91e569d0a4fbfa3e492ed2026081bdd7e892f63ba1c88a2f548/ruamel_yaml_clib-0.2.15-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - name: ruamel-yaml-clib - version: 0.2.15 - sha256: 2812ff359ec1f30129b62372e5f22a52936fac13d5d21e70373dbca5d64bb97c - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/5c/48/ccd6c49477674389d55b5b5520e47d1290f4c29686c36f5674f4a7aced00/rucio_clients-39.2.0-py3-none-any.whl - name: rucio-clients - version: 39.2.0 - sha256: 97406fa7f927b24b59499bb507a43cc9f24ca8283e45315d59dd5ad4fcfbc5a2 - requires_dist: - - click - - requests - - urllib3 - - dogpile-cache - - packaging - - tabulate - - jsonschema - - rich - - typing-extensions - - paramiko ; extra == 'ssh' - - kerberos ; extra == 'kerberos' - - pykerberos ; extra == 'kerberos' - - requests-kerberos ; extra == 'kerberos' - - python-swiftclient ; extra == 'swift' - - argcomplete ; extra == 'argcomplete' - - paramiko ; extra == 'sftp' - - python-magic ; extra == 'dumper' - requires_python: '>=3.9' -- conda: https://conda.anaconda.org/conda-forge/linux-64/ruff-0.15.0-h40fa522_0.conda - noarch: python - sha256: fc456645570586c798d2da12fe723b38ea0d0901373fd9959cab914cbb19518b - md5: fe90be2abf12b301dde984719a02ca0b + license: LGPL-2.1-only + purls: [] + size: 750379 + timestamp: 1754909073836 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libintl-0.25.1-h493aca8_0.conda + sha256: 99d2cebcd8f84961b86784451b010f5f0a795ed1c08f1e7c76fbb3c22abf021a + md5: 5103f6a6b210a3912faf8d7db516918c depends: - - python - - __glibc >=2.17,<3.0.a0 - - libgcc >=14 - constrains: - - __glibc >=2.17 - license: MIT - license_family: MIT - purls: - - pkg:pypi/ruff?source=compressed-mapping - size: 9103793 - timestamp: 1770153712370 -- conda: https://conda.anaconda.org/conda-forge/osx-64/ruff-0.15.0-h5930b28_0.conda - noarch: python - sha256: de9f76a00b86053d340cb0cc43f119c9d917f870e71b0320e4fd6d7e00c74657 - md5: a48352b21637abd3e40822c4e6eb5c56 + - __osx >=11.0 + - libiconv >=1.18,<2.0a0 + license: LGPL-2.1-or-later + purls: [] + size: 90957 + timestamp: 1751558394144 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/liblapack-3.11.0-5_hd9741b5_openblas.conda + build_number: 5 + sha256: 735a6e6f7d7da6f718b6690b7c0a8ae4815afb89138aa5793abe78128e951dbb + md5: ca9d752201b7fa1225bca036ee300f2b depends: - - python - - __osx >=10.13 + - libblas 3.11.0 5_h51639a9_openblas constrains: - - __osx >=10.13 - license: MIT - license_family: MIT - purls: - - pkg:pypi/ruff?source=compressed-mapping - size: 9136186 - timestamp: 1770153825397 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/ruff-0.15.0-h279115b_0.conda - noarch: python - sha256: d0d55cd450f7e66b98aec49bd76e7476badeed78563988003766d4dd5c4850fa - md5: 67e036614accdbee477daac1ba2441b9 + - libcblas 3.11.0 5*_openblas + - blas 2.305 openblas + - liblapacke 3.11.0 5*_openblas + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 18551 + timestamp: 1765819121855 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libltdl-2.4.3a-h286801f_0.conda + sha256: 69cdd97f0a31b2b1e8a8bd8ebc03c6042d2ba589721d2eead3d7815d801cafdd + md5: db358e8493bd213b5650b9f9e1d0d355 + depends: + - __osx >=11.0 + license: LGPL-2.0-or-later + license_family: LGPL + purls: [] + size: 37328 + timestamp: 1740594040504 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/liblzma-5.8.2-h8088a28_0.conda + sha256: 7bfc7ffb2d6a9629357a70d4eadeadb6f88fa26ebc28f606b1c1e5e5ed99dc7e + md5: 009f0d956d7bfb00de86901d16e486c7 depends: - - python - __osx >=11.0 constrains: + - xz 5.8.2.* + license: 0BSD + purls: [] + size: 92242 + timestamp: 1768752982486 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libmpdec-4.0.0-h84a0fba_1.conda + sha256: 1089c7f15d5b62c622625ec6700732ece83be8b705da8c6607f4dabb0c4bd6d2 + md5: 57c4be259f5e0b99a5983799a228ae55 + depends: - __osx >=11.0 - license: MIT - license_family: MIT - purls: - - pkg:pypi/ruff?source=compressed-mapping - size: 8383076 - timestamp: 1770153856208 -- pypi: https://files.pythonhosted.org/packages/fc/51/727abb13f44c1fcf6d145979e1535a35794db0f6e450a0cb46aa24732fe2/s3transfer-0.16.0-py3-none-any.whl - name: s3transfer - version: 0.16.0 - sha256: 18e25d66fed509e3868dc1572b3f427ff947dd2c56f844a5bf09481ad3f3b2fe - requires_dist: - - botocore>=1.37.4,<2.0a0 - - botocore[crt]>=1.37.4,<2.0a0 ; extra == 'crt' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/62/86/3915cb5a603e1b1d798e1ee1ce2a0a390a0f85d35da97e4b6d1c6a45421b/schema_salad-8.9.20251102115403-cp314-cp314-macosx_10_15_x86_64.whl - name: schema-salad - version: 8.9.20251102115403 - sha256: 8d12fe61d68cbce0de95e5206dcd24d18bdb77a41830ab4c7b5794326ed23d90 - requires_dist: - - requests>=1.0 - - ruamel-yaml>=0.17.6,<0.19 - - rdflib>=4.2.2,<8.0.0 - - mistune>=3,<3.2 - - cachecontrol[filecache]>=0.13.1,<0.15 - - mypy-extensions - - sphinx>=2.2 ; extra == 'docs' - - sphinx-rtd-theme>=1 ; extra == 'docs' - - pytest<9 ; extra == 'docs' - - sphinx-autoapi ; extra == 'docs' - - sphinx-autodoc-typehints ; extra == 'docs' - - sphinxcontrib-autoprogram ; extra == 'docs' - - black ; extra == 'pycodegen' - requires_python: '>=3.9,<3.15' -- pypi: https://files.pythonhosted.org/packages/71/3f/212e32937253312e102e152c954a5495df0379255719ce28e0288194748d/schema_salad-8.9.20251102115403-cp314-cp314-macosx_11_0_arm64.whl - name: schema-salad - version: 8.9.20251102115403 - sha256: 38c5faa34f7f70641ea4984f65aab062cc78c8f4528e3f2c092fa81503fc937d - requires_dist: - - requests>=1.0 - - ruamel-yaml>=0.17.6,<0.19 - - rdflib>=4.2.2,<8.0.0 - - mistune>=3,<3.2 - - cachecontrol[filecache]>=0.13.1,<0.15 - - mypy-extensions - - sphinx>=2.2 ; extra == 'docs' - - sphinx-rtd-theme>=1 ; extra == 'docs' - - pytest<9 ; extra == 'docs' - - sphinx-autoapi ; extra == 'docs' - - sphinx-autodoc-typehints ; extra == 'docs' - - sphinxcontrib-autoprogram ; extra == 'docs' - - black ; extra == 'pycodegen' - requires_python: '>=3.9,<3.15' -- pypi: https://files.pythonhosted.org/packages/89/d4/24a137517140fc8cc07f7423695b9296c993d6b6cbf2a7867d8f859de77f/schema_salad-8.9.20251102115403-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - name: schema-salad - version: 8.9.20251102115403 - sha256: d7f9dcdafe3ca64f28a1ee219434bc1297801c9435b7431817e435e782f1c1db - requires_dist: - - requests>=1.0 - - ruamel-yaml>=0.17.6,<0.19 - - rdflib>=4.2.2,<8.0.0 - - mistune>=3,<3.2 - - cachecontrol[filecache]>=0.13.1,<0.15 - - mypy-extensions - - sphinx>=2.2 ; extra == 'docs' - - sphinx-rtd-theme>=1 ; extra == 'docs' - - pytest<9 ; extra == 'docs' - - sphinx-autoapi ; extra == 'docs' - - sphinx-autodoc-typehints ; extra == 'docs' - - sphinxcontrib-autoprogram ; extra == 'docs' - - black ; extra == 'pycodegen' - requires_python: '>=3.9,<3.15' -- conda: https://conda.anaconda.org/conda-forge/linux-64/scitokens-cpp-1.3.0-h096d96b_0.conda - sha256: 11ad442837d2bd3c856c8a7ed08754ca430e6779999d898d1fa313fcd670458c - md5: 946024dbdba971eeda33da76ae586694 - depends: - - __glibc >=2.17,<3.0.a0 - - libcurl >=8.18.0,<9.0a0 - - libgcc >=14 - - libsqlite >=3.51.2,<4.0a0 - - libstdcxx >=14 - - libuuid >=2.41.3,<3.0a0 - - openssl >=3.5.5,<4.0a0 - license: Apache-2.0 - license_family: APACHE + license: BSD-2-Clause + license_family: BSD purls: [] - size: 2227714 - timestamp: 1769697062631 -- conda: https://conda.anaconda.org/conda-forge/osx-64/scitokens-cpp-1.3.0-hcb75e18_0.conda - sha256: d44f4ba1470d3e13c8f36c0086d5cbca97f3dbc05a0ed384be31ec56e79de3f0 - md5: 086d476a1c59a3984ef460bfb292425d + size: 73690 + timestamp: 1769482560514 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libnghttp2-1.67.0-hc438710_0.conda + sha256: a07cb53b5ffa2d5a18afc6fd5a526a5a53dd9523fbc022148bd2f9395697c46d + md5: a4b4dd73c67df470d091312ab87bf6ae depends: - - __osx >=10.13 - - libcurl >=8.18.0,<9.0a0 + - __osx >=11.0 + - c-ares >=1.34.5,<2.0a0 - libcxx >=19 - - libsqlite >=3.51.2,<4.0a0 - - openssl >=3.5.5,<4.0a0 - license: Apache-2.0 - license_family: APACHE + - libev >=4.33,<4.34.0a0 + - libev >=4.33,<5.0a0 + - libzlib >=1.3.1,<2.0a0 + - openssl >=3.5.2,<4.0a0 + license: MIT + license_family: MIT purls: [] - size: 184130 - timestamp: 1769697263474 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/scitokens-cpp-1.3.0-h608d757_0.conda - sha256: 647dd5a8ead4e8268c546cb91a34289a4aaede39b9d47ab50fe9facdd91880dd - md5: c63e2462ec4f3ef4a2af2dcbf63a3842 + size: 575454 + timestamp: 1756835746393 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libntlm-1.8-h5505292_0.conda + sha256: ea8c680924d957e12270dca549620327d5e986f23c4bd5f45627167ca6ef7a3b + md5: c90c1d3bd778f5ec0d4bb4ef36cbd5b6 depends: - __osx >=11.0 - - libcurl >=8.18.0,<9.0a0 - - libcxx >=19 - - libsqlite >=3.51.2,<4.0a0 - - openssl >=3.5.5,<4.0a0 - license: Apache-2.0 - license_family: APACHE + license: LGPL-2.1-or-later purls: [] - size: 178975 - timestamp: 1769697339391 -- conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-80.10.2-pyh332efcf_0.conda - sha256: f5fcb7854d2b7639a5b1aca41dd0f2d5a69a60bbc313e7f192e2dc385ca52f86 - md5: 7b446fcbb6779ee479debb4fd7453e6c + size: 31099 + timestamp: 1734670168822 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libopenblas-0.3.30-openmp_ha158390_4.conda + sha256: ebbbc089b70bcde87c4121a083c724330f02a690fb9d7c6cd18c30f1b12504fa + md5: a6f6d3a31bb29e48d37ce65de54e2df0 depends: - - python >=3.10 + - __osx >=11.0 + - libgfortran + - libgfortran5 >=14.3.0 + - llvm-openmp >=19.1.7 + constrains: + - openblas >=0.3.30,<0.3.31.0a0 + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 4284132 + timestamp: 1768547079205 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsqlite-3.51.2-h1ae2325_0.conda + sha256: 6e9b9f269732cbc4698c7984aa5b9682c168e2a8d1e0406e1ff10091ca046167 + md5: 4b0bf313c53c3e89692f020fb55d5f2c + depends: + - __osx >=11.0 + - icu >=78.2,<79.0a0 + - libzlib >=1.3.1,<2.0a0 + license: blessing + purls: [] + size: 909777 + timestamp: 1768148320535 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libssh2-1.11.1-h1590b86_0.conda + sha256: 8bfe837221390ffc6f111ecca24fa12d4a6325da0c8d131333d63d6c37f27e0a + md5: b68e8f66b94b44aaa8de4583d3d4cc40 + depends: + - libzlib >=1.3.1,<2.0a0 + - openssl >=3.5.0,<4.0a0 + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 279193 + timestamp: 1745608793272 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libtool-2.5.4-h286801f_0.conda + sha256: e23da9c94975f3b0251b4e81ff70e0631702e103278038157cc4dfe4c2f3d851 + md5: bdd3ba2e9c5d24fa4341521df822f0c7 + depends: + - __osx >=11.0 + - libltdl 2.4.3a h286801f_0 + license: GPL-2.0-or-later + license_family: GPL + purls: [] + size: 414678 + timestamp: 1740594107488 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libuuid-2.41.3-h0053d0f_0.conda + sha256: 28b4a4ef050413e7793dfb935e675a9f57423e20ea98f4c0b165d1386b05f93b + md5: 5e4c76ba638d70a2e1ba9ed34dc4dced + depends: + - __osx >=11.0 + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 36727 + timestamp: 1766271567403 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libxcrypt-4.4.36-h93a5062_1.conda + sha256: 4c7884834f261a4b7d7d8bc9cfb9940f0a4bc5582a21624f386973bb254c7560 + md5: 7d2e687b217d4de0fa7064b4de3e0be8 + license: LGPL-2.1-or-later + purls: [] + size: 99413 + timestamp: 1702724499136 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libxml2-16-2.15.1-h5ef1a60_1.conda + sha256: 2d5ab15113b0ba21f4656d387d26ab59e4fbaf3027f5e58a2a4fe370821eb106 + md5: 7eed1026708e26ee512f43a04d9d0027 + depends: + - __osx >=11.0 + - icu >=78.1,<79.0a0 + - libiconv >=1.18,<2.0a0 + - liblzma >=5.8.1,<6.0a0 + - libzlib >=1.3.1,<2.0a0 + constrains: + - libxml2 2.15.1 license: MIT license_family: MIT - purls: - - pkg:pypi/setuptools?source=compressed-mapping - size: 678888 - timestamp: 1769601206751 -- pypi: https://files.pythonhosted.org/packages/70/98/d82f14ac7ffedbd38dfa2383f142b26d18d23ca6cf35a40f4af60df666bd/sh-2.2.2-py3-none-any.whl - name: sh - version: 2.2.2 - sha256: e0b15b4ae8ffcd399bc8ffddcbd770a43c7a70a24b16773fbb34c001ad5d52af - requires_python: '>=3.8.1,<4.0' -- pypi: https://files.pythonhosted.org/packages/e0/f9/0595336914c5619e5f28a1fb793285925a8cd4b432c9da0a987836c7f822/shellingham-1.5.4-py2.py3-none-any.whl - name: shellingham - version: 1.5.4 - sha256: 7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686 - requires_python: '>=3.7' -- pypi: https://files.pythonhosted.org/packages/59/25/68f81c50aeb3f30e01c20da0f56d14c1a779b57d9308c50e19c63dc8413f/signurlarity-0.2.2-py3-none-any.whl - name: signurlarity - version: 0.2.2 - sha256: 0c8089ecac04ce105e525b60749d134b171410beefc962e167e0e64141d6e7a7 - requires_dist: - - cryptography>=41.0.0 - - httpx>=0.24.0 - - orjson - - aiobotocore>=2.15 ; extra == 'testing' - - botocore>=1.35 ; extra == 'testing' - - httpx ; extra == 'testing' - - moto[server] ; extra == 'testing' - - pytest ; extra == 'testing' - - pytest-asyncio ; extra == 'testing' - - pytest-benchmark ; extra == 'testing' - - pytest-xdist ; extra == 'testing' - - rich ; extra == 'testing' - - ty ; extra == 'testing' - requires_python: '>=3.11' -- pypi: https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl - name: six - version: 1.17.0 - sha256: 4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274 - requires_python: '>=2.7,!=3.0.*,!=3.1.*,!=3.2.*' -- pypi: https://files.pythonhosted.org/packages/04/be/d09147ad1ec7934636ad912901c5fd7667e1c858e19d355237db0d0cd5e4/smmap-5.0.2-py3-none-any.whl - name: smmap - version: 5.0.2 - sha256: b30115f0def7d7531d22a0fb6502488d879e75b260a9db4d0819cfb25403af5e - requires_python: '>=3.7' -- pypi: https://files.pythonhosted.org/packages/46/2c/1462b1d0a634697ae9e55b3cecdcb64788e8b7d63f54d923fcd0bb140aed/soupsieve-2.8.3-py3-none-any.whl - name: soupsieve - version: 2.8.3 - sha256: ed64f2ba4eebeab06cc4962affce381647455978ffc1e36bb79a545b91f45a95 - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/f9/38/8b6fc7a8153cb49eb3a9a13acfa9eeb6cc476e37888781e593e6f02ac05e/spython-0.3.14-py3-none-any.whl - name: spython - version: 0.3.14 - sha256: 72968583e498bc2a51f9acd0ed6bc0d7d1f7ccd491feaba5e2f7d944bc51da3a -- pypi: https://files.pythonhosted.org/packages/05/45/1256fb597bb83b58a01ddb600c59fe6fdf0e5afe333f0456ed75c0f8d7bd/sqlalchemy-2.0.46-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - name: sqlalchemy - version: 2.0.46 - sha256: 9bcdce05f056622a632f1d44bb47dbdb677f58cad393612280406ce37530eb6d - requires_dist: - - importlib-metadata ; python_full_version < '3.8' - - greenlet>=1 ; platform_machine == 'AMD64' or platform_machine == 'WIN32' or platform_machine == 'aarch64' or platform_machine == 'amd64' or platform_machine == 'ppc64le' or platform_machine == 'win32' or platform_machine == 'x86_64' - - typing-extensions>=4.6.0 - - greenlet>=1 ; extra == 'asyncio' - - mypy>=0.910 ; extra == 'mypy' - - pyodbc ; extra == 'mssql' - - pymssql ; extra == 'mssql-pymssql' - - pyodbc ; extra == 'mssql-pyodbc' - - mysqlclient>=1.4.0 ; extra == 'mysql' - - mysql-connector-python ; extra == 'mysql-connector' - - mariadb>=1.0.1,!=1.1.2,!=1.1.5,!=1.1.10 ; extra == 'mariadb-connector' - - cx-oracle>=8 ; extra == 'oracle' - - oracledb>=1.0.1 ; extra == 'oracle-oracledb' - - psycopg2>=2.7 ; extra == 'postgresql' - - pg8000>=1.29.1 ; extra == 'postgresql-pg8000' - - greenlet>=1 ; extra == 'postgresql-asyncpg' - - asyncpg ; extra == 'postgresql-asyncpg' - - psycopg2-binary ; extra == 'postgresql-psycopg2binary' - - psycopg2cffi ; extra == 'postgresql-psycopg2cffi' - - psycopg>=3.0.7 ; extra == 'postgresql-psycopg' - - psycopg[binary]>=3.0.7 ; extra == 'postgresql-psycopgbinary' - - pymysql ; extra == 'pymysql' - - greenlet>=1 ; extra == 'aiomysql' - - aiomysql>=0.2.0 ; extra == 'aiomysql' - - greenlet>=1 ; extra == 'aioodbc' - - aioodbc ; extra == 'aioodbc' - - greenlet>=1 ; extra == 'asyncmy' - - asyncmy>=0.2.3,!=0.2.4,!=0.2.6 ; extra == 'asyncmy' - - greenlet>=1 ; extra == 'aiosqlite' - - aiosqlite ; extra == 'aiosqlite' - - typing-extensions!=3.10.0.1 ; extra == 'aiosqlite' - - sqlcipher3-binary ; extra == 'sqlcipher' - requires_python: '>=3.7' -- pypi: https://files.pythonhosted.org/packages/e9/f8/5ecdfc73383ec496de038ed1614de9e740a82db9ad67e6e4514ebc0708a3/sqlalchemy-2.0.46-cp314-cp314-macosx_11_0_arm64.whl - name: sqlalchemy - version: 2.0.46 - sha256: 56bdd261bfd0895452006d5316cbf35739c53b9bb71a170a331fa0ea560b2ada - requires_dist: - - importlib-metadata ; python_full_version < '3.8' - - greenlet>=1 ; platform_machine == 'AMD64' or platform_machine == 'WIN32' or platform_machine == 'aarch64' or platform_machine == 'amd64' or platform_machine == 'ppc64le' or platform_machine == 'win32' or platform_machine == 'x86_64' - - typing-extensions>=4.6.0 - - greenlet>=1 ; extra == 'asyncio' - - mypy>=0.910 ; extra == 'mypy' - - pyodbc ; extra == 'mssql' - - pymssql ; extra == 'mssql-pymssql' - - pyodbc ; extra == 'mssql-pyodbc' - - mysqlclient>=1.4.0 ; extra == 'mysql' - - mysql-connector-python ; extra == 'mysql-connector' - - mariadb>=1.0.1,!=1.1.2,!=1.1.5,!=1.1.10 ; extra == 'mariadb-connector' - - cx-oracle>=8 ; extra == 'oracle' - - oracledb>=1.0.1 ; extra == 'oracle-oracledb' - - psycopg2>=2.7 ; extra == 'postgresql' - - pg8000>=1.29.1 ; extra == 'postgresql-pg8000' - - greenlet>=1 ; extra == 'postgresql-asyncpg' - - asyncpg ; extra == 'postgresql-asyncpg' - - psycopg2-binary ; extra == 'postgresql-psycopg2binary' - - psycopg2cffi ; extra == 'postgresql-psycopg2cffi' - - psycopg>=3.0.7 ; extra == 'postgresql-psycopg' - - psycopg[binary]>=3.0.7 ; extra == 'postgresql-psycopgbinary' - - pymysql ; extra == 'pymysql' - - greenlet>=1 ; extra == 'aiomysql' - - aiomysql>=0.2.0 ; extra == 'aiomysql' - - greenlet>=1 ; extra == 'aioodbc' - - aioodbc ; extra == 'aioodbc' - - greenlet>=1 ; extra == 'asyncmy' - - asyncmy>=0.2.3,!=0.2.4,!=0.2.6 ; extra == 'asyncmy' - - greenlet>=1 ; extra == 'aiosqlite' - - aiosqlite ; extra == 'aiosqlite' - - typing-extensions!=3.10.0.1 ; extra == 'aiosqlite' - - sqlcipher3-binary ; extra == 'sqlcipher' - requires_python: '>=3.7' -- pypi: https://files.pythonhosted.org/packages/fc/a1/9c4efa03300926601c19c18582531b45aededfb961ab3c3585f1e24f120b/sqlalchemy-2.0.46-py3-none-any.whl - name: sqlalchemy - version: 2.0.46 - sha256: f9c11766e7e7c0a2767dda5acb006a118640c9fc0a4104214b96269bfb78399e - requires_dist: - - importlib-metadata ; python_full_version < '3.8' - - greenlet>=1 ; platform_machine == 'AMD64' or platform_machine == 'WIN32' or platform_machine == 'aarch64' or platform_machine == 'amd64' or platform_machine == 'ppc64le' or platform_machine == 'win32' or platform_machine == 'x86_64' - - typing-extensions>=4.6.0 - - greenlet>=1 ; extra == 'asyncio' - - mypy>=0.910 ; extra == 'mypy' - - pyodbc ; extra == 'mssql' - - pymssql ; extra == 'mssql-pymssql' - - pyodbc ; extra == 'mssql-pyodbc' - - mysqlclient>=1.4.0 ; extra == 'mysql' - - mysql-connector-python ; extra == 'mysql-connector' - - mariadb>=1.0.1,!=1.1.2,!=1.1.5,!=1.1.10 ; extra == 'mariadb-connector' - - cx-oracle>=8 ; extra == 'oracle' - - oracledb>=1.0.1 ; extra == 'oracle-oracledb' - - psycopg2>=2.7 ; extra == 'postgresql' - - pg8000>=1.29.1 ; extra == 'postgresql-pg8000' - - greenlet>=1 ; extra == 'postgresql-asyncpg' - - asyncpg ; extra == 'postgresql-asyncpg' - - psycopg2-binary ; extra == 'postgresql-psycopg2binary' - - psycopg2cffi ; extra == 'postgresql-psycopg2cffi' - - psycopg>=3.0.7 ; extra == 'postgresql-psycopg' - - psycopg[binary]>=3.0.7 ; extra == 'postgresql-psycopgbinary' - - pymysql ; extra == 'pymysql' - - greenlet>=1 ; extra == 'aiomysql' - - aiomysql>=0.2.0 ; extra == 'aiomysql' - - greenlet>=1 ; extra == 'aioodbc' - - aioodbc ; extra == 'aioodbc' - - greenlet>=1 ; extra == 'asyncmy' - - asyncmy>=0.2.3,!=0.2.4,!=0.2.6 ; extra == 'asyncmy' - - greenlet>=1 ; extra == 'aiosqlite' - - aiosqlite ; extra == 'aiosqlite' - - typing-extensions!=3.10.0.1 ; extra == 'aiosqlite' - - sqlcipher3-binary ; extra == 'sqlcipher' - requires_python: '>=3.7' -- conda: https://conda.anaconda.org/conda-forge/linux-64/srm-ifce-1.24.6-h3b26d37_2.conda - sha256: 994e04767e2fa540c43ffb96397835154a7fcc5b7bd9281d0923615f2f208352 - md5: a84d7ea541bfada40c748035211a9ce9 - depends: - - cgsi-gsoap >=1.3.11,<1.4.0a0 - - gct >=6.2.1705709074,<6.2.1705709075.0a0 - - gsoap >=2.8.123,<2.8.124.0a0 - - libgcc-ng >=12 - - libglib >=2.78.4,<3.0a0 - - libstdcxx-ng >=12 - - openssl >=3.2.1,<4.0a0 - license: Apache-2.0 - license_family: Apache - purls: [] - size: 215070 - timestamp: 1709962013437 -- conda: https://conda.anaconda.org/conda-forge/osx-64/srm-ifce-1.24.6-h73c9bdb_2.conda - sha256: 2004682e917722b471d9b9817ee3f14aa47b3832d4087f4f7f8b9965ecdae22a - md5: aea203ab9df6dc991bc26552617ccc66 - depends: - - gct >=6.2.1705709074,<6.2.1705709075.0a0 - - gsoap >=2.8.123,<2.8.124.0a0 - - libcxx >=16 - - libglib >=2.78.4,<3.0a0 - - openssl >=3.2.1,<4.0a0 - license: Apache-2.0 - license_family: Apache purls: [] - size: 175433 - timestamp: 1709962268470 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/srm-ifce-1.24.6-he0fb9dd_2.conda - sha256: 8a0bcdaa875490a30a7928c720c622bef66b903e0036b0e89ff1df46d30449bf - md5: 08116d760c59cc3b713406ded76db1ac + size: 464886 + timestamp: 1766327479416 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libxml2-2.15.1-h8d039ee_1.conda + sha256: 59f96fa27cce6a9a27414c5bb301eedda1a1b85cd0d8f5d68f77e46b86e7c95f + md5: fd804ee851e20faca4fecc7df0901d07 depends: - - gct >=6.2.1705709074,<6.2.1705709075.0a0 - - gsoap >=2.8.123,<2.8.124.0a0 - - libcxx >=16 - - libglib >=2.78.4,<3.0a0 - - openssl >=3.2.1,<4.0a0 - license: Apache-2.0 - license_family: Apache + - __osx >=11.0 + - icu >=78.1,<79.0a0 + - libiconv >=1.18,<2.0a0 + - liblzma >=5.8.1,<6.0a0 + - libxml2-16 2.15.1 h5ef1a60_1 + - libzlib >=1.3.1,<2.0a0 + license: MIT + license_family: MIT purls: [] - size: 181605 - timestamp: 1709962334959 -- pypi: https://files.pythonhosted.org/packages/f4/40/8561ce06dc46fd17242c7724ab25b257a2ac1b35f4ebf551b40ce6105cfa/stevedore-5.6.0-py3-none-any.whl - name: stevedore - version: 5.6.0 - sha256: 4a36dccefd7aeea0c70135526cecb7766c4c84c473b1af68db23d541b6dc1820 - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/40/44/4a5f08c96eb108af5cb50b41f76142f0afa346dfa99d5296fe7202a11854/tabulate-0.9.0-py3-none-any.whl - name: tabulate - version: 0.9.0 - sha256: 024ca478df22e9340661486f85298cff5f6dcdba14f3813e8830015b9ed1948f - requires_dist: - - wcwidth ; extra == 'widechars' - requires_python: '>=3.7' -- conda: https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda - sha256: cafeec44494f842ffeca27e9c8b0c27ed714f93ac77ddadc6aaf726b5554ebac - md5: cffd3bdd58090148f4cfcd831f4b26ab + size: 40607 + timestamp: 1766327501392 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libxml2-devel-2.15.1-h8d039ee_1.conda + sha256: a51ac5f66270b5f21b6669d705531208ab599a8744c7e60c1638229e22c8267d + md5: 8975a4d0277920627000f0126c3c2b48 depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=14 + - __osx >=11.0 + - icu >=78.1,<79.0a0 + - libiconv >=1.18,<2.0a0 + - liblzma >=5.8.1,<6.0a0 + - libxml2 2.15.1 h8d039ee_1 + - libxml2-16 2.15.1 h5ef1a60_1 - libzlib >=1.3.1,<2.0a0 - constrains: - - xorg-libx11 >=1.8.12,<2.0a0 - license: TCL - license_family: BSD + license: MIT + license_family: MIT purls: [] - size: 3301196 - timestamp: 1769460227866 -- conda: https://conda.anaconda.org/conda-forge/osx-64/tk-8.6.13-h7142dee_3.conda - sha256: 7f0d9c320288532873e2d8486c331ec6d87919c9028208d3f6ac91dc8f99a67b - md5: 6e6efb7463f8cef69dbcb4c2205bf60e + size: 79725 + timestamp: 1766327519923 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libzlib-1.3.1-h8359307_2.conda + sha256: ce34669eadaba351cd54910743e6a2261b67009624dbc7daeeafdef93616711b + md5: 369964e85dc26bfe78f41399b366c435 depends: - - __osx >=10.13 - - libzlib >=1.3.1,<2.0a0 - license: TCL - license_family: BSD + - __osx >=11.0 + constrains: + - zlib 1.3.1 *_2 + license: Zlib + license_family: Other purls: [] - size: 3282953 - timestamp: 1769460532442 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/tk-8.6.13-h010d191_3.conda - sha256: 799cab4b6cde62f91f750149995d149bc9db525ec12595e8a1d91b9317f038b3 - md5: a9d86bc62f39b94c4661716624eb21b0 + size: 46438 + timestamp: 1727963202283 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/llvm-openmp-21.1.8-h4a912ad_0.conda + sha256: 56bcd20a0a44ddd143b6ce605700fdf876bcf5c509adc50bf27e76673407a070 + md5: 206ad2df1b5550526e386087bef543c7 depends: - __osx >=11.0 - - libzlib >=1.3.1,<2.0a0 - license: TCL - license_family: BSD + constrains: + - openmp 21.1.8|21.1.8.* + - intel-openmp <0.0a0 + license: Apache-2.0 WITH LLVM-exception + license_family: APACHE purls: [] - size: 3127137 - timestamp: 1769460817696 -- conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.0-pyhcf101f3_0.conda - sha256: 62940c563de45790ba0f076b9f2085a842a65662268b02dd136a8e9b1eaf47a8 - md5: 72e780e9aa2d0a3295f59b1874e3768b + size: 285974 + timestamp: 1765964756583 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/m2crypto-0.45.1-py314hdb6fb3f_2.conda + sha256: d5eaf9498468368f651c6bc72bec90c1441b2dd91f17112c1d0a32082abab8fb + md5: 8cae6040ec4477c78304682f18f950f5 depends: - - python >=3.10 + - openssl - python - license: MIT + - __osx >=11.0 + - python 3.14.* *_cp314 + - openssl >=3.5.2,<4.0a0 + - python_abi 3.14.* *_cp314 + license: MIT license_family: MIT purls: - - pkg:pypi/tomli?source=compressed-mapping - size: 21453 - timestamp: 1768146676791 -- pypi: https://files.pythonhosted.org/packages/a0/1d/d9257dd49ff2ca23ea5f132edf1281a0c4f9de8a762b9ae399b670a59235/typer-0.21.1-py3-none-any.whl - name: typer - version: 0.21.1 - sha256: 7985e89081c636b88d172c2ee0cfe33c253160994d47bdfdc302defd7d1f1d01 - requires_dist: - - click>=8.0.0 - - typing-extensions>=3.7.4.3 - - shellingham>=1.3.0 - - rich>=10.11.0 - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/dc/9b/47798a6c91d8bdb567fe2698fe81e0c6b7cb7ef4d13da4114b41d239f65d/typing_inspection-0.4.2-py3-none-any.whl - name: typing-inspection - version: 0.4.2 - sha256: 4ed1cacbdc298c220f1bd249ed5287caa16f34d44ef4e9c3d0cbad5b521545e7 - requires_dist: - - typing-extensions>=4.12.0 - requires_python: '>=3.9' -- conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda - sha256: 032271135bca55aeb156cee361c81350c6f3fb203f57d024d7e5a1fc9ef18731 - md5: 0caa1af407ecff61170c9437a808404d + - pkg:pypi/m2crypto?source=hash-mapping + size: 395003 + timestamp: 1757689131892 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/mypy-1.19.1-py314hbdd0d06_0.conda + sha256: c5c9a691dc00ce9a726426f971fbe21d0501ec8c6228513b945210898f26c761 + md5: 584f58048dc4af70f6c647b40a7049a6 + depends: + - __osx >=11.0 + - mypy_extensions >=1.0.0 + - pathspec >=0.9.0 + - psutil >=4.0 + - python >=3.14,<3.15.0a0 + - python >=3.14,<3.15.0a0 *_cp314 + - python-librt >=0.6.2 + - python_abi 3.14.* *_cp314 + - typing_extensions >=4.6.0 + license: MIT + license_family: MIT + purls: + - pkg:pypi/mypy?source=hash-mapping + size: 11320681 + timestamp: 1765795843941 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/ncurses-6.5-h5e97a16_3.conda + sha256: 2827ada40e8d9ca69a153a45f7fd14f32b2ead7045d3bbb5d10964898fe65733 + md5: 068d497125e4bf8a66bf707254fff5ae + depends: + - __osx >=11.0 + license: X11 AND BSD-3-Clause + purls: [] + size: 797030 + timestamp: 1738196177597 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/numpy-2.4.2-py314hae46ccb_1.conda + sha256: 43b5ed0ead36e5133ee8462916d23284f0bce0e5f266fa4bd31a020a6cc22f14 + md5: 0f0ddf0575b98d91cda9e3ca9eaeb9a2 depends: - - python >=3.10 - python - license: PSF-2.0 - license_family: PSF + - __osx >=11.0 + - python 3.14.* *_cp314 + - libcxx >=19 + - libblas >=3.9.0,<4.0a0 + - liblapack >=3.9.0,<4.0a0 + - python_abi 3.14.* *_cp314 + - libcblas >=3.9.0,<4.0a0 + constrains: + - numpy-base <0a0 + license: BSD-3-Clause + license_family: BSD purls: - - pkg:pypi/typing-extensions?source=hash-mapping - size: 51692 - timestamp: 1756220668932 -- pypi: https://files.pythonhosted.org/packages/c7/b0/003792df09decd6849a5e39c28b513c06e84436a54440380862b5aeff25d/tzdata-2025.3-py2.py3-none-any.whl - name: tzdata - version: '2025.3' - sha256: 06a47e5700f3081aab02b2e513160914ff0694bce9947d6b76ebd6bf57cfc5d1 - requires_python: '>=2' -- conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda - sha256: 1d30098909076af33a35017eed6f2953af1c769e273a0626a04722ac4acaba3c - md5: ad659d0a2b3e47e38d829aa8cad2d610 - license: LicenseRef-Public-Domain + - pkg:pypi/numpy?source=hash-mapping + size: 6992958 + timestamp: 1770098398327 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/openldap-2.6.10-hbe55e7a_0.conda + sha256: 08d859836b81296c16f74336c3a9a455b23d57ce1d7c2b0b3e1b7a07f984c677 + md5: 6fd5d73c63b5d37d9196efb4f044af76 + depends: + - __osx >=11.0 + - cyrus-sasl >=2.1.27,<3.0a0 + - krb5 >=1.21.3,<1.22.0a0 + - libcxx >=18 + - openssl >=3.5.0,<4.0a0 + license: OLDAP-2.8 + license_family: BSD purls: [] - size: 119135 - timestamp: 1767016325805 -- conda: https://conda.anaconda.org/conda-forge/linux-64/ukkonen-1.1.0-py314h9891dd4_0.conda - sha256: c84034056dc938c853e4f61e72e5bd37e2ec91927a661fb9762f678cbea52d43 - md5: 5d3c008e54c7f49592fca9c32896a76f + size: 843597 + timestamp: 1748010484231 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.6.1-hd24854e_1.conda + sha256: 361f5c5e60052abc12bdd1b50d7a1a43e6a6653aab99a2263bf2288d709dcf67 + md5: f4f6ad63f98f64191c3e77c5f5f29d76 depends: - - __glibc >=2.17,<3.0.a0 - - cffi - - libgcc >=14 - - libstdcxx >=14 - - python >=3.14,<3.15.0a0 + - __osx >=11.0 + - ca-certificates + license: Apache-2.0 + license_family: Apache + purls: [] + size: 3104268 + timestamp: 1769556384749 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/pcre2-10.47-h30297fc_0.conda + sha256: 5e2e443f796f2fd92adf7978286a525fb768c34e12b1ee9ded4000a41b2894ba + md5: 9b4190c4055435ca3502070186eba53a + depends: + - __osx >=11.0 + - bzip2 >=1.0.8,<2.0a0 + - libzlib >=1.3.1,<2.0a0 + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 850231 + timestamp: 1763655726735 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/perl-5.32.1-7_h4614cfb_perl5.conda + build_number: 7 + sha256: b0c55040d2994fd6bf2f83786561d92f72306d982d6ea12889acad24a9bf43b8 + md5: ba3cbe93f99e896765422cc5f7c3a79e + license: GPL-1.0-or-later OR Artistic-1.0-Perl + purls: [] + size: 14439531 + timestamp: 1703311335652 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/psutil-7.2.2-py314ha14b1ff_0.conda + sha256: e0f31c053eb11803d63860c213b2b1b57db36734f5f84a3833606f7c91fedff9 + md5: fc4c7ab223873eee32080d51600ce7e7 + depends: + - python + - __osx >=11.0 + - python 3.14.* *_cp314 - python_abi 3.14.* *_cp314 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/psutil?source=hash-mapping + size: 245502 + timestamp: 1769678303655 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/pugixml-1.15-hd3d436d_0.conda + sha256: 5ad8d036040b095f85d23c70624d3e5e1e4c00bc5cea97831542f2dcae294ec9 + md5: b9a4004e46de7aeb005304a13b35cb94 + depends: + - __osx >=11.0 + - libcxx >=18 license: MIT license_family: MIT - purls: - - pkg:pypi/ukkonen?source=hash-mapping - size: 15004 - timestamp: 1769438727085 -- conda: https://conda.anaconda.org/conda-forge/osx-64/ukkonen-1.1.0-py314h473ef84_0.conda - sha256: a77214fabb930c5332dece5407973c0c1c711298bf687976a0b6a9207b758e12 - md5: 08a26dd1ba8fc9681d6b5256b2895f8e + purls: [] + size: 91283 + timestamp: 1736601509593 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/python-3.14.3-h4c637c5_100_cp314.conda + build_number: 100 + sha256: 05f63767b548e9dd1d4d3b5978721703b376ce451c7dfaba8ba3ca020e11bc76 + md5: 97852749b58606ffe363c2cc491cfce1 depends: - - __osx >=10.13 - - cffi + - __osx >=11.0 + - bzip2 >=1.0.8,<2.0a0 + - libexpat >=2.7.3,<3.0a0 + - libffi >=3.5.2,<3.6.0a0 + - liblzma >=5.8.2,<6.0a0 + - libmpdec >=4.0.0,<5.0a0 + - libsqlite >=3.51.2,<4.0a0 + - libzlib >=1.3.1,<2.0a0 + - ncurses >=6.5,<7.0a0 + - openssl >=3.5.5,<4.0a0 + - python_abi 3.14.* *_cp314 + - readline >=8.3,<9.0a0 + - tk >=8.6.13,<8.7.0a0 + - tzdata + - zstd >=1.5.7,<1.6.0a0 + license: Python-2.0 + purls: [] + size: 13553519 + timestamp: 1770271668429 + python_site_packages_path: lib/python3.14/site-packages +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/python-gfal2-1.13.1-py314h5c1db39_2.conda + sha256: a94056439b953daed560227e6128a3fcf55fdb8f18f9b36793a29c1b64c16391 + md5: 7e203553047ba0626fdbb8e86e6a89d2 + depends: + - python - libcxx >=19 - - python >=3.14,<3.15.0a0 + - __osx >=11.0 + - python 3.14.* *_cp314 + - gfal2 >=2.23.5,<2.24.0a0 + - python_abi 3.14.* *_cp314 + - libboost-python >=1.88.0,<1.89.0a0 + - libglib >=2.86.3,<3.0a0 + license: Apache-2.0 + license_family: APACHE + purls: + - pkg:pypi/gfal2-python?source=hash-mapping + size: 185917 + timestamp: 1769083275804 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/python-librt-0.7.8-py314ha14b1ff_0.conda + sha256: 3af72999955913d5f1f1eec62ff5080ff14e44435f527e273e310a5e3e7682d9 + md5: 89c4e1720ff541a874b45fe06b4e1e1e + depends: + - python + - __osx >=11.0 + - python 3.14.* *_cp314 - python_abi 3.14.* *_cp314 license: MIT license_family: MIT purls: - - pkg:pypi/ukkonen?source=hash-mapping - size: 14286 - timestamp: 1769439103231 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/ukkonen-1.1.0-py314h6cfcd04_0.conda - sha256: 033dbf9859fe58fb85350cf6395be6b1346792e1766d2d5acab538a6eb3659fb - md5: e229f444fbdb28d8c4f40e247154d993 + - pkg:pypi/librt?source=hash-mapping + size: 65713 + timestamp: 1768407001203 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyyaml-6.0.3-py314h6e9b3f0_1.conda + sha256: 95f385f9606e30137cf0b5295f63855fd22223a4cf024d306cf9098ea1c4a252 + md5: dcf51e564317816cb8d546891019b3ab depends: - __osx >=11.0 - - cffi - - libcxx >=19 - python >=3.14,<3.15.0a0 - python >=3.14,<3.15.0a0 *_cp314 - python_abi 3.14.* *_cp314 + - yaml >=0.2.5,<0.3.0a0 license: MIT license_family: MIT purls: - - pkg:pypi/ukkonen?source=hash-mapping - size: 14884 - timestamp: 1769439056290 + - pkg:pypi/pyyaml?source=compressed-mapping + size: 189475 + timestamp: 1770223788648 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/readline-8.3-h46df422_0.conda + sha256: a77010528efb4b548ac2a4484eaf7e1c3907f2aec86123ed9c5212ae44502477 + md5: f8381319127120ce51e081dce4865cf4 + depends: + - __osx >=11.0 + - ncurses >=6.5,<7.0a0 + license: GPL-3.0-only + license_family: GPL + purls: [] + size: 313930 + timestamp: 1765813902568 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/rpds-py-0.30.0-py314haad56a0_0.conda + sha256: e161dd97403b8b8a083d047369a5cf854557dba1204d29e2f0250f5ac4403925 + md5: 76a4f88d1b7748c477abf3c341edc64c + depends: + - python + - __osx >=11.0 + - python 3.14.* *_cp314 + - python_abi 3.14.* *_cp314 + constrains: + - __osx >=11.0 + license: MIT + license_family: MIT + purls: + - pkg:pypi/rpds-py?source=hash-mapping + size: 350976 + timestamp: 1764543169524 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/ruff-0.15.0-h279115b_0.conda + noarch: python + sha256: d0d55cd450f7e66b98aec49bd76e7476badeed78563988003766d4dd5c4850fa + md5: 67e036614accdbee477daac1ba2441b9 + depends: + - python + - __osx >=11.0 + constrains: + - __osx >=11.0 + license: MIT + license_family: MIT + purls: + - pkg:pypi/ruff?source=compressed-mapping + size: 8383076 + timestamp: 1770153856208 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/scitokens-cpp-1.3.0-h608d757_0.conda + sha256: 647dd5a8ead4e8268c546cb91a34289a4aaede39b9d47ab50fe9facdd91880dd + md5: c63e2462ec4f3ef4a2af2dcbf63a3842 + depends: + - __osx >=11.0 + - libcurl >=8.18.0,<9.0a0 + - libcxx >=19 + - libsqlite >=3.51.2,<4.0a0 + - openssl >=3.5.5,<4.0a0 + license: Apache-2.0 + license_family: APACHE + purls: [] + size: 178975 + timestamp: 1769697339391 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/srm-ifce-1.24.6-he0fb9dd_2.conda + sha256: 8a0bcdaa875490a30a7928c720c622bef66b903e0036b0e89ff1df46d30449bf + md5: 08116d760c59cc3b713406ded76db1ac + depends: + - gct >=6.2.1705709074,<6.2.1705709075.0a0 + - gsoap >=2.8.123,<2.8.124.0a0 + - libcxx >=16 + - libglib >=2.78.4,<3.0a0 + - openssl >=3.2.1,<4.0a0 + license: Apache-2.0 + license_family: Apache + purls: [] + size: 181605 + timestamp: 1709962334959 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/tk-8.6.13-h010d191_3.conda + sha256: 799cab4b6cde62f91f750149995d149bc9db525ec12595e8a1d91b9317f038b3 + md5: a9d86bc62f39b94c4661716624eb21b0 + depends: + - __osx >=11.0 + - libzlib >=1.3.1,<2.0a0 + license: TCL + license_family: BSD + purls: [] + size: 3127137 + timestamp: 1769460817696 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/ukkonen-1.1.0-py314h6cfcd04_0.conda + sha256: 033dbf9859fe58fb85350cf6395be6b1346792e1766d2d5acab538a6eb3659fb + md5: e229f444fbdb28d8c4f40e247154d993 + depends: + - __osx >=11.0 + - cffi + - libcxx >=19 + - python >=3.14,<3.15.0a0 + - python >=3.14,<3.15.0a0 *_cp314 + - python_abi 3.14.* *_cp314 + license: MIT + license_family: MIT + purls: + - pkg:pypi/ukkonen?source=hash-mapping + size: 14884 + timestamp: 1769439056290 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/xrootd-5.9.1-py314h6e96a01_0.conda + sha256: 2c3a4a6ed0e8c9163eef9967b6ff3ca72145e08d90349052ebf48c9e89a5dbd7 + md5: e7a71484b64ce6e45fd9d85645641f4a + depends: + - openssl + - python + - readline + - libxml2-devel + - krb5 + - zlib + - ncurses + - libcxx >=19 + - __osx >=11.0 + - python 3.14.* *_cp314 + - libxml2 + - libxml2-16 >=2.14.6 + - openssl >=3.5.4,<4.0a0 + - libxcrypt >=4.4.36 + - libzlib >=1.3.1,<2.0a0 + - scitokens-cpp >=1.2.0,<2.0a0 + - python_abi 3.14.* *_cp314 + - readline >=8.3,<9.0a0 + - krb5 >=1.21.3,<1.22.0a0 + - libcurl >=8.18.0,<9.0a0 + - ncurses >=6.5,<7.0a0 + license: LGPL-3.0-or-later + license_family: LGPL + purls: + - pkg:pypi/xrootd?source=hash-mapping + size: 3347452 + timestamp: 1769448002819 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/yaml-0.2.5-h925e9cb_3.conda + sha256: b03433b13d89f5567e828ea9f1a7d5c5d697bf374c28a4168d71e9464f5dafac + md5: 78a0fe9e9c50d2c381e8ee47e3ea437d + depends: + - __osx >=11.0 + license: MIT + license_family: MIT + purls: [] + size: 83386 + timestamp: 1753484079473 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/zlib-1.3.1-h8359307_2.conda + sha256: 58f8860756680a4831c1bf4f294e2354d187f2e999791d53b1941834c4b37430 + md5: e3170d898ca6cb48f1bb567afb92f775 + depends: + - __osx >=11.0 + - libzlib 1.3.1 h8359307_2 + license: Zlib + license_family: Other + purls: [] + size: 77606 + timestamp: 1727963209370 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/zstd-1.5.7-hbf9d68e_6.conda + sha256: 9485ba49e8f47d2b597dd399e88f4802e100851b27c21d7525625b0b4025a5d9 + md5: ab136e4c34e97f34fb621d2592a393d8 + depends: + - __osx >=11.0 + - libzlib >=1.3.1,<2.0a0 + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 433413 + timestamp: 1764777166076 +- pypi: . + name: dirac-cwl + requires_dist: + - cwl-utils + - cwlformat + - cwltool + - dirac>=9.0.0 + - diracx-core>=0.0.8 + - diracx-api>=0.0.8 + - diracx-client>=0.0.8 + - diracx-cli>=0.0.8 + - lbprodrun + - lhcbdirac @ git+https://****@gitlab.cern.ch/jlisalab/LHCbDIRAC.git@modules-to-cwl-migration + - pydantic + - pyyaml + - typer + - referencing>=0.30 + - rich + - ruamel-yaml + - pytest>=6 ; extra == 'testing' + - pytest-mock ; extra == 'testing' + - mypy ; extra == 'testing' + requires_python: '>=3.11' +- pypi: git+https://gitlab.cern.ch/jlisalab/LHCbDIRAC.git?rev=modules-to-cwl-migration#bc5f8f1804107bc8807edcc98a97c346ef61c0e8 + name: lhcbdirac + version: 0.1.dev20470+gbc5f8f180 + requires_dist: + - dirac~=9.1 + - lbplatformutils>=4.6.1 + - lbenv>=2.3.0 + - lbprodrun + - lbcondawrappers + - requests + - pydantic>=2 + - uproot[xrootd]>=5.3 + - pyyaml + - xmltodict + - hyperscan + - levenshtein + - zstandard + - rich + - httpx + - beautifulsoup4 + - python-gitlab + - pandas + - numpy + - lhcbdiracx-client + - lhcbdiracx-core + - lhcbdiracx-cli + - signurlarity + - oracledb ; extra == 'server' + - dirac[server]~=9.1.0 ; extra == 'server' + - psutil ; extra == 'server' + - stomp-py ; extra == 'server' + - suds ; extra == 'server' + - mock ; extra == 'testing' + - pytest-mock ; extra == 'testing' + - pillow ; extra == 'testing' + - pytest ; extra == 'testing' + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/02/64/c86924898062e8217ed914a29458cfde9e4a9b80e4d4cbcca141983ba339/lbprodrun-1.12.4-py3-none-any.whl + name: lbprodrun + version: 1.12.4 + sha256: a2a408f00f31d124dd3c262db7d3aaa4cd022ec9c649b91b792c6be64b7b4c21 + requires_dist: + - click>=8.0 + - lbenv + - pydantic>=1.10 + - typer>=0.4.1 + - packaging + - pyyaml>=6.0 + - lbcondawrappers + - pytest ; extra == 'testing' + - pytest-cov ; extra == 'testing' + - zstandard ; extra == 'testing' + - mypy ; extra == 'mypy' + - types-pyyaml ; extra == 'mypy' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/03/15/d4a377b385ab693ce97b472fe0c77c2b16ec79590e688b3ccc71fba19884/lxml-6.0.2-cp314-cp314-macosx_10_13_universal2.whl + name: lxml + version: 6.0.2 + sha256: b0c732aa23de8f8aec23f4b580d1e52905ef468afb4abeafd3fec77042abb6fe + requires_dist: + - cssselect>=0.7 ; extra == 'cssselect' + - html5lib ; extra == 'html5' + - beautifulsoup4 ; extra == 'htmlsoup' + - lxml-html-clean ; extra == 'html-clean' + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl + name: h11 + version: 0.16.0 + sha256: 63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86 + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/04/80/97b6f357ac458d9ad9872cc3183ca09ef7439ac89e030ea43053ba1294b6/rich_argparse-1.7.2-py3-none-any.whl + name: rich-argparse + version: 1.7.2 + sha256: 0559b1f47a19bbeb82bf15f95a057f99bcbbc98385532f57937f9fc57acc501a + requires_dist: + - rich>=11.0.0 + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/04/be/d09147ad1ec7934636ad912901c5fd7667e1c858e19d355237db0d0cd5e4/smmap-5.0.2-py3-none-any.whl + name: smmap + version: 5.0.2 + sha256: b30115f0def7d7531d22a0fb6502488d879e75b260a9db4d0819cfb25403af5e + requires_python: '>=3.7' +- pypi: https://files.pythonhosted.org/packages/05/45/1256fb597bb83b58a01ddb600c59fe6fdf0e5afe333f0456ed75c0f8d7bd/sqlalchemy-2.0.46-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + name: sqlalchemy + version: 2.0.46 + sha256: 9bcdce05f056622a632f1d44bb47dbdb677f58cad393612280406ce37530eb6d + requires_dist: + - importlib-metadata ; python_full_version < '3.8' + - greenlet>=1 ; platform_machine == 'AMD64' or platform_machine == 'WIN32' or platform_machine == 'aarch64' or platform_machine == 'amd64' or platform_machine == 'ppc64le' or platform_machine == 'win32' or platform_machine == 'x86_64' + - typing-extensions>=4.6.0 + - greenlet>=1 ; extra == 'asyncio' + - mypy>=0.910 ; extra == 'mypy' + - pyodbc ; extra == 'mssql' + - pymssql ; extra == 'mssql-pymssql' + - pyodbc ; extra == 'mssql-pyodbc' + - mysqlclient>=1.4.0 ; extra == 'mysql' + - mysql-connector-python ; extra == 'mysql-connector' + - mariadb>=1.0.1,!=1.1.2,!=1.1.5,!=1.1.10 ; extra == 'mariadb-connector' + - cx-oracle>=8 ; extra == 'oracle' + - oracledb>=1.0.1 ; extra == 'oracle-oracledb' + - psycopg2>=2.7 ; extra == 'postgresql' + - pg8000>=1.29.1 ; extra == 'postgresql-pg8000' + - greenlet>=1 ; extra == 'postgresql-asyncpg' + - asyncpg ; extra == 'postgresql-asyncpg' + - psycopg2-binary ; extra == 'postgresql-psycopg2binary' + - psycopg2cffi ; extra == 'postgresql-psycopg2cffi' + - psycopg>=3.0.7 ; extra == 'postgresql-psycopg' + - psycopg[binary]>=3.0.7 ; extra == 'postgresql-psycopgbinary' + - pymysql ; extra == 'pymysql' + - greenlet>=1 ; extra == 'aiomysql' + - aiomysql>=0.2.0 ; extra == 'aiomysql' + - greenlet>=1 ; extra == 'aioodbc' + - aioodbc ; extra == 'aioodbc' + - greenlet>=1 ; extra == 'asyncmy' + - asyncmy>=0.2.3,!=0.2.4,!=0.2.6 ; extra == 'asyncmy' + - greenlet>=1 ; extra == 'aiosqlite' + - aiosqlite ; extra == 'aiosqlite' + - typing-extensions!=3.10.0.1 ; extra == 'aiosqlite' + - sqlcipher3-binary ; extra == 'sqlcipher' + requires_python: '>=3.7' +- pypi: https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl + name: idna + version: '3.11' + sha256: 771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea + requires_dist: + - ruff>=0.6.2 ; extra == 'all' + - mypy>=1.11.2 ; extra == 'all' + - pytest>=8.3.2 ; extra == 'all' + - flake8>=7.1.1 ; extra == 'all' + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/0f/15/5bf3b99495fb160b63f95972b81750f18f7f4e02ad051373b669d17d44f2/aiohappyeyeballs-2.6.1-py3-none-any.whl + name: aiohappyeyeballs + version: 2.6.1 + sha256: f349ba8f4b75cb25c99c5c2d84e997e485204d2902a9597802b0371f09331fb8 + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/10/a1/510b0a7fadc6f43a6ce50152e69dbd86415240835868bb0bd9b5b88b1e06/aioitertools-0.13.0-py3-none-any.whl + name: aioitertools + version: 0.13.0 + sha256: 0be0292b856f08dfac90e31f4739432f4cb6d7520ab9eb73e143f4f2fa5259be + requires_dist: + - typing-extensions>=4.0 ; python_full_version < '3.10' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/10/bd/c038d7cc38edc1aa5bf91ab8068b63d4308c66c4c8bb3cbba7dfbc049f9c/pyparsing-3.3.2-py3-none-any.whl + name: pyparsing + version: 3.3.2 + sha256: 850ba148bd908d7e2411587e247a1e4f0327839c40e2e5e6d05a007ecc69911d + requires_dist: + - railroad-diagrams ; extra == 'diagrams' + - jinja2 ; extra == 'diagrams' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/11/63/ff458113c5c2dac9a9719ac68ee7c947cb621432bcf28c9972b1c0e83938/yarl-1.22.0-cp314-cp314-macosx_11_0_arm64.whl + name: yarl + version: 1.22.0 + sha256: 594fcab1032e2d2cc3321bb2e51271e7cd2b516c7d9aee780ece81b07ff8244b + requires_dist: + - idna>=2.0 + - multidict>=4.0 + - propcache>=0.2.1 + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/14/1b/a298b06749107c305e1fe0f814c6c74aea7b2f1e10989cb30f544a1b3253/python_dotenv-1.2.1-py3-none-any.whl + name: python-dotenv + version: 1.2.1 + sha256: b81ee9561e9ca4004139c6cbba3a238c32b03e4894671e181b671e8cb8425d61 + requires_dist: + - click>=5.0 ; extra == 'cli' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/14/2f/967ba146e6d58cf6a652da73885f52fc68001525b4197effc174321d70b4/jmespath-1.1.0-py3-none-any.whl + name: jmespath + version: 1.1.0 + sha256: a5663118de4908c91729bea0acadca56526eb2698e83de10cd116ae0f4e97c64 + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/15/88/3cdd54fa279341afa10acf8d2b503556b1375245dccc9315659f795dd2e9/pandas-3.0.2-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl + name: pandas + version: 3.0.2 + sha256: deeca1b5a931fdf0c2212c8a659ade6d3b1edc21f0914ce71ef24456ca7a6535 + requires_dist: + - numpy>=1.26.0 ; python_full_version < '3.14' + - numpy>=2.3.3 ; python_full_version >= '3.14' + - python-dateutil>=2.8.2 + - tzdata ; sys_platform == 'win32' + - tzdata ; sys_platform == 'emscripten' + - hypothesis>=6.116.0 ; extra == 'test' + - pytest>=8.3.4 ; extra == 'test' + - pytest-xdist>=3.6.1 ; extra == 'test' + - pyarrow>=13.0.0 ; extra == 'pyarrow' + - bottleneck>=1.4.2 ; extra == 'performance' + - numba>=0.60.0 ; extra == 'performance' + - numexpr>=2.10.2 ; extra == 'performance' + - scipy>=1.14.1 ; extra == 'computation' + - xarray>=2024.10.0 ; extra == 'computation' + - fsspec>=2024.10.0 ; extra == 'fss' + - s3fs>=2024.10.0 ; extra == 'aws' + - gcsfs>=2024.10.0 ; extra == 'gcp' + - odfpy>=1.4.1 ; extra == 'excel' + - openpyxl>=3.1.5 ; extra == 'excel' + - python-calamine>=0.3.0 ; extra == 'excel' + - pyxlsb>=1.0.10 ; extra == 'excel' + - xlrd>=2.0.1 ; extra == 'excel' + - xlsxwriter>=3.2.0 ; extra == 'excel' + - pyarrow>=13.0.0 ; extra == 'parquet' + - pyarrow>=13.0.0 ; extra == 'feather' + - pyiceberg>=0.8.1 ; extra == 'iceberg' + - tables>=3.10.1 ; extra == 'hdf5' + - pyreadstat>=1.2.8 ; extra == 'spss' + - sqlalchemy>=2.0.36 ; extra == 'postgresql' + - psycopg2>=2.9.10 ; extra == 'postgresql' + - adbc-driver-postgresql>=1.2.0 ; extra == 'postgresql' + - sqlalchemy>=2.0.36 ; extra == 'mysql' + - pymysql>=1.1.1 ; extra == 'mysql' + - sqlalchemy>=2.0.36 ; extra == 'sql-other' + - adbc-driver-postgresql>=1.2.0 ; extra == 'sql-other' + - adbc-driver-sqlite>=1.2.0 ; extra == 'sql-other' + - beautifulsoup4>=4.12.3 ; extra == 'html' + - html5lib>=1.1 ; extra == 'html' + - lxml>=5.3.0 ; extra == 'html' + - lxml>=5.3.0 ; extra == 'xml' + - matplotlib>=3.9.3 ; extra == 'plot' + - jinja2>=3.1.5 ; extra == 'output-formatting' + - tabulate>=0.9.0 ; extra == 'output-formatting' + - pyqt5>=5.15.9 ; extra == 'clipboard' + - qtpy>=2.4.2 ; extra == 'clipboard' + - zstandard>=0.23.0 ; extra == 'compression' + - pytz>=2024.2 ; extra == 'timezone' + - adbc-driver-postgresql>=1.2.0 ; extra == 'all' + - adbc-driver-sqlite>=1.2.0 ; extra == 'all' + - beautifulsoup4>=4.12.3 ; extra == 'all' + - bottleneck>=1.4.2 ; extra == 'all' + - fastparquet>=2024.11.0 ; extra == 'all' + - fsspec>=2024.10.0 ; extra == 'all' + - gcsfs>=2024.10.0 ; extra == 'all' + - html5lib>=1.1 ; extra == 'all' + - hypothesis>=6.116.0 ; extra == 'all' + - jinja2>=3.1.5 ; extra == 'all' + - lxml>=5.3.0 ; extra == 'all' + - matplotlib>=3.9.3 ; extra == 'all' + - numba>=0.60.0 ; extra == 'all' + - numexpr>=2.10.2 ; extra == 'all' + - odfpy>=1.4.1 ; extra == 'all' + - openpyxl>=3.1.5 ; extra == 'all' + - psycopg2>=2.9.10 ; extra == 'all' + - pyarrow>=13.0.0 ; extra == 'all' + - pyiceberg>=0.8.1 ; extra == 'all' + - pymysql>=1.1.1 ; extra == 'all' + - pyqt5>=5.15.9 ; extra == 'all' + - pyreadstat>=1.2.8 ; extra == 'all' + - pytest>=8.3.4 ; extra == 'all' + - pytest-xdist>=3.6.1 ; extra == 'all' + - python-calamine>=0.3.0 ; extra == 'all' + - pytz>=2024.2 ; extra == 'all' + - pyxlsb>=1.0.10 ; extra == 'all' + - qtpy>=2.4.2 ; extra == 'all' + - scipy>=1.14.1 ; extra == 'all' + - s3fs>=2024.10.0 ; extra == 'all' + - sqlalchemy>=2.0.36 ; extra == 'all' + - tables>=3.10.1 ; extra == 'all' + - tabulate>=0.9.0 ; extra == 'all' + - xarray>=2024.10.0 ; extra == 'all' + - xlrd>=2.0.1 ; extra == 'all' + - xlsxwriter>=3.2.0 ; extra == 'all' + - zstandard>=0.23.0 ; extra == 'all' + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/15/aa/0aca39a37d3c7eb941ba736ede56d689e7be91cab5d9ca846bde3999eba6/isodate-0.7.2-py3-none-any.whl + name: isodate + version: 0.7.2 + sha256: 28009937d8031054830160fce6d409ed342816b543597cece116d966c6d99e15 + requires_python: '>=3.7' +- pypi: https://files.pythonhosted.org/packages/18/d7/5dac2eb2ec75fd771957a13e5dda560efb2176d5203f39502a5fc571f899/xxhash-3.6.0-cp314-cp314-macosx_11_0_arm64.whl + name: xxhash + version: 3.6.0 + sha256: a54844be970d3fc22630b32d515e79a90d0a3ddb2644d8d7402e3c4c8da61405 + requires_python: '>=3.7' +- pypi: https://files.pythonhosted.org/packages/19/0f/f6121b90b86b9093c066889274d26a1de3f29969d45c2ed1ecbe2033cb78/cramjam-2.11.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl + name: cramjam + version: 2.11.0 + sha256: 17eb39b1696179fb471eea2de958fa21f40a2cd8bf6b40d428312d5541e19dc4 + requires_dist: + - black==22.3.0 ; extra == 'dev' + - numpy ; extra == 'dev' + - pytest>=5.30 ; extra == 'dev' + - pytest-xdist ; extra == 'dev' + - pytest-benchmark ; extra == 'dev' + - hypothesis==6.60.0 ; extra == 'dev' + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/1a/39/47f9197bdd44df24d67ac8893641e16f386c984a0619ef2ee4c51fbbc019/beautifulsoup4-4.14.3-py3-none-any.whl + name: beautifulsoup4 + version: 4.14.3 + sha256: 0918bfe44902e6ad8d57732ba310582e98da931428d231a5ecb9e7c703a735bb + requires_dist: + - soupsieve>=1.6.1 + - typing-extensions>=4.0.0 + - cchardet ; extra == 'cchardet' + - chardet ; extra == 'chardet' + - charset-normalizer ; extra == 'charset-normalizer' + - html5lib ; extra == 'html5lib' + - lxml ; extra == 'lxml' + requires_python: '>=3.7.0' +- pypi: https://files.pythonhosted.org/packages/1b/9f/38ff9e57a2eade7bf9dfee5eae17f39fc0e998658050279cbb14d97d36d9/msgpack-1.1.2-cp314-cp314-macosx_11_0_arm64.whl + name: msgpack + version: 1.1.2 + sha256: 6c15b7d74c939ebe620dd8e559384be806204d73b4f9356320632d783d1f7939 + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/1c/1c/ab905d19a1349e847e37e02933316d17adfd1dd70b64d366885ab0bd959d/xattr-1.3.0-cp314-cp314-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl + name: xattr + version: 1.3.0 + sha256: c6992eb5da32c0a1375a9eeacfab15c66eebc8bd34be63ebd1eae80cc2f8bf03 + requires_dist: + - cffi>=1.16.0 + - pytest ; extra == 'test' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/1e/db/4254e3eabe8020b458f1a747140d32277ec7a271daf1d235b70dc0b4e6e3/requests-2.32.5-py3-none-any.whl + name: requests + version: 2.32.5 + sha256: 2462f94637a34fd532264295e186976db0f5d453d1cdd31473c85a6a161affb6 + requires_dist: + - charset-normalizer>=2,<4 + - idna>=2.5,<4 + - urllib3>=1.21.1,<3 + - certifi>=2017.4.17 + - pysocks>=1.5.6,!=1.5.7 ; extra == 'socks' + - chardet>=3.0.2,<6 ; extra == 'use-chardet-on-py3' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/22/71/201105712d0a2ff07b7873ed3c220292fb2ea5120603c00c4b634bcdafb3/msgpack-1.1.2-cp314-cp314-macosx_10_13_x86_64.whl + name: msgpack + version: 1.1.2 + sha256: e23ce8d5f7aa6ea6d2a2b326b4ba46c985dbb204523759984430db7114f8aa00 + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/22/a6/858897256d0deac81a172289110f31629fc4cee19b6f01283303e18c8db3/ptyprocess-0.7.0-py2.py3-none-any.whl + name: ptyprocess + version: 0.7.0 + sha256: 4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35 +- pypi: https://files.pythonhosted.org/packages/22/ed/9c45c468fd6c31df3fe0622394b1853c00b86545d1e297f3fb9fba1232ce/hyperscan-0.8.2-cp314-cp314-macosx_10_15_x86_64.whl + name: hyperscan + version: 0.8.2 + sha256: 2c579c1ebccc384d904de4a20e7a105df6041dd82adb54cb9acd5bb19b9b07dc + requires_python: '>=3.9,<4.0' +- pypi: https://files.pythonhosted.org/packages/24/b4/11f8a31d8b67cca3371e046db49baa7c0594d71eb40ac8121e2fc0888db0/bcrypt-5.0.0-cp39-abi3-manylinux_2_28_x86_64.whl + name: bcrypt + version: 5.0.0 + sha256: f8429e1c410b4073944f03bd778a9e066e7fad723564a52ff91841d278dfc822 + requires_dist: + - pytest>=3.2.1,!=3.3.0 ; extra == 'tests' + - mypy ; extra == 'typecheck' + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/28/df/2dd32cce20cbcf6f2ec456b58d44368161ad28320729f64e5e1d5d7bd0ae/cachetools-7.0.0-py3-none-any.whl + name: cachetools + version: 7.0.0 + sha256: d52fef60e6e964a1969cfb61ccf6242a801b432790fe520d78720d757c81cbd2 + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/29/9c/47293c58cc91769130fbf85531280e8cc7868f7fbb6d92f4670071b9cb3e/lxml-6.0.2-cp314-cp314-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl + name: lxml + version: 6.0.2 + sha256: 98a5e1660dc7de2200b00d53fa00bcd3c35a3608c305d45a7bbcaf29fa16e83d + requires_dist: + - cssselect>=0.7 ; extra == 'cssselect' + - html5lib ; extra == 'html5' + - beautifulsoup4 ; extra == 'htmlsoup' + - lxml-html-clean ; extra == 'html-clean' + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/29/ce/ed422816fb30ffa3bc11597b30d5deca06b4a1388707a04215da73c65b53/levenshtein-0.27.3-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl + name: levenshtein + version: 0.27.3 + sha256: ce3bbbe92172a08b599d79956182c6b7ab6ec8d4adbe7237417a363b968ad87b + requires_dist: + - rapidfuzz>=3.9.0,<4.0.0 + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/2a/35/7051599bd493e62411d6ede36fd5af83a38f37c4767b92884df7301db25d/charset_normalizer-3.4.4-cp314-cp314-macosx_10_13_universal2.whl + name: charset-normalizer + version: 3.4.4 + sha256: da3326d9e65ef63a817ecbcc0df6e94463713b754fe293eaa03da99befb9a5bd + requires_python: '>=3.7' +- pypi: https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl + name: httpx + version: 0.28.1 + sha256: d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad + requires_dist: + - anyio + - certifi + - httpcore==1.* + - idna + - brotli ; platform_python_implementation == 'CPython' and extra == 'brotli' + - brotlicffi ; platform_python_implementation != 'CPython' and extra == 'brotli' + - click==8.* ; extra == 'cli' + - pygments==2.* ; extra == 'cli' + - rich>=10,<14 ; extra == 'cli' + - h2>=3,<5 ; extra == 'http2' + - socksio==1.* ; extra == 'socks' + - zstandard>=0.18.0 ; extra == 'zstd' + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/2b/08/f83e2e0814248b844265802d081f2fac2f1cbe6cd258e72ba14ff006823a/cryptography-46.0.4-cp311-abi3-manylinux_2_28_x86_64.whl + name: cryptography + version: 46.0.4 + sha256: 0a9ad24359fee86f131836a9ac3bffc9329e956624a2d379b613f8f8abaf5255 + requires_dist: + - cffi>=1.14 ; python_full_version == '3.8.*' and platform_python_implementation != 'PyPy' + - cffi>=2.0.0 ; python_full_version >= '3.9' and platform_python_implementation != 'PyPy' + - typing-extensions>=4.13.2 ; python_full_version < '3.11' + - bcrypt>=3.1.5 ; extra == 'ssh' + - nox[uv]>=2024.4.15 ; extra == 'nox' + - cryptography-vectors==46.0.4 ; extra == 'test' + - pytest>=7.4.0 ; extra == 'test' + - pytest-benchmark>=4.0 ; extra == 'test' + - pytest-cov>=2.10.1 ; extra == 'test' + - pytest-xdist>=3.5.0 ; extra == 'test' + - pretend>=0.7 ; extra == 'test' + - certifi>=2024 ; extra == 'test' + - pytest-randomly ; extra == 'test-randomorder' + - sphinx>=5.3.0 ; extra == 'docs' + - sphinx-rtd-theme>=3.0.0 ; extra == 'docs' + - sphinx-inline-tabs ; extra == 'docs' + - pyenchant>=3 ; extra == 'docstest' + - readme-renderer>=30.0 ; extra == 'docstest' + - sphinxcontrib-spelling>=7.3.1 ; extra == 'docstest' + - build>=1.0.0 ; extra == 'sdist' + - ruff>=0.11.11 ; extra == 'pep8test' + - mypy>=1.14 ; extra == 'pep8test' + - check-sdist ; extra == 'pep8test' + - click>=8.0.1 ; extra == 'pep8test' + requires_python: '>=3.8,!=3.9.0,!=3.9.1' +- pypi: https://files.pythonhosted.org/packages/2d/88/67602dfa2d7ab5d0518af82db34ab4d70dc2c3029b3ca788299a3be4a96d/lhcbdiracx_client-0.0.8-py3-none-any.whl + name: lhcbdiracx-client + version: 0.0.8 + sha256: 72bea573c481d011d816cbf02e39cee610b4b7aa8b57a2941659036de483907e + requires_dist: + - lhcbdiracx-core + - diracx-client==0.0.8 + - types-requests ; extra == 'types' + - diracx-api[types]==0.0.8 ; extra == 'types' + - diracx-client[testing]==0.0.8 ; extra == 'testing' + - diracx-testing==0.0.8 ; extra == 'testing' + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/2d/e1/c2141f1840a41e07ad2db6f724945f8f8ff3065463899a22939152dd6e09/rapidfuzz-3.14.5-cp314-cp314-macosx_11_0_arm64.whl + name: rapidfuzz + version: 3.14.5 + sha256: 0298d357e2bc59d572da4db0bc631009b6f8f6c9bc8c11e99a12b833f16b6575 + requires_dist: + - numpy ; extra == 'all' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/2e/54/647ade08bf0db230bfea292f893923872fd20be6ac6f53b2b936ba839d75/zipp-3.23.0-py3-none-any.whl + name: zipp + version: 3.23.0 + sha256: 071652d6115ed432f5ce1d34c336c0adfd6a884660d1e9712a256d3d3bd4b14e + requires_dist: + - pytest>=6,!=8.1.* ; extra == 'test' + - jaraco-itertools ; extra == 'test' + - jaraco-functools ; extra == 'test' + - more-itertools ; extra == 'test' + - big-o ; extra == 'test' + - pytest-ignore-flaky ; extra == 'test' + - jaraco-test ; extra == 'test' + - sphinx>=3.5 ; extra == 'doc' + - jaraco-packaging>=9.3 ; extra == 'doc' + - rst-linker>=1.9 ; extra == 'doc' + - furo ; extra == 'doc' + - sphinx-lint ; extra == 'doc' + - jaraco-tidelift>=1.4 ; extra == 'doc' + - pytest-checkdocs>=2.4 ; extra == 'check' + - pytest-ruff>=0.2.1 ; sys_platform != 'cygwin' and extra == 'check' + - pytest-cov ; extra == 'cover' + - pytest-enabler>=2.2 ; extra == 'enabler' + - pytest-mypy ; extra == 'type' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/2f/40/dc34d1a8d5f1e51fc64640b62b191684da52ca469da9cd74e84936ffa4a6/msgpack-1.1.2-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + name: msgpack + version: 1.1.2 + sha256: 180759d89a057eab503cf62eeec0aa61c4ea1200dee709f3a8e9397dbb3b6931 + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/31/dc/cc50210e11e465c975462439a492516a73300ab8caa8f5e0902544fd748b/zstandard-0.25.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + name: zstandard + version: 0.25.0 + sha256: e09bb6252b6476d8d56100e8147b803befa9a12cea144bbe629dd508800d1ad0 + requires_dist: + - cffi~=1.17 ; python_full_version < '3.14' and platform_python_implementation != 'PyPy' and extra == 'cffi' + - cffi>=2.0.0b0 ; python_full_version >= '3.14' and platform_python_implementation != 'PyPy' and extra == 'cffi' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/32/4b/b99e37f88336009971405cbb7630610322ed6fbfa31e1d7ab3fbf3049a2d/invoke-2.2.1-py3-none-any.whl + name: invoke + version: 2.2.1 + sha256: 2413bc441b376e5cd3f55bb5d364f973ad8bdd7bf87e53c79de3c11bf3feecc8 + requires_python: '>=3.6' +- pypi: https://files.pythonhosted.org/packages/34/8f/6105afdd8f4e1f3b198d09e4b2622622923d9fa9e077aed852c0bb035a3a/lhcbdiracx_core-0.0.8-py3-none-any.whl + name: lhcbdiracx-core + version: 0.0.8 + sha256: a23f9b343efddb80cb53c3e06c409c65221ff29a339d4aebe336f930d04c7942 + requires_dist: + - diracx-core==0.0.8 + - lhcbdiracx-testing ; extra == 'testing' + - diracx-testing ; extra == 'testing' + - diracx-core[types]==0.0.8 ; extra == 'testing' + - diracx-core[testing]==0.0.8 ; extra == 'types' + - types-cachetools ; extra == 'types' + - types-pyyaml ; extra == 'types' + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/37/f9/f8497ef8b873a8bb2a750ee2a6c5f0fc22258e1acb6245fd237042a6c279/fabric-3.2.3-py3-none-any.whl + name: fabric + version: 3.2.3 + sha256: ce61917f4f398018337ce279b357650a3a74baecf3fdd53a5839013944af965e + requires_dist: + - invoke>=2.0,<3.0 + - paramiko>=2.4 + - decorator>=5 + - deprecated>=1.2 + - pytest>=7 ; extra == 'pytest' +- pypi: https://files.pythonhosted.org/packages/38/0e/27be9fdef66e72d64c0cdc3cc2823101b80585f8119b5c112c2e8f5f7dab/anyio-4.12.1-py3-none-any.whl + name: anyio + version: 4.12.1 + sha256: d405828884fc140aa80a3c667b8beed277f1dfedec42ba031bd6ac3db606ab6c + requires_dist: + - exceptiongroup>=1.0.2 ; python_full_version < '3.11' + - idna>=2.8 + - typing-extensions>=4.5 ; python_full_version < '3.13' + - trio>=0.32.0 ; python_full_version >= '3.10' and extra == 'trio' + - trio>=0.31.0 ; python_full_version < '3.10' and extra == 'trio' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/38/34/98a2f52245f4d47be93b580dae5f9861ef58977d73a79eb47c58f1ad1f3a/xmltodict-1.0.4-py3-none-any.whl + name: xmltodict + version: 1.0.4 + sha256: a4a00d300b0e1c59fc2bfccb53d7b2e88c32f200df138a0dd2229f842497026a + requires_dist: + - pytest ; extra == 'test' + - pytest-cov ; extra == 'test' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/38/ee/a61bb562bdf6f0bc6c51cdcf80ab5503cbb4b2f5053fa4b054cc0a56e48a/python_gitlab-8.2.0-py3-none-any.whl + name: python-gitlab + version: 8.2.0 + sha256: 884618d4d60beadb21bb0c5f0cca46e70c6e501784f136bf0b6f85f5bc15ce62 + requires_dist: + - requests>=2.32.0 + - requests-toolbelt>=1.0.0 + - argcomplete>=1.10.0,<3 ; extra == 'autocompletion' + - pyyaml>=6.0.1 ; extra == 'yaml' + - gql[httpx]>=3.5.0,<5 ; extra == 'graphql' + requires_python: '>=3.10.0' +- pypi: https://files.pythonhosted.org/packages/39/08/aaaad47bc4e9dc8c725e68f9d04865dbcb2052843ff09c97b08904852d84/urllib3-2.6.3-py3-none-any.whl + name: urllib3 + version: 2.6.3 + sha256: bf272323e553dfb2e87d9bfd225ca7b0f467b919d7bbd355436d3fd37cb0acd4 + requires_dist: + - brotli>=1.2.0 ; platform_python_implementation == 'CPython' and extra == 'brotli' + - brotlicffi>=1.2.0.0 ; platform_python_implementation != 'CPython' and extra == 'brotli' + - h2>=4,<5 ; extra == 'h2' + - pysocks>=1.5.6,!=1.5.7,<2.0 ; extra == 'socks' + - backports-zstd>=1.0.0 ; python_full_version < '3.14' and extra == 'zstd' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/3b/56/99a7cf6ca8533695874cf804369221d03bf5e869a7e0b38acbf4dbe8deeb/cwlformat-2022.2.18-py3-none-any.whl + name: cwlformat + version: 2022.2.18 + sha256: d3e2dca192ce10e703ed4eb0bae26539db08d8ddd7c6a6fe9d1406c3f1b53cda + requires_dist: + - ruamel-yaml>=0.16.12 + - importlib-resources ; python_full_version < '3.7' + requires_python: '>=3.6.0' +- pypi: https://files.pythonhosted.org/packages/3c/c1/d73f12f8cdb1891334a2ccf7389eed244d3941e74d80dd220badb937f3fb/wcwidth-0.5.3-py3-none-any.whl + name: wcwidth + version: 0.5.3 + sha256: d584eff31cd4753e1e5ff6c12e1edfdb324c995713f75d26c29807bb84bf649e + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/3d/36/9ab4f0b5c3d10df3aceaecf7e395cabe7fb7c7c004b2dc3f3cff0ef70fc3/xattr-1.3.0-cp314-cp314-macosx_11_0_arm64.whl + name: xattr + version: 1.3.0 + sha256: 88557c0769f64b1d014aada916c9630cfefa38b0be6c247eae20740d2d8f7b47 + requires_dist: + - cffi>=1.16.0 + - pytest ; extra == 'test' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/3d/5c/f8923b595b55fe49e30612987ad8bf053aef555c14f05bb659dd5dbe3e8a/zstandard-0.25.0-cp314-cp314-macosx_10_13_x86_64.whl + name: zstandard + version: 0.25.0 + sha256: e29f0cf06974c899b2c188ef7f783607dbef36da4c242eb6c82dcd8b512855e3 + requires_dist: + - cffi~=1.17 ; python_full_version < '3.14' and platform_python_implementation != 'PyPy' and extra == 'cffi' + - cffi>=2.0.0b0 ; python_full_version >= '3.14' and platform_python_implementation != 'PyPy' and extra == 'cffi' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/3e/bd/ab8459c8bb759c14a146990bf07f632c1cbec0910d4853feeee4be2ab8bb/ruamel_yaml_clib-0.2.15-cp314-cp314-macosx_10_15_x86_64.whl + name: ruamel-yaml-clib + version: 0.2.15 + sha256: 753faf20b3a5906faf1fc50e4ddb8c074cb9b251e00b14c18b28492f933ac8ef + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/3e/d0/f301f83ac8dbe53442c5a43f6a39016f94f754d7a9815a875b65e218a307/pynacl-1.6.2-cp38-abi3-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl + name: pynacl + version: 1.6.2 + sha256: 8a66d6fb6ae7661c58995f9c6435bda2b1e68b54b598a6a10247bfcdadac996c + requires_dist: + - cffi>=1.4.1 ; python_full_version < '3.9' and platform_python_implementation != 'PyPy' + - cffi>=2.0.0 ; python_full_version >= '3.9' and platform_python_implementation != 'PyPy' + - pytest>=7.4.0 ; extra == 'tests' + - pytest-cov>=2.10.1 ; extra == 'tests' + - pytest-xdist>=3.5.0 ; extra == 'tests' + - hypothesis>=3.27.0 ; extra == 'tests' + - sphinx<7 ; extra == 'docs' + - sphinx-rtd-theme ; extra == 'docs' + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/3f/51/d4db610ef29373b879047326cbf6fa98b6c1969d6f6dc423279de2b1be2c/requests_toolbelt-1.0.0-py2.py3-none-any.whl + name: requests-toolbelt + version: 1.0.0 + sha256: cccfdd665f0a24fcf4726e690f65639d272bb0637b9b92dfd91a5568ccf6bd06 + requires_dist: + - requests>=2.0.1,<3.0.0 + requires_python: '>=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*' +- pypi: https://files.pythonhosted.org/packages/40/44/4a5f08c96eb108af5cb50b41f76142f0afa346dfa99d5296fe7202a11854/tabulate-0.9.0-py3-none-any.whl + name: tabulate + version: 0.9.0 + sha256: 024ca478df22e9340661486f85298cff5f6dcdba14f3813e8830015b9ed1948f + requires_dist: + - wcwidth ; extra == 'widechars' + requires_python: '>=3.7' +- pypi: https://files.pythonhosted.org/packages/44/b5/a96872e5184f354da9c84ae119971a0a4c221fe9b27a4d94bd43f2596727/pyasn1-0.6.2-py3-none-any.whl + name: pyasn1 + version: 0.6.2 + sha256: 1eb26d860996a18e9b6ed05e7aae0e9fc21619fcee6af91cca9bad4fbea224bf + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/46/2c/1462b1d0a634697ae9e55b3cecdcb64788e8b7d63f54d923fcd0bb140aed/soupsieve-2.8.3-py3-none-any.whl + name: soupsieve + version: 2.8.3 + sha256: ed64f2ba4eebeab06cc4962affce381647455978ffc1e36bb79a545b91f45a95 + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/47/8d/d529b5d697919ba8c11ad626e835d4039be708a35b0d22de83a269a6682c/pyasn1_modules-0.4.2-py3-none-any.whl + name: pyasn1-modules + version: 0.4.2 + sha256: 29253a9207ce32b64c3ac6600edc75368f98473906e8fd1043bd6b5b1de2c14a + requires_dist: + - pyasn1>=0.6.1,<0.7.0 + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/4c/d2/ef2074dc020dd6e109611a8be4449b98cd25e1b9b8a303c2f0fca2f2bcf7/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl + name: pydantic-core + version: 2.41.5 + sha256: 22f0fb8c1c583a3b6f24df2470833b40207e907b90c928cc8d3594b76f874375 + requires_dist: + - typing-extensions>=4.14.1 + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/4e/8c/f3147f5c4b73e7550fe5f9352eaa956ae838d5c51eb58e7a25b9f3e2643b/decorator-5.2.1-py3-none-any.whl + name: decorator + version: 5.2.1 + sha256: d316bb415a2d9e2d2b3abcc4084c6502fc09240e292cd76a76afc106a1c8e04a + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/54/51/321e821856452f7386c4e9df866f196720b1ad0c5ea1623ea7399969ae3b/authlib-1.6.6-py2.py3-none-any.whl + name: authlib + version: 1.6.6 + sha256: 7d9e9bc535c13974313a87f53e8430eb6ea3d1cf6ae4f6efcd793f2e949143fd + requires_dist: + - cryptography + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/58/19/0380af745f151a1648657bbcef0fb49ac28bf09083d94498163ffd9b32dc/dominate-2.9.1-py2.py3-none-any.whl + name: dominate + version: 2.9.1 + sha256: cb7b6b79d33b15ae0a6e87856b984879927c7c2ebb29522df4c75b28ffd9b989 + requires_python: '>=3.4' +- pypi: https://files.pythonhosted.org/packages/59/25/68f81c50aeb3f30e01c20da0f56d14c1a779b57d9308c50e19c63dc8413f/signurlarity-0.2.2-py3-none-any.whl + name: signurlarity + version: 0.2.2 + sha256: 0c8089ecac04ce105e525b60749d134b171410beefc962e167e0e64141d6e7a7 + requires_dist: + - cryptography>=41.0.0 + - httpx>=0.24.0 + - orjson + - aiobotocore>=2.15 ; extra == 'testing' + - botocore>=1.35 ; extra == 'testing' + - httpx ; extra == 'testing' + - moto[server] ; extra == 'testing' + - pytest ; extra == 'testing' + - pytest-asyncio ; extra == 'testing' + - pytest-benchmark ; extra == 'testing' + - pytest-xdist ; extra == 'testing' + - rich ; extra == 'testing' + - ty ; extra == 'testing' + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/5a/36/17015b7bae2783f7bbde50a8bafdeb702802c080322204f1bfcae25b9e02/DB12-1.0.4-py3-none-any.whl + name: db12 + version: 1.0.4 + sha256: 2dbb96e77e43870e02f3dfe32bb9a4e0ad0a6e68db65bc2d5ac96b136469e2d3 + requires_python: '>=2.7' +- pypi: https://files.pythonhosted.org/packages/5a/87/b70ad306ebb6f9b585f114d0ac2137d792b48be34d732d60e597c2f8465a/pydantic-2.12.5-py3-none-any.whl + name: pydantic + version: 2.12.5 + sha256: e561593fccf61e8a20fc46dfc2dfe075b8be7d0188df33f221ad1f0139180f9d + requires_dist: + - annotated-types>=0.6.0 + - pydantic-core==2.41.5 + - typing-extensions>=4.14.1 + - typing-inspection>=0.4.2 + - email-validator>=2.0.0 ; extra == 'email' + - tzdata ; python_full_version >= '3.9' and sys_platform == 'win32' and extra == 'timezone' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/5c/48/ccd6c49477674389d55b5b5520e47d1290f4c29686c36f5674f4a7aced00/rucio_clients-39.2.0-py3-none-any.whl + name: rucio-clients + version: 39.2.0 + sha256: 97406fa7f927b24b59499bb507a43cc9f24ca8283e45315d59dd5ad4fcfbc5a2 + requires_dist: + - click + - requests + - urllib3 + - dogpile-cache + - packaging + - tabulate + - jsonschema + - rich + - typing-extensions + - paramiko ; extra == 'ssh' + - kerberos ; extra == 'kerberos' + - pykerberos ; extra == 'kerberos' + - requests-kerberos ; extra == 'kerberos' + - python-swiftclient ; extra == 'swift' + - argcomplete ; extra == 'argcomplete' + - paramiko ; extra == 'sftp' + - python-magic ; extra == 'dumper' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/5d/ba/2af136406e1c3839aea9ecadc2f6be2bcd1eff255bd451dd39bcf302c47a/bcrypt-5.0.0-cp39-abi3-macosx_10_12_universal2.whl + name: bcrypt + version: 5.0.0 + sha256: 0c418ca99fd47e9c59a301744d63328f17798b5947b0f791e9af3c1c499c2d0a + requires_dist: + - pytest>=3.2.1,!=3.3.0 ; extra == 'tests' + - mypy ; extra == 'typecheck' + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/5e/0a/3966f239e1d9da93cb755dc0213835ce4e9ed93645192878d0a055ecdc31/boto3-1.42.42-py3-none-any.whl + name: boto3 + version: 1.42.42 + sha256: 8c78169ef47dc29863ebb11ba99134b1b418d3dfdd836419830f22552f8afe43 + requires_dist: + - botocore>=1.42.42,<1.43.0 + - jmespath>=0.7.1,<2.0.0 + - s3transfer>=0.16.0,<0.17.0 + - botocore[crt]>=1.21.0,<2.0a0 ; extra == 'crt' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/5f/e8/2e6301567e6debaad6abae0e217428471651ce877537b7095b6a8e7d8cd2/fts3-3.14.2-py3-none-any.whl + name: fts3 + version: 3.14.2 + sha256: 28528f3656f156dd7cddb02ce82bb88cbaa8ab635d899aa2b97aa838d080bfd4 + requires_dist: + - m2crypto + - requests + - setuptools>=39 + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/62/86/3915cb5a603e1b1d798e1ee1ce2a0a390a0f85d35da97e4b6d1c6a45421b/schema_salad-8.9.20251102115403-cp314-cp314-macosx_10_15_x86_64.whl + name: schema-salad + version: 8.9.20251102115403 + sha256: 8d12fe61d68cbce0de95e5206dcd24d18bdb77a41830ab4c7b5794326ed23d90 + requires_dist: + - requests>=1.0 + - ruamel-yaml>=0.17.6,<0.19 + - rdflib>=4.2.2,<8.0.0 + - mistune>=3,<3.2 + - cachecontrol[filecache]>=0.13.1,<0.15 + - mypy-extensions + - sphinx>=2.2 ; extra == 'docs' + - sphinx-rtd-theme>=1 ; extra == 'docs' + - pytest<9 ; extra == 'docs' + - sphinx-autoapi ; extra == 'docs' + - sphinx-autodoc-typehints ; extra == 'docs' + - sphinxcontrib-autoprogram ; extra == 'docs' + - black ; extra == 'pycodegen' + requires_python: '>=3.9,<3.15' +- pypi: https://files.pythonhosted.org/packages/63/4b/ccab2a5ca9e0b6553810b85c06387e60fc9443cec3c987e3a062705bd225/cwl_utils-0.40-py3-none-any.whl + name: cwl-utils + version: '0.40' + sha256: f6688cd3b78b826af2aa5518b31d8d7ba784914d0a7a5784266c615093e1e94b + requires_dist: + - cwl-upgrader>=1.2.3 + - packaging + - rdflib + - requests + - schema-salad>=8.8.20250205075315,<9 + - ruamel-yaml>=0.17.6,<0.19 + - typing-extensions ; python_full_version < '3.10' + - cwlformat ; extra == 'pretty' + - pytest<9 ; extra == 'testing' + - pytest-mock ; extra == 'testing' + requires_python: '>=3.9,<3.15' +- pypi: https://files.pythonhosted.org/packages/65/9b/03b04e7d82a5f54fb16113d839f5ea1ede58a61e90edf515f6577c66fa8f/propcache-0.4.1-cp314-cp314-macosx_10_13_x86_64.whl + name: propcache + version: 0.4.1 + sha256: c0d4b719b7da33599dfe3b22d3db1ef789210a0597bc650b7cee9c77c2be8c5c + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/65/ee/a7aba2b112c5ae879d5cfb231c75189a7fd2a5e84b6af7e07dd71fb2bb35/cwltool-3.1.20260108082145-py3-none-any.whl + name: cwltool + version: 3.1.20260108082145 + sha256: ddc895c809cccf04b731476d2e35ca0126f498be079b349457a5c56471155556 + requires_dist: + - requests>=2.6.1 + - ruamel-yaml>=0.16,<0.20 + - rdflib>=4.2.2,<7.6.0 + - schema-salad>=8.9,<9 + - prov==1.5.1 + - mypy-extensions + - psutil>=5.6.6 + - coloredlogs + - pydot>=1.4.1 + - argcomplete>=1.12.0 + - pyparsing!=3.0.2 + - cwl-utils>=0.32 + - spython>=0.3.0 + - rich-argparse + - typing-extensions>=4.1.0 + - galaxy-tool-util>=22.1.2,!=23.0.1,!=23.0.2,!=23.0.3,!=23.0.4,!=23.0.5,<25.2 ; extra == 'deps' + - galaxy-util<25.2 ; extra == 'deps' + - pillow ; extra == 'deps' + requires_python: '>=3.10,<3.15' +- pypi: https://files.pythonhosted.org/packages/67/ff/f6b948ca32e4f2a4576aa129d8bed61f2e0543bf9f5f2b7fc3758ed005c9/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + name: charset-normalizer + version: 3.4.4 + sha256: ecaae4149d99b1c9e7b88bb03e3221956f68fd6d50be2ef061b2381b61d20838 + requires_python: '>=3.7' +- pypi: https://files.pythonhosted.org/packages/68/15/bfb0c717b8f23c16907f3e73e8f56010ccd72e9900a108209665b0d9ed4b/lhcbdiracx_cli-0.0.8-py3-none-any.whl + name: lhcbdiracx-cli + version: 0.0.8 + sha256: 85e357eed0578796f78a5502c2235949dcd7fa456e7efaf1a0b2913f926f1b64 + requires_dist: + - lhcbdiracx-core + - lhcbdiracx-client + - lhcbdiracx-api + - diracx-cli==0.0.8 + - diracx-cli[types]==0.0.8 ; extra == 'types' + - diracx-cli[testing]==0.0.8 ; extra == 'testing' + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/69/f2/c4cec0a30f1955510fde498aac451d2e52b24afdbcb00204d3a951b772c3/ruamel_yaml_clib-0.2.15-cp314-cp314-macosx_11_0_arm64.whl + name: ruamel-yaml-clib + version: 0.2.15 + sha256: 480894aee0b29752560a9de46c0e5f84a82602f2bc5c6cde8db9a345319acfdf + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/6a/09/e21df6aef1e1ffc0c816f0522ddc3f6dcded766c3261813131c78a704470/gitpython-3.1.46-py3-none-any.whl + name: gitpython + version: 3.1.46 + sha256: 79812ed143d9d25b6d176a10bb511de0f9c67b1fa641d82097b0ab90398a2058 + requires_dist: + - gitdb>=4.0.1,<5 + - typing-extensions>=3.10.0.2 ; python_full_version < '3.10' + - coverage[toml] ; extra == 'test' + - ddt>=1.1.1,!=1.4.3 ; extra == 'test' + - mock ; python_full_version < '3.8' and extra == 'test' + - mypy==1.18.2 ; python_full_version >= '3.9' and extra == 'test' + - pre-commit ; extra == 'test' + - pytest>=7.3.1 ; extra == 'test' + - pytest-cov ; extra == 'test' + - pytest-instafail ; extra == 'test' + - pytest-mock ; extra == 'test' + - pytest-sugar ; extra == 'test' + - typing-extensions ; python_full_version < '3.11' and extra == 'test' + - sphinx>=7.1.2,<7.2 ; extra == 'doc' + - sphinx-rtd-theme ; extra == 'doc' + - sphinx-autodoc-typehints ; extra == 'doc' + requires_python: '>=3.7' +- pypi: https://files.pythonhosted.org/packages/6d/10/b37ac718c5903758fa9058a5182026a4f3b65443196b82c7840389ea0dbd/lbplatformutils-4.6.1-py3-none-any.whl + name: lbplatformutils + version: 4.6.1 + sha256: 92e6dd273e77873ba6cbd302c8b29fde71e5dbb7706f05856e362fb44fd9eee8 + requires_python: '>=3.7,<4.0' +- pypi: https://files.pythonhosted.org/packages/6f/01/c26ce75ba460d5cd503da9e13b21a33804d38c2165dec7b716d06b13010c/pyjwt-2.11.0-py3-none-any.whl + name: pyjwt + version: 2.11.0 + sha256: 94a6bde30eb5c8e04fee991062b534071fd1439ef58d2adc9ccb823e7bcd0469 + requires_dist: + - cryptography>=3.4.0 ; extra == 'crypto' + - coverage[toml]==7.10.7 ; extra == 'dev' + - cryptography>=3.4.0 ; extra == 'dev' + - pre-commit ; extra == 'dev' + - pytest>=8.4.2,<9.0.0 ; extra == 'dev' + - sphinx ; extra == 'dev' + - sphinx-rtd-theme ; extra == 'dev' + - zope-interface ; extra == 'dev' + - sphinx ; extra == 'docs' + - sphinx-rtd-theme ; extra == 'docs' + - zope-interface ; extra == 'docs' + - coverage[toml]==7.10.7 ; extra == 'tests' + - pytest>=8.4.2,<9.0.0 ; extra == 'tests' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/70/98/d82f14ac7ffedbd38dfa2383f142b26d18d23ca6cf35a40f4af60df666bd/sh-2.2.2-py3-none-any.whl + name: sh + version: 2.2.2 + sha256: e0b15b4ae8ffcd399bc8ffddcbd770a43c7a70a24b16773fbb34c001ad5d52af + requires_python: '>=3.8.1,<4.0' +- pypi: https://files.pythonhosted.org/packages/71/3f/212e32937253312e102e152c954a5495df0379255719ce28e0288194748d/schema_salad-8.9.20251102115403-cp314-cp314-macosx_11_0_arm64.whl + name: schema-salad + version: 8.9.20251102115403 + sha256: 38c5faa34f7f70641ea4984f65aab062cc78c8f4528e3f2c092fa81503fc937d + requires_dist: + - requests>=1.0 + - ruamel-yaml>=0.17.6,<0.19 + - rdflib>=4.2.2,<8.0.0 + - mistune>=3,<3.2 + - cachecontrol[filecache]>=0.13.1,<0.15 + - mypy-extensions + - sphinx>=2.2 ; extra == 'docs' + - sphinx-rtd-theme>=1 ; extra == 'docs' + - pytest<9 ; extra == 'docs' + - sphinx-autoapi ; extra == 'docs' + - sphinx-autodoc-typehints ; extra == 'docs' + - sphinxcontrib-autoprogram ; extra == 'docs' + - black ; extra == 'pycodegen' + requires_python: '>=3.9,<3.15' +- pypi: https://files.pythonhosted.org/packages/73/90/a2c51050d9254bd9134e6368b3f94f92f0eb2c34ed0ca19ec449ce2fc288/fsspec_xrootd-0.5.2-py3-none-any.whl + name: fsspec-xrootd + version: 0.5.2 + sha256: 314763b6f31c01358ffe1fb1dca038085690efbee80ac5f5204f66d0ae9fd417 + requires_dist: + - fsspec + - pytest>=6 ; extra == 'dev' + - sphinx>=4.0 ; extra == 'docs' + - myst-parser>=0.13 ; extra == 'docs' + - sphinx-book-theme>=0.1.0 ; extra == 'docs' + - sphinx-copybutton ; extra == 'docs' + - pytest>=6 ; extra == 'test' + - pytest-rerunfailures ; extra == 'test' + - pytest-timeout ; extra == 'test' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/74/1a/145646e5687e8d9a1e8d09acb278c8535ebe9e972e1f162ed338a622f193/pydantic_core-2.41.5-cp314-cp314-macosx_11_0_arm64.whl + name: pydantic-core + version: 2.41.5 + sha256: 1d1d9764366c73f996edd17abb6d9d7649a7eb690006ab6adbda117717099b14 + requires_dist: + - typing-extensions>=4.14.1 + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/74/f5/9373290775639cb67a2fce7f629a1c240dce9f12fe927bc32b2736e16dfc/argcomplete-3.6.3-py3-none-any.whl + name: argcomplete + version: 3.6.3 + sha256: f5007b3a600ccac5d25bbce33089211dfd49eab4a7718da3f10e3082525a92ce + requires_dist: + - coverage ; extra == 'test' + - mypy ; extra == 'test' + - pexpect ; extra == 'test' + - ruff ; extra == 'test' + - wheel ; extra == 'test' + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/76/2c/bb6ef359e007fe7b6b3195b68a94f4dd3ecd1885ee337ee8fbd4df55996f/levenshtein-0.27.3-cp314-cp314-macosx_11_0_arm64.whl + name: levenshtein + version: 0.27.3 + sha256: 8e5037c4a6f97a238e24aad6f98a1e984348b7931b1b04b6bd02bd4f8238150d + requires_dist: + - rapidfuzz>=3.9.0,<4.0.0 + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/76/3e/c0b690253f0b82d86e99949af13533363acfb5432ecb5d53dd5b3bce9c34/orjson-3.11.9-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl + name: orjson + version: 3.11.9 + sha256: aaea64f3f467d22e70eeed68bdccb3bc4f83f650446c4a03c59f2cba28a108db + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/77/39/4d8414260c3d83f22029a39e51553c173611b378d62ca391e5ca68e65cfa/awkward-2.9.0-py3-none-any.whl + name: awkward + version: 2.9.0 + sha256: 4859e371c606ca7fe737546f302de08110d53ed986cdd1254fb059dd48912db6 + requires_dist: + - awkward-cpp==52 + - fsspec>=2022.11.0 + - importlib-metadata>=4.13.0 ; python_full_version < '3.12' + - numpy>=1.21.3 + - packaging + - typing-extensions>=4.1.0 ; python_full_version < '3.11' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl + name: annotated-types + version: 0.7.0 + sha256: 1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53 + requires_dist: + - typing-extensions>=4.0.0 ; python_full_version < '3.9' + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/7a/f0/8282d9641415e9e33df173516226b404d367a0fc55e1a60424a152913abc/mistune-3.1.4-py3-none-any.whl + name: mistune + version: 3.1.4 + sha256: 93691da911e5d9d2e23bc54472892aff676df27a75274962ff9edc210364266d + requires_dist: + - typing-extensions ; python_full_version < '3.11' + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/7e/32/a7125fb28c4261a627f999d5fb4afff25b523800faed2c30979949d6facd/pydot-4.0.1-py3-none-any.whl + name: pydot + version: 4.0.1 + sha256: 869c0efadd2708c0be1f916eb669f3d664ca684bc57ffb7ecc08e70d5e93fee6 + requires_dist: + - pyparsing>=3.1.0 + - ruff ; extra == 'lint' + - mypy ; extra == 'types' + - pydot[lint] ; extra == 'dev' + - pydot[types] ; extra == 'dev' + - chardet ; extra == 'dev' + - parameterized ; extra == 'dev' + - pydot[dev] ; extra == 'tests' + - tox ; extra == 'tests' + - pytest ; extra == 'tests' + - pytest-cov ; extra == 'tests' + - pytest-xdist[psutil] ; extra == 'tests' + - zest-releaser[recommended] ; extra == 'release' + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/7e/5e/0138bc4484ea9b897864d59fce9be9086030825bc778b76cb5a33a906d37/xxhash-3.6.0-cp314-cp314-macosx_10_13_x86_64.whl + name: xxhash + version: 3.6.0 + sha256: a40a3d35b204b7cc7643cbcf8c9976d818cb47befcfac8bbefec8038ac363f3e + requires_python: '>=3.7' +- pypi: https://files.pythonhosted.org/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl + name: httpcore + version: 1.0.9 + sha256: 2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55 + requires_dist: + - certifi + - h11>=0.16 + - anyio>=4.0,<5.0 ; extra == 'asyncio' + - h2>=3,<5 ; extra == 'http2' + - socksio==1.* ; extra == 'socks' + - trio>=0.22.0,<1.0 ; extra == 'trio' + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/7f/37/8ea3555769b6048b5e4ec162cc90fd32e761c0e381ffb3baf888cb0d8a71/lhcbdiracx_api-0.0.8-py3-none-any.whl + name: lhcbdiracx-api + version: 0.0.8 + sha256: 13337f9b98b0907e372e014ee1012d99c7d1f1d8e3877daf96d73b165ca10aca + requires_dist: + - lhcbdiracx-core + - lhcbdiracx-client + - diracx-api==0.0.8 + - diracx-api[types]==0.0.8 ; extra == 'types' + - diracx-api[testing]==0.0.8 ; extra == 'testing' + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/80/38/9d42d60dffb04b45f03dbab9430898352dba277758640751dc5cc316c521/greenlet-3.3.1-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl + name: greenlet + version: 3.3.1 + sha256: 34a729e2e4e4ffe9ae2408d5ecaf12f944853f40ad724929b7585bca808a9d6f + requires_dist: + - sphinx ; extra == 'docs' + - furo ; extra == 'docs' + - objgraph ; extra == 'test' + - psutil ; extra == 'test' + - setuptools ; extra == 'test' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/81/41/aa3ffb3355e62e1bf91f6599b3092e866bc88487a07c524004943c7676df/rapidfuzz-3.14.5-cp314-cp314-macosx_10_15_x86_64.whl + name: rapidfuzz + version: 3.14.5 + sha256: 1a31cc6d7d03e7318a0974c038959c59e19c752b81115f2e9138b3331cd64d45 + requires_dist: + - numpy ; extra == 'all' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/81/c4/34e93fe5f5429d7570ec1fa436f1986fb1f00c3e0f43a589fe2bbcd22c3f/pytz-2025.2-py2.py3-none-any.whl + name: pytz + version: '2025.2' + sha256: 5ddf76296dd8c44c26eb8f4b6f35488f3ccbf6fbbd7adee0b7262d43f0ec2f00 +- pypi: https://files.pythonhosted.org/packages/84/03/0d3ce49e2505ae70cf43bc5bb3033955d2fc9f932163e84dc0779cc47f48/prompt_toolkit-3.0.52-py3-none-any.whl + name: prompt-toolkit + version: 3.0.52 + sha256: 9aac639a3bbd33284347de5ad8d68ecc044b91a762dc39b7c21095fcd6a19955 + requires_dist: + - wcwidth + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/84/d0/205d54408c08b13550c733c4b85429e7ead111c7f0014309637425520a9a/deprecated-1.3.1-py2.py3-none-any.whl + name: deprecated + version: 1.3.1 + sha256: 597bfef186b6f60181535a29fbe44865ce137a5079f295b479886c82729d5f3f + requires_dist: + - wrapt>=1.10,<3 + - inspect2 ; python_full_version < '3' + - tox ; extra == 'dev' + - pytest ; extra == 'dev' + - pytest-cov ; extra == 'dev' + - bump2version<1 ; extra == 'dev' + - setuptools ; python_full_version >= '3.12' and extra == 'dev' + requires_python: '>=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*' +- pypi: https://files.pythonhosted.org/packages/87/a4/afc9dddc6b14fb3d52a900cd9b4c77770128edc4b07e576034bbd0ffd290/LbCondaWrappers-0.5.2-py3-none-any.whl + name: lbcondawrappers + version: 0.5.2 + sha256: 4200c89661017bc28b910aa040092970c357f4130375d84ec14a258adf8318e0 + requires_dist: + - lb-telemetry>=0.5.0 + - pytest ; extra == 'testing' + - pytest-cov ; extra == 'testing' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/89/d4/24a137517140fc8cc07f7423695b9296c993d6b6cbf2a7867d8f859de77f/schema_salad-8.9.20251102115403-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + name: schema-salad + version: 8.9.20251102115403 + sha256: d7f9dcdafe3ca64f28a1ee219434bc1297801c9435b7431817e435e782f1c1db + requires_dist: + - requests>=1.0 + - ruamel-yaml>=0.17.6,<0.19 + - rdflib>=4.2.2,<8.0.0 + - mistune>=3,<3.2 + - cachecontrol[filecache]>=0.13.1,<0.15 + - mypy-extensions + - sphinx>=2.2 ; extra == 'docs' + - sphinx-rtd-theme>=1 ; extra == 'docs' + - pytest<9 ; extra == 'docs' + - sphinx-autoapi ; extra == 'docs' + - sphinx-autodoc-typehints ; extra == 'docs' + - sphinxcontrib-autoprogram ; extra == 'docs' + - black ; extra == 'pycodegen' + requires_python: '>=3.9,<3.15' +- pypi: https://files.pythonhosted.org/packages/8d/09/d0a2a14fc3439c5f874042dca72a79c70a532090b7ba0003be73fee37ae2/zstandard-0.25.0-cp314-cp314-macosx_11_0_arm64.whl + name: zstandard + version: 0.25.0 + sha256: 05df5136bc5a011f33cd25bc9f506e7426c0c9b3f9954f056831ce68f3b6689f + requires_dist: + - cffi~=1.17 ; python_full_version < '3.14' and platform_python_implementation != 'PyPy' and extra == 'cffi' + - cffi>=2.0.0b0 ; python_full_version >= '3.14' and platform_python_implementation != 'PyPy' and extra == 'cffi' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/8d/99/157aae7949a5f30d51fcb1a9851e8ebd5c74bf99b5285d8bb4b8b9ee641e/cryptography-46.0.4-cp311-abi3-macosx_10_9_universal2.whl + name: cryptography + version: 46.0.4 + sha256: 281526e865ed4166009e235afadf3a4c4cba6056f99336a99efba65336fd5485 + requires_dist: + - cffi>=1.14 ; python_full_version == '3.8.*' and platform_python_implementation != 'PyPy' + - cffi>=2.0.0 ; python_full_version >= '3.9' and platform_python_implementation != 'PyPy' + - typing-extensions>=4.13.2 ; python_full_version < '3.11' + - bcrypt>=3.1.5 ; extra == 'ssh' + - nox[uv]>=2024.4.15 ; extra == 'nox' + - cryptography-vectors==46.0.4 ; extra == 'test' + - pytest>=7.4.0 ; extra == 'test' + - pytest-benchmark>=4.0 ; extra == 'test' + - pytest-cov>=2.10.1 ; extra == 'test' + - pytest-xdist>=3.5.0 ; extra == 'test' + - pretend>=0.7 ; extra == 'test' + - certifi>=2024 ; extra == 'test' + - pytest-randomly ; extra == 'test-randomorder' + - sphinx>=5.3.0 ; extra == 'docs' + - sphinx-rtd-theme>=3.0.0 ; extra == 'docs' + - sphinx-inline-tabs ; extra == 'docs' + - pyenchant>=3 ; extra == 'docstest' + - readme-renderer>=30.0 ; extra == 'docstest' + - sphinxcontrib-spelling>=7.3.1 ; extra == 'docstest' + - build>=1.0.0 ; extra == 'sdist' + - ruff>=0.11.11 ; extra == 'pep8test' + - mypy>=1.14 ; extra == 'pep8test' + - check-sdist ; extra == 'pep8test' + - click>=8.0.1 ; extra == 'pep8test' + requires_python: '>=3.8,!=3.9.0,!=3.9.1' +- pypi: https://files.pythonhosted.org/packages/8e/e8/a1185e236ec66c20afd72399522f142c3724c785789255202d27ae992818/frozenlist-1.8.0-cp314-cp314-macosx_10_13_x86_64.whl + name: frozenlist + version: 1.8.0 + sha256: 119fb2a1bd47307e899c2fac7f28e85b9a543864df47aa7ec9d3c1b4545f096f + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/8e/eb/5da01e356015aee6ecfa1187ced87aef51364e306f5e695dd52719bf0e78/orjson-3.11.9-cp314-cp314-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl + name: orjson + version: 3.11.9 + sha256: b6ef1979adc4bc243523f1a2ba91418030a8e29b0a99cbe7e0e2d6807d4dce6e + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/8e/fb/2c4c618185be2bda327f9dacd16b3122cc938809f19df7be840595d0e584/prov-1.5.1-py2.py3-none-any.whl + name: prov + version: 1.5.1 + sha256: 5c930cbbd05424aa3066d336dc31d314dd9fa0280caeab064288e592ed716bea + requires_dist: + - lxml + - networkx + - python-dateutil + - rdflib>=4.2.1 + - six>=1.9.0 + - pydot>=1.2.0 ; extra == 'dot' +- pypi: https://files.pythonhosted.org/packages/94/54/e7d793b573f298e1c9013b8c4dade17d481164aa517d1d7148619c2cedbf/markdown_it_py-4.0.0-py3-none-any.whl + name: markdown-it-py + version: 4.0.0 + sha256: 87327c59b172c5011896038353a81343b6754500a08cd7a4973bb48c6d578147 + requires_dist: + - mdurl~=0.1 + - psutil ; extra == 'benchmarking' + - pytest ; extra == 'benchmarking' + - pytest-benchmark ; extra == 'benchmarking' + - commonmark~=0.9 ; extra == 'compare' + - markdown~=3.4 ; extra == 'compare' + - mistletoe~=1.0 ; extra == 'compare' + - mistune~=3.0 ; extra == 'compare' + - panflute~=2.3 ; extra == 'compare' + - markdown-it-pyrs ; extra == 'compare' + - linkify-it-py>=1,<3 ; extra == 'linkify' + - mdit-py-plugins>=0.5.0 ; extra == 'plugins' + - gprof2dot ; extra == 'profiling' + - mdit-py-plugins>=0.5.0 ; extra == 'rtd' + - myst-parser ; extra == 'rtd' + - pyyaml ; extra == 'rtd' + - sphinx ; extra == 'rtd' + - sphinx-copybutton ; extra == 'rtd' + - sphinx-design ; extra == 'rtd' + - sphinx-book-theme~=1.0 ; extra == 'rtd' + - jupyter-sphinx ; extra == 'rtd' + - ipykernel ; extra == 'rtd' + - coverage ; extra == 'testing' + - pytest ; extra == 'testing' + - pytest-cov ; extra == 'testing' + - pytest-regressions ; extra == 'testing' + - requests ; extra == 'testing' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/95/25/bdb9326c3b5455f8d4d3549fce7abcf967259de146fe2cf7a82368141948/pandas-3.0.2-cp314-cp314-macosx_11_0_arm64.whl + name: pandas + version: 3.0.2 + sha256: 0555c5882688a39317179ab4a0ed41d3ebc8812ab14c69364bbee8fb7a3f6288 + requires_dist: + - numpy>=1.26.0 ; python_full_version < '3.14' + - numpy>=2.3.3 ; python_full_version >= '3.14' + - python-dateutil>=2.8.2 + - tzdata ; sys_platform == 'win32' + - tzdata ; sys_platform == 'emscripten' + - hypothesis>=6.116.0 ; extra == 'test' + - pytest>=8.3.4 ; extra == 'test' + - pytest-xdist>=3.6.1 ; extra == 'test' + - pyarrow>=13.0.0 ; extra == 'pyarrow' + - bottleneck>=1.4.2 ; extra == 'performance' + - numba>=0.60.0 ; extra == 'performance' + - numexpr>=2.10.2 ; extra == 'performance' + - scipy>=1.14.1 ; extra == 'computation' + - xarray>=2024.10.0 ; extra == 'computation' + - fsspec>=2024.10.0 ; extra == 'fss' + - s3fs>=2024.10.0 ; extra == 'aws' + - gcsfs>=2024.10.0 ; extra == 'gcp' + - odfpy>=1.4.1 ; extra == 'excel' + - openpyxl>=3.1.5 ; extra == 'excel' + - python-calamine>=0.3.0 ; extra == 'excel' + - pyxlsb>=1.0.10 ; extra == 'excel' + - xlrd>=2.0.1 ; extra == 'excel' + - xlsxwriter>=3.2.0 ; extra == 'excel' + - pyarrow>=13.0.0 ; extra == 'parquet' + - pyarrow>=13.0.0 ; extra == 'feather' + - pyiceberg>=0.8.1 ; extra == 'iceberg' + - tables>=3.10.1 ; extra == 'hdf5' + - pyreadstat>=1.2.8 ; extra == 'spss' + - sqlalchemy>=2.0.36 ; extra == 'postgresql' + - psycopg2>=2.9.10 ; extra == 'postgresql' + - adbc-driver-postgresql>=1.2.0 ; extra == 'postgresql' + - sqlalchemy>=2.0.36 ; extra == 'mysql' + - pymysql>=1.1.1 ; extra == 'mysql' + - sqlalchemy>=2.0.36 ; extra == 'sql-other' + - adbc-driver-postgresql>=1.2.0 ; extra == 'sql-other' + - adbc-driver-sqlite>=1.2.0 ; extra == 'sql-other' + - beautifulsoup4>=4.12.3 ; extra == 'html' + - html5lib>=1.1 ; extra == 'html' + - lxml>=5.3.0 ; extra == 'html' + - lxml>=5.3.0 ; extra == 'xml' + - matplotlib>=3.9.3 ; extra == 'plot' + - jinja2>=3.1.5 ; extra == 'output-formatting' + - tabulate>=0.9.0 ; extra == 'output-formatting' + - pyqt5>=5.15.9 ; extra == 'clipboard' + - qtpy>=2.4.2 ; extra == 'clipboard' + - zstandard>=0.23.0 ; extra == 'compression' + - pytz>=2024.2 ; extra == 'timezone' + - adbc-driver-postgresql>=1.2.0 ; extra == 'all' + - adbc-driver-sqlite>=1.2.0 ; extra == 'all' + - beautifulsoup4>=4.12.3 ; extra == 'all' + - bottleneck>=1.4.2 ; extra == 'all' + - fastparquet>=2024.11.0 ; extra == 'all' + - fsspec>=2024.10.0 ; extra == 'all' + - gcsfs>=2024.10.0 ; extra == 'all' + - html5lib>=1.1 ; extra == 'all' + - hypothesis>=6.116.0 ; extra == 'all' + - jinja2>=3.1.5 ; extra == 'all' + - lxml>=5.3.0 ; extra == 'all' + - matplotlib>=3.9.3 ; extra == 'all' + - numba>=0.60.0 ; extra == 'all' + - numexpr>=2.10.2 ; extra == 'all' + - odfpy>=1.4.1 ; extra == 'all' + - openpyxl>=3.1.5 ; extra == 'all' + - psycopg2>=2.9.10 ; extra == 'all' + - pyarrow>=13.0.0 ; extra == 'all' + - pyiceberg>=0.8.1 ; extra == 'all' + - pymysql>=1.1.1 ; extra == 'all' + - pyqt5>=5.15.9 ; extra == 'all' + - pyreadstat>=1.2.8 ; extra == 'all' + - pytest>=8.3.4 ; extra == 'all' + - pytest-xdist>=3.6.1 ; extra == 'all' + - python-calamine>=0.3.0 ; extra == 'all' + - pytz>=2024.2 ; extra == 'all' + - pyxlsb>=1.0.10 ; extra == 'all' + - qtpy>=2.4.2 ; extra == 'all' + - scipy>=1.14.1 ; extra == 'all' + - s3fs>=2024.10.0 ; extra == 'all' + - sqlalchemy>=2.0.36 ; extra == 'all' + - tables>=3.10.1 ; extra == 'all' + - tabulate>=0.9.0 ; extra == 'all' + - xarray>=2024.10.0 ; extra == 'all' + - xlrd>=2.0.1 ; extra == 'all' + - xlsxwriter>=3.2.0 ; extra == 'all' + - zstandard>=0.23.0 ; extra == 'all' + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/95/a0/1c2396e272f91efe6b16a6a8bce7ad53856c8f9ae4f34ceaa711d63ec9e1/wrapt-2.1.1-cp314-cp314-macosx_10_15_x86_64.whl + name: wrapt + version: 2.1.1 + sha256: 9aa1765054245bb01a37f615503290d4e207e3fd59226e78341afb587e9c1236 + requires_dist: + - pytest ; extra == 'dev' + - setuptools ; extra == 'dev' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/98/78/01c019cdb5d6498122777c1a43056ebb3ebfeef2076d9d026bfe15583b2b/click-8.3.1-py3-none-any.whl + name: click + version: 8.3.1 + sha256: 981153a64e25f12d547d3426c367a4857371575ee7ad18df2a6183ab0545b2a6 + requires_dist: + - colorama ; sys_platform == 'win32' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/9a/02/0e550c9606ffae81603a9d240369a93cdf1e4bc48e2e314d367825a1c02d/awkward_cpp-52-cp314-cp314-macosx_10_15_x86_64.whl + name: awkward-cpp + version: '52' + sha256: d792c969c5261d8141c0b817a6a541849355b0fafe49e6e63a542a501cc0b73a + requires_dist: + - numpy>=1.21.3 + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/9d/0a/03192e78071cfb86e6d8ceae0e5dcec4bacf0fd734755263aabd01532e50/xattr-1.3.0-cp314-cp314-macosx_10_15_x86_64.whl + name: xattr + version: 1.3.0 + sha256: 95f1e14a4d9ca160b4b78c527bf2bac6addbeb0fd9882c405fc0b5e3073a8752 + requires_dist: + - cffi>=1.16.0 + - pytest ; extra == 'test' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/9e/c3/059298687310d527a58bb01f3b1965787ee3b40dce76752eda8b44e9a2c5/pexpect-4.9.0-py2.py3-none-any.whl + name: pexpect + version: 4.9.0 + sha256: 7236d1e080e4936be2dc3e326cec0af72acf9212a7e1d060210e70a47e253523 + requires_dist: + - ptyprocess>=0.5 +- pypi: https://files.pythonhosted.org/packages/9e/c9/b2622292ea83fbb4ec318f5b9ab867d0a28ab43c5717bb85b0a5f6b3b0a4/networkx-3.6.1-py3-none-any.whl + name: networkx + version: 3.6.1 + sha256: d47fbf302e7d9cbbb9e2555a0d267983d2aa476bac30e90dfbe5669bd57f3762 + requires_dist: + - asv ; extra == 'benchmarking' + - virtualenv ; extra == 'benchmarking' + - numpy>=1.25 ; extra == 'default' + - scipy>=1.11.2 ; extra == 'default' + - matplotlib>=3.8 ; extra == 'default' + - pandas>=2.0 ; extra == 'default' + - pre-commit>=4.1 ; extra == 'developer' + - mypy>=1.15 ; extra == 'developer' + - sphinx>=8.0 ; extra == 'doc' + - pydata-sphinx-theme>=0.16 ; extra == 'doc' + - sphinx-gallery>=0.18 ; extra == 'doc' + - numpydoc>=1.8.0 ; extra == 'doc' + - pillow>=10 ; extra == 'doc' + - texext>=0.6.7 ; extra == 'doc' + - myst-nb>=1.1 ; extra == 'doc' + - intersphinx-registry ; extra == 'doc' + - osmnx>=2.0.0 ; extra == 'example' + - momepy>=0.7.2 ; extra == 'example' + - contextily>=1.6 ; extra == 'example' + - seaborn>=0.13 ; extra == 'example' + - cairocffi>=1.7 ; extra == 'example' + - igraph>=0.11 ; extra == 'example' + - scikit-learn>=1.5 ; extra == 'example' + - iplotx>=0.9.0 ; extra == 'example' + - lxml>=4.6 ; extra == 'extra' + - pygraphviz>=1.14 ; extra == 'extra' + - pydot>=3.0.1 ; extra == 'extra' + - sympy>=1.10 ; extra == 'extra' + - build>=0.10 ; extra == 'release' + - twine>=4.0 ; extra == 'release' + - wheel>=0.40 ; extra == 'release' + - changelist==0.5 ; extra == 'release' + - pytest>=7.2 ; extra == 'test' + - pytest-cov>=4.0 ; extra == 'test' + - pytest-xdist>=3.0 ; extra == 'test' + - pytest-mpl ; extra == 'test-extras' + - pytest-randomly ; extra == 'test-extras' + requires_python: '>=3.11,!=3.14.1' +- pypi: https://files.pythonhosted.org/packages/9f/90/279f55fff9481f9e0424c3c97b24dc10004ec8d8f98ddf5afd07a7b79194/diraccfg-1.0.1-py2.py3-none-any.whl + name: diraccfg + version: 1.0.1 + sha256: 5103e25208fd41c623a72ddd5775416633f97b376531c86fb4e79282871db218 + requires_dist: + - pytest>=4.6 ; extra == 'testing' + - pytest-cov ; extra == 'testing' + - pylint>=1.6.5 ; extra == 'testing' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/a0/1d/d9257dd49ff2ca23ea5f132edf1281a0c4f9de8a762b9ae399b670a59235/typer-0.21.1-py3-none-any.whl + name: typer + version: 0.21.1 + sha256: 7985e89081c636b88d172c2ee0cfe33c253160994d47bdfdc302defd7d1f1d01 + requires_dist: + - click>=8.0.0 + - typing-extensions>=3.7.4.3 + - shellingham>=1.3.0 + - rich>=10.11.0 + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/a0/61/5c78b91c3143ed5c14207f463aecfc8f9dbb5092fb2869baf37c273b2705/gitdb-4.0.12-py3-none-any.whl + name: gitdb + version: 4.0.12 + sha256: 67073e15955400952c6565cc3e707c554a4eea2e428946f7a4c162fab9bd9bcf + requires_dist: + - smmap>=3.0.1,<6 + requires_python: '>=3.7' +- pypi: https://files.pythonhosted.org/packages/a1/01/9674cc6d478406ae61d910cb16ca8b5699a8a9e6a2019987ebe5a5957d1d/joserfc-1.6.1-py3-none-any.whl + name: joserfc + version: 1.6.1 + sha256: 74d158c9d56be54c710cdcb2a0741372254b682ad2101a0f72e5bd0e925695f0 + requires_dist: + - cryptography>=45.0.1 + - pycryptodome ; extra == 'drafts' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/a1/5c/8b56b08db91e569d0a4fbfa3e492ed2026081bdd7e892f63ba1c88a2f548/ruamel_yaml_clib-0.2.15-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + name: ruamel-yaml-clib + version: 0.2.15 + sha256: 2812ff359ec1f30129b62372e5f22a52936fac13d5d21e70373dbca5d64bb97c + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/a1/93/72b1736d68f03fda5fdf0f2180fb6caaae3894f1b854d006ac61ecc727ee/frozenlist-1.8.0-cp314-cp314-macosx_11_0_arm64.whl + name: frozenlist + version: 1.8.0 + sha256: 4970ece02dbc8c3a92fcc5228e36a3e933a01a999f7094ff7c23fbd2beeaa67c + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/a4/ed/1f1afb2e9e7f38a545d628f864d562a5ae64fe6f7a10e28ffb9b185b4e89/importlib_resources-6.5.2-py3-none-any.whl + name: importlib-resources + version: 6.5.2 + sha256: 789cfdc3ed28c78b67a06acb8126751ced69a3d5f79c095a98298cd8a760ccec + requires_dist: + - zipp>=3.1.0 ; python_full_version < '3.10' + - pytest>=6,!=8.1.* ; extra == 'test' + - zipp>=3.17 ; extra == 'test' + - jaraco-test>=5.4 ; extra == 'test' + - sphinx>=3.5 ; extra == 'doc' + - jaraco-packaging>=9.3 ; extra == 'doc' + - rst-linker>=1.9 ; extra == 'doc' + - furo ; extra == 'doc' + - sphinx-lint ; extra == 'doc' + - jaraco-tidelift>=1.4 ; extra == 'doc' + - pytest-checkdocs>=2.4 ; extra == 'check' + - pytest-ruff>=0.2.1 ; sys_platform != 'cygwin' and extra == 'check' + - pytest-cov ; extra == 'cover' + - pytest-enabler>=2.2 ; extra == 'enabler' + - pytest-mypy ; extra == 'type' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/a7/06/3d6badcf13db419e25b07041d9c7b4a2c331d3f4e7134445ec5df57714cd/coloredlogs-15.0.1-py2.py3-none-any.whl + name: coloredlogs + version: 15.0.1 + sha256: 612ee75c546f53e92e70049c9dbfcc18c935a2b9a53b66085ce9ef6a6e5c0934 + requires_dist: + - humanfriendly>=9.1 + - capturer>=2.4 ; extra == 'cron' + requires_python: '>=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*' +- pypi: https://files.pythonhosted.org/packages/a7/b2/fabede9fafd976b991e9f1b9c8c873ed86f202889b864756f240ce6dd855/frozenlist-1.8.0-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl + name: frozenlist + version: 1.8.0 + sha256: cba69cb73723c3f329622e34bdbf5ce1f80c21c290ff04256cff1cd3c2036ed2 + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/a9/90/a744336f5af32c433bd09af7854599682a383b37cfd78f7de263de6ad6cb/paramiko-4.0.0-py3-none-any.whl + name: paramiko + version: 4.0.0 + sha256: 0e20e00ac666503bf0b4eda3b6d833465a2b7aff2e2b3d79a8bba5ef144ee3b9 + requires_dist: + - bcrypt>=3.2 + - cryptography>=3.3 + - invoke>=2.0 + - pynacl>=1.5 + - pyasn1>=0.1.7 ; extra == 'gssapi' + - gssapi>=1.4.1 ; sys_platform != 'win32' and extra == 'gssapi' + - pywin32>=2.1.8 ; sys_platform == 'win32' and extra == 'gssapi' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/ab/7e/5f02b757bb825e5cdc65f6f7a12c209963bec877d61497393bea8f41f9ce/diracx_api-0.0.8-py3-none-any.whl + name: diracx-api + version: 0.0.8 + sha256: 73343b5cebadf17ab511a3dfb47492f1fc2b8aca0d3fe1b3c4808d5595e9ce7d + requires_dist: + - diracx-client + - diracx-core + - httpx + - zstandard + - diracx-testing ; extra == 'testing' + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/ae/fb/011c7c717213182caf78084a9bea51c8590b0afda98001f69d9f853a495b/greenlet-3.3.1-cp314-cp314-macosx_11_0_universal2.whl + name: greenlet + version: 3.3.1 + sha256: bd59acd8529b372775cd0fcbc5f420ae20681c5b045ce25bd453ed8455ab99b5 + requires_dist: + - sphinx ; extra == 'docs' + - furo ; extra == 'docs' + - objgraph ; extra == 'test' + - psutil ; extra == 'test' + - setuptools ; extra == 'test' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/af/fe/b6045c782f1fd1ae317d2a6ca1884857ce5c20f59befe6ab25a8603c43a7/ruamel_yaml-0.18.17-py3-none-any.whl + name: ruamel-yaml + version: 0.18.17 + sha256: 9c8ba9eb3e793efdf924b60d521820869d5bf0cb9c6f1b82d82de8295e290b9d + requires_dist: + - ruamel-yaml-clib>=0.2.15 ; python_full_version < '3.15' and platform_python_implementation == 'CPython' + - ruamel-yaml-jinja2>=0.2 ; extra == 'jinja2' + - ryd ; extra == 'docs' + - mercurial>5.7 ; extra == 'docs' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/b0/28/87e78ff0d6041f40431d88b8aa3b645be7476a420d8dcbf7197f5b394c5c/diracx_cli-0.0.8-py3-none-any.whl + name: diracx-cli + version: 0.0.8 + sha256: 3c38d3913e99922a0d9d8692a6d154bbdf98c63bb4411609bf5a65881b157e10 + requires_dist: + - diraccfg + - diracx-api + - diracx-client + - diracx-core + - gitpython + - pydantic>=2.10 + - pyyaml + - rich + - typer>=0.15.4 + - diracx-testing ; extra == 'testing' + - types-pyyaml ; extra == 'types' + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/b0/57/dea471da24ceac6de8c3dc5d37e4ddde57a5c340d6bac90010898734de34/gitlint_core-0.19.1-py3-none-any.whl + name: gitlint-core + version: 0.19.1 + sha256: f41effd1dcbc06ffbfc56b6888cce72241796f517b46bd9fd4ab1b145056988c + requires_dist: + - arrow>=1 + - click>=8 + - importlib-metadata>=1.0 ; python_full_version < '3.8' + - sh>=1.13.0 ; sys_platform != 'win32' + - arrow==1.2.3 ; extra == 'trusted-deps' + - click==8.1.3 ; extra == 'trusted-deps' + - sh==1.14.3 ; sys_platform != 'win32' and extra == 'trusted-deps' + requires_python: '>=3.7' +- pypi: https://files.pythonhosted.org/packages/b0/9a/d2faba7e61072a7507b5722db63562fdb22f5a24e237d460d18755627f15/wrapt-2.1.1-cp314-cp314-macosx_11_0_arm64.whl + name: wrapt + version: 2.1.1 + sha256: feff14b63a6d86c1eee33a57f77573649f2550935981625be7ff3cb7342efe05 + requires_dist: + - pytest ; extra == 'dev' + - setuptools ; extra == 'dev' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/b2/c9/459da97eb93fad89738951972671d44be197610242b8da88a0384791ea7e/diracx_core-0.0.8-py3-none-any.whl + name: diracx-core + version: 0.0.8 + sha256: caed9a107a1ee93a4c5a44e1e2ca753acefbacdb44a46e22907d7ef839e3bdf8 + requires_dist: + - aiobotocore>=2.15 + - botocore>=1.35 + - cachetools + - diraccommon>=9.0.0 + - email-validator + - gitpython + - joserfc>=1.1.0 + - pydantic-settings + - pydantic>=2.10 + - pyyaml + - sh + - diracx-testing ; extra == 'testing' + - moto[server] ; extra == 'testing' + - botocore-stubs ; extra == 'types' + - types-aiobotocore-s3 ; extra == 'types' + - types-aiobotocore[essential] ; extra == 'types' + - types-cachetools ; extra == 'types' + - types-pyyaml ; extra == 'types' + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/b2/f2/889ad4b2408f72fe1a4f6a19491177b30ea7bf1a0fd5f17050ca08cfc882/propcache-0.4.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + name: propcache + version: 0.4.1 + sha256: 8326e144341460402713f91df60ade3c999d601e7eb5ff8f6f7862d54de0610d + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/b2/fa/89a8ef0468d5833a23fff277b143d0573897cf75bd56670a6d28126c7d68/propcache-0.4.1-cp314-cp314-macosx_11_0_arm64.whl + name: propcache + version: 0.4.1 + sha256: 9f302f4783709a78240ebc311b793f123328716a60911d667e0c036bc5dcbded + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl + name: mdurl + version: 0.1.2 + sha256: 84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8 + requires_python: '>=3.7' +- pypi: https://files.pythonhosted.org/packages/b3/68/aa714515d65090fcbcc9a1f3debd5a644b14aad11e59238f42f00bd4b298/logzero-1.7.0-py2.py3-none-any.whl + name: logzero + version: 1.7.0 + sha256: 23eb1f717a2736f9ab91ca0d43160fd2c996ad49ae6bad34652d47aba908769d + requires_dist: + - colorama ; sys_platform == 'win32' +- pypi: https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl + name: six + version: 1.17.0 + sha256: 4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274 + requires_python: '>=2.7,!=3.0.*,!=3.1.*,!=3.2.*' +- pypi: https://files.pythonhosted.org/packages/b9/20/35d2baebacf357b562bd081936b66cd845775442973cb033a377fd639a84/rdflib-7.5.0-py3-none-any.whl + name: rdflib + version: 7.5.0 + sha256: b011dfc40d0fc8a44252e906dcd8fc806a7859bc231be190c37e9568a31ac572 + requires_dist: + - berkeleydb>=18.1.0,<19.0.0 ; extra == 'berkeleydb' + - html5rdf>=1.2,<2 ; extra == 'html' + - httpx>=0.28.1,<0.29.0 ; extra == 'rdf4j' + - isodate>=0.7.2,<1.0.0 ; python_full_version < '3.11' + - lxml>=4.3,<6.0 ; extra == 'lxml' + - networkx>=2,<4 ; extra == 'networkx' + - orjson>=3.9.14,<4 ; extra == 'orjson' + - pyparsing>=2.1.0,<4 + requires_python: '>=3.8.1' +- pypi: https://files.pythonhosted.org/packages/ba/24/c65fe1aef4e0681cb17ca136eb0f3e20a47d3941a306bc9d636938029ca5/lb_telemetry-0.5.0-py3-none-any.whl + name: lb-telemetry + version: 0.5.0 + sha256: 45c2ef5a5bdb98446f0a57b71742ef76b0a3add44e58ab059761ccc5d6fd1bbf + requires_dist: + - lbplatformutils + - logzero + - requests + - mypy ; extra == 'dev' + - mypy-extensions ; extra == 'dev' + - pre-commit ; extra == 'dev' + - pytest ; extra == 'dev' + - pytest-cov ; extra == 'dev' + - ruff ; extra == 'dev' + - types-requests ; extra == 'dev' +- pypi: https://files.pythonhosted.org/packages/ba/5a/18ad964b0086c6e62e2e7500f7edc89e3faa45033c71c1893d34eed2b2de/dnspython-2.8.0-py3-none-any.whl + name: dnspython + version: 2.8.0 + sha256: 01d9bbc4a2d76bf0db7c1f729812ded6d912bd318d3b1cf81d30c0f845dbf3af + requires_dist: + - black>=25.1.0 ; extra == 'dev' + - coverage>=7.0 ; extra == 'dev' + - flake8>=7 ; extra == 'dev' + - hypercorn>=0.17.0 ; extra == 'dev' + - mypy>=1.17 ; extra == 'dev' + - pylint>=3 ; extra == 'dev' + - pytest-cov>=6.2.0 ; extra == 'dev' + - pytest>=8.4 ; extra == 'dev' + - quart-trio>=0.12.0 ; extra == 'dev' + - sphinx-rtd-theme>=3.0.0 ; extra == 'dev' + - sphinx>=8.2.0 ; extra == 'dev' + - twine>=6.1.0 ; extra == 'dev' + - wheel>=0.45.0 ; extra == 'dev' + - cryptography>=45 ; extra == 'dnssec' + - h2>=4.2.0 ; extra == 'doh' + - httpcore>=1.0.0 ; extra == 'doh' + - httpx>=0.28.0 ; extra == 'doh' + - aioquic>=1.2.0 ; extra == 'doq' + - idna>=3.10 ; extra == 'idna' + - trio>=0.30 ; extra == 'trio' + - wmi>=1.5.1 ; sys_platform == 'win32' and extra == 'wmi' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/bb/40/c6ea527147c73b24fc15c891c3fcffe9c019793119c5742b8784a062c7db/pandas-3.0.2-cp314-cp314-macosx_10_15_x86_64.whl + name: pandas + version: 3.0.2 + sha256: db0dbfd2a6cdf3770aa60464d50333d8f3d9165b2f2671bcc299b72de5a6677b + requires_dist: + - numpy>=1.26.0 ; python_full_version < '3.14' + - numpy>=2.3.3 ; python_full_version >= '3.14' + - python-dateutil>=2.8.2 + - tzdata ; sys_platform == 'win32' + - tzdata ; sys_platform == 'emscripten' + - hypothesis>=6.116.0 ; extra == 'test' + - pytest>=8.3.4 ; extra == 'test' + - pytest-xdist>=3.6.1 ; extra == 'test' + - pyarrow>=13.0.0 ; extra == 'pyarrow' + - bottleneck>=1.4.2 ; extra == 'performance' + - numba>=0.60.0 ; extra == 'performance' + - numexpr>=2.10.2 ; extra == 'performance' + - scipy>=1.14.1 ; extra == 'computation' + - xarray>=2024.10.0 ; extra == 'computation' + - fsspec>=2024.10.0 ; extra == 'fss' + - s3fs>=2024.10.0 ; extra == 'aws' + - gcsfs>=2024.10.0 ; extra == 'gcp' + - odfpy>=1.4.1 ; extra == 'excel' + - openpyxl>=3.1.5 ; extra == 'excel' + - python-calamine>=0.3.0 ; extra == 'excel' + - pyxlsb>=1.0.10 ; extra == 'excel' + - xlrd>=2.0.1 ; extra == 'excel' + - xlsxwriter>=3.2.0 ; extra == 'excel' + - pyarrow>=13.0.0 ; extra == 'parquet' + - pyarrow>=13.0.0 ; extra == 'feather' + - pyiceberg>=0.8.1 ; extra == 'iceberg' + - tables>=3.10.1 ; extra == 'hdf5' + - pyreadstat>=1.2.8 ; extra == 'spss' + - sqlalchemy>=2.0.36 ; extra == 'postgresql' + - psycopg2>=2.9.10 ; extra == 'postgresql' + - adbc-driver-postgresql>=1.2.0 ; extra == 'postgresql' + - sqlalchemy>=2.0.36 ; extra == 'mysql' + - pymysql>=1.1.1 ; extra == 'mysql' + - sqlalchemy>=2.0.36 ; extra == 'sql-other' + - adbc-driver-postgresql>=1.2.0 ; extra == 'sql-other' + - adbc-driver-sqlite>=1.2.0 ; extra == 'sql-other' + - beautifulsoup4>=4.12.3 ; extra == 'html' + - html5lib>=1.1 ; extra == 'html' + - lxml>=5.3.0 ; extra == 'html' + - lxml>=5.3.0 ; extra == 'xml' + - matplotlib>=3.9.3 ; extra == 'plot' + - jinja2>=3.1.5 ; extra == 'output-formatting' + - tabulate>=0.9.0 ; extra == 'output-formatting' + - pyqt5>=5.15.9 ; extra == 'clipboard' + - qtpy>=2.4.2 ; extra == 'clipboard' + - zstandard>=0.23.0 ; extra == 'compression' + - pytz>=2024.2 ; extra == 'timezone' + - adbc-driver-postgresql>=1.2.0 ; extra == 'all' + - adbc-driver-sqlite>=1.2.0 ; extra == 'all' + - beautifulsoup4>=4.12.3 ; extra == 'all' + - bottleneck>=1.4.2 ; extra == 'all' + - fastparquet>=2024.11.0 ; extra == 'all' + - fsspec>=2024.10.0 ; extra == 'all' + - gcsfs>=2024.10.0 ; extra == 'all' + - html5lib>=1.1 ; extra == 'all' + - hypothesis>=6.116.0 ; extra == 'all' + - jinja2>=3.1.5 ; extra == 'all' + - lxml>=5.3.0 ; extra == 'all' + - matplotlib>=3.9.3 ; extra == 'all' + - numba>=0.60.0 ; extra == 'all' + - numexpr>=2.10.2 ; extra == 'all' + - odfpy>=1.4.1 ; extra == 'all' + - openpyxl>=3.1.5 ; extra == 'all' + - psycopg2>=2.9.10 ; extra == 'all' + - pyarrow>=13.0.0 ; extra == 'all' + - pyiceberg>=0.8.1 ; extra == 'all' + - pymysql>=1.1.1 ; extra == 'all' + - pyqt5>=5.15.9 ; extra == 'all' + - pyreadstat>=1.2.8 ; extra == 'all' + - pytest>=8.3.4 ; extra == 'all' + - pytest-xdist>=3.6.1 ; extra == 'all' + - python-calamine>=0.3.0 ; extra == 'all' + - pytz>=2024.2 ; extra == 'all' + - pyxlsb>=1.0.10 ; extra == 'all' + - qtpy>=2.4.2 ; extra == 'all' + - scipy>=1.14.1 ; extra == 'all' + - s3fs>=2024.10.0 ; extra == 'all' + - sqlalchemy>=2.0.36 ; extra == 'all' + - tables>=3.10.1 ; extra == 'all' + - tabulate>=0.9.0 ; extra == 'all' + - xarray>=2024.10.0 ; extra == 'all' + - xlrd>=2.0.1 ; extra == 'all' + - xlsxwriter>=3.2.0 ; extra == 'all' + - zstandard>=0.23.0 ; extra == 'all' + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/be/7b/4845bbf88e94586ec47a432da4e9107e3fc3ce37eb412b1398630a37f7dd/pynacl-1.6.2-cp38-abi3-macosx_10_10_universal2.whl + name: pynacl + version: 1.6.2 + sha256: c949ea47e4206af7c8f604b8278093b674f7c79ed0d4719cc836902bf4517465 + requires_dist: + - cffi>=1.4.1 ; python_full_version < '3.9' and platform_python_implementation != 'PyPy' + - cffi>=2.0.0 ; python_full_version >= '3.9' and platform_python_implementation != 'PyPy' + - pytest>=7.4.0 ; extra == 'tests' + - pytest-cov>=2.10.1 ; extra == 'tests' + - pytest-xdist>=3.5.0 ; extra == 'tests' + - hypothesis>=3.27.0 ; extra == 'tests' + - sphinx<7 ; extra == 'docs' + - sphinx-rtd-theme ; extra == 'docs' + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/c1/60/5d4751ba3f4a40a6891f24eec885f51afd78d208498268c734e256fb13c4/pydantic_settings-2.12.0-py3-none-any.whl + name: pydantic-settings + version: 2.12.0 + sha256: fddb9fd99a5b18da837b29710391e945b1e30c135477f484084ee513adb93809 + requires_dist: + - pydantic>=2.7.0 + - python-dotenv>=0.21.0 + - typing-inspection>=0.4.0 + - boto3-stubs[secretsmanager] ; extra == 'aws-secrets-manager' + - boto3>=1.35.0 ; extra == 'aws-secrets-manager' + - azure-identity>=1.16.0 ; extra == 'azure-key-vault' + - azure-keyvault-secrets>=4.8.0 ; extra == 'azure-key-vault' + - google-cloud-secret-manager>=2.23.1 ; extra == 'gcp-secret-manager' + - tomli>=2.0.1 ; extra == 'toml' + - pyyaml>=6.0.1 ; extra == 'yaml' + requires_python: '>=3.10' - pypi: https://files.pythonhosted.org/packages/c4/55/85e2732345dd8b66437cddedac4ee7ef2d9c25bf8792830b095f2ee658f3/uproot-5.7.3-py3-none-any.whl name: uproot version: 5.7.3 @@ -6233,70 +5947,272 @@ packages: - s3fs ; extra == 's3' - fsspec-xrootd>=0.5.0 ; extra == 'xrootd' requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/39/08/aaaad47bc4e9dc8c725e68f9d04865dbcb2052843ff09c97b08904852d84/urllib3-2.6.3-py3-none-any.whl - name: urllib3 - version: 2.6.3 - sha256: bf272323e553dfb2e87d9bfd225ca7b0f467b919d7bbd355436d3fd37cb0acd4 +- pypi: https://files.pythonhosted.org/packages/c7/b0/003792df09decd6849a5e39c28b513c06e84436a54440380862b5aeff25d/tzdata-2025.3-py2.py3-none-any.whl + name: tzdata + version: '2025.3' + sha256: 06a47e5700f3081aab02b2e513160914ff0694bce9947d6b76ebd6bf57cfc5d1 + requires_python: '>=2' +- pypi: https://files.pythonhosted.org/packages/c8/85/9535df0b78ba51f478c9ce7eb6d1f85535cc31fe356773b48fd9d3e563ca/rapidfuzz-3.14.5-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl + name: rapidfuzz + version: 3.14.5 + sha256: 4900143d82071bdda533b00300c40b14b963ff826b3642cc463b6dd0f036585e + requires_dist: + - numpy ; extra == 'all' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/c8/e8/c128e37589463668794d503afaeb003987373c5f94d667124ffd8078bbd9/lxml-6.0.2-cp314-cp314-macosx_10_13_x86_64.whl + name: lxml + version: 6.0.2 + sha256: 4468e3b83e10e0317a89a33d28f7aeba1caa4d1a6fd457d115dd4ffe90c5931d + requires_dist: + - cssselect>=0.7 ; extra == 'cssselect' + - html5lib ; extra == 'html5' + - beautifulsoup4 ; extra == 'htmlsoup' + - lxml-html-clean ; extra == 'html-clean' + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/ca/6d/b1a49f9712a910acdcb8dc5765e57d60c2be9fe9b001a21b6a98a1d85adb/xenv-0.0.6-py3-none-any.whl + name: xenv + version: 0.0.6 + sha256: b0407192f7b3e489375231dbb17439d928ca381d0f58057a5e078375f2125cea + requires_dist: + - coverage ; extra == 'testing' + requires_python: '>=3.7' +- pypi: https://files.pythonhosted.org/packages/ca/aa/ab2d6d68c3ee50f6dedbbc91a31cd38f9fede9258d54e7aca29bfca4ebc1/awkward_cpp-52-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl + name: awkward-cpp + version: '52' + sha256: bbfd5745b59684a044c91394d7c1c5a82bac204ed9ef6125f37ffe35aa719e2b + requires_dist: + - numpy>=1.21.3 + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/cd/22/4d16dca3bd1d6475a53063eb72150269cea1a0a201b55288b3402f61f119/aiobotocore-3.1.2-py3-none-any.whl + name: aiobotocore + version: 3.1.2 + sha256: 1141cec16c47cc3e466d89fcccc5c57291a3751a15488fe7fbaea8550f94f468 + requires_dist: + - aiohttp>=3.12.0,<4.0.0 + - aioitertools>=0.5.1,<1.0.0 + - botocore>=1.41.0,<1.42.43 + - python-dateutil>=2.1,<3.0.0 + - jmespath>=0.7.1,<2.0.0 + - multidict>=6.0.0,<7.0.0 + - typing-extensions>=4.14.0,<5.0.0 ; python_full_version < '3.11' + - wrapt>=1.10.10,<3.0.0 + - httpx>=0.25.1,<0.29 ; extra == 'httpx' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/d0/23/49cf8ea1d129637941f06fb78f5f66077bf362762c5f6c01712c4cd0e87f/hyperscan-0.8.2-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl + name: hyperscan + version: 0.8.2 + sha256: 0c0af5d882bd6afb61e2b9a13c0d39fcbcee49c62f392096d6303bd34452813f + requires_python: '>=3.9,<4.0' +- pypi: https://files.pythonhosted.org/packages/d0/d0/9e71fdc3394ffc632f35946c572e60fcc2a5452ba0a23c52493f23d60672/dirac-9.1.6-py3-none-any.whl + name: dirac + version: 9.1.6 + sha256: d818427204216f239df4171ddaa3cc646d7e208a34577bb8c86f2d9d50f6ffb3 + requires_dist: + - boto3>=1.35 + - botocore>=1.35 + - cachetools + - certifi + - cwltool + - diraccfg + - diraccommon==9.1.6 + - diracx-client>=0.0.1 + - diracx-core>=0.0.1 + - diracx-cli>=0.0.1 + - db12 + - fabric + - fts3 + - gfal2-python + - importlib-metadata>=4.4 + - importlib-resources + - invoke + - m2crypto>=0.36 + - packaging + - paramiko + - pexpect + - prompt-toolkit>=3 + - psutil + - pyasn1 + - pyasn1-modules + - pydantic>=2.4 + - pyparsing + - python-dateutil + - pytz + - requests + - rucio-clients>=34.4.2 + - sqlalchemy + - typing-extensions>=4.3.0 + - authlib>=1.0.0a2 + - pyjwt + - dominate + - zstandard + - xattr + - cmreshandler ; extra == 'server' + - opensearch-py ; extra == 'server' + - gitpython ; extra == 'server' + - ldap3 ; extra == 'server' + - apache-libcloud ; extra == 'server' + - matplotlib ; extra == 'server' + - mysqlclient ; extra == 'server' + - numpy ; extra == 'server' + - pillow ; extra == 'server' + - python-json-logger ; extra == 'server' + - pyyaml ; extra == 'server' + - stomp-py ; extra == 'server' + - suds ; extra == 'server' + - tornado~=5.1.1 ; extra == 'server' + - tornado-m2crypto ; extra == 'server' + - importlib-resources ; extra == 'server' + - hypothesis ; extra == 'testing' + - mock ; extra == 'testing' + - parameterized ; extra == 'testing' + - pytest ; extra == 'testing' + - pytest-cov ; extra == 'testing' + - pytest-mock ; extra == 'testing' + - pytest-rerunfailures ; extra == 'testing' + - pycodestyle ; extra == 'testing' + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/d5/1f/5f4a3cd9e4440e9d9bc78ad0a91a1c8d46b4d429d5239ebe6793c9fe5c41/fsspec-2026.3.0-py3-none-any.whl + name: fsspec + version: 2026.3.0 + sha256: d2ceafaad1b3457968ed14efa28798162f1638dbb5d2a6868a2db002a5ee39a4 + requires_dist: + - adlfs ; extra == 'abfs' + - adlfs ; extra == 'adl' + - pyarrow>=1 ; extra == 'arrow' + - dask ; extra == 'dask' + - distributed ; extra == 'dask' + - pre-commit ; extra == 'dev' + - ruff>=0.5 ; extra == 'dev' + - numpydoc ; extra == 'doc' + - sphinx ; extra == 'doc' + - sphinx-design ; extra == 'doc' + - sphinx-rtd-theme ; extra == 'doc' + - yarl ; extra == 'doc' + - dropbox ; extra == 'dropbox' + - dropboxdrivefs ; extra == 'dropbox' + - requests ; extra == 'dropbox' + - adlfs ; extra == 'full' + - aiohttp!=4.0.0a0,!=4.0.0a1 ; extra == 'full' + - dask ; extra == 'full' + - distributed ; extra == 'full' + - dropbox ; extra == 'full' + - dropboxdrivefs ; extra == 'full' + - fusepy ; extra == 'full' + - gcsfs>2024.2.0 ; extra == 'full' + - libarchive-c ; extra == 'full' + - ocifs ; extra == 'full' + - panel ; extra == 'full' + - paramiko ; extra == 'full' + - pyarrow>=1 ; extra == 'full' + - pygit2 ; extra == 'full' + - requests ; extra == 'full' + - s3fs>2024.2.0 ; extra == 'full' + - smbprotocol ; extra == 'full' + - tqdm ; extra == 'full' + - fusepy ; extra == 'fuse' + - gcsfs>2024.2.0 ; extra == 'gcs' + - pygit2 ; extra == 'git' + - requests ; extra == 'github' + - gcsfs ; extra == 'gs' + - panel ; extra == 'gui' + - pyarrow>=1 ; extra == 'hdfs' + - aiohttp!=4.0.0a0,!=4.0.0a1 ; extra == 'http' + - libarchive-c ; extra == 'libarchive' + - ocifs ; extra == 'oci' + - s3fs>2024.2.0 ; extra == 's3' + - paramiko ; extra == 'sftp' + - smbprotocol ; extra == 'smb' + - paramiko ; extra == 'ssh' + - aiohttp!=4.0.0a0,!=4.0.0a1 ; extra == 'test' + - numpy ; extra == 'test' + - pytest ; extra == 'test' + - pytest-asyncio!=0.22.0 ; extra == 'test' + - pytest-benchmark ; extra == 'test' + - pytest-cov ; extra == 'test' + - pytest-mock ; extra == 'test' + - pytest-recording ; extra == 'test' + - pytest-rerunfailures ; extra == 'test' + - requests ; extra == 'test' + - aiobotocore>=2.5.4,<3.0.0 ; extra == 'test-downstream' + - dask[dataframe,test] ; extra == 'test-downstream' + - moto[server]>4,<5 ; extra == 'test-downstream' + - pytest-timeout ; extra == 'test-downstream' + - xarray ; extra == 'test-downstream' + - adlfs ; extra == 'test-full' + - aiohttp!=4.0.0a0,!=4.0.0a1 ; extra == 'test-full' + - backports-zstd ; python_full_version < '3.14' and extra == 'test-full' + - cloudpickle ; extra == 'test-full' + - dask ; extra == 'test-full' + - distributed ; extra == 'test-full' + - dropbox ; extra == 'test-full' + - dropboxdrivefs ; extra == 'test-full' + - fastparquet ; extra == 'test-full' + - fusepy ; extra == 'test-full' + - gcsfs ; extra == 'test-full' + - jinja2 ; extra == 'test-full' + - kerchunk ; extra == 'test-full' + - libarchive-c ; extra == 'test-full' + - lz4 ; extra == 'test-full' + - notebook ; extra == 'test-full' + - numpy ; extra == 'test-full' + - ocifs ; extra == 'test-full' + - pandas<3.0.0 ; extra == 'test-full' + - panel ; extra == 'test-full' + - paramiko ; extra == 'test-full' + - pyarrow ; extra == 'test-full' + - pyarrow>=1 ; extra == 'test-full' + - pyftpdlib ; extra == 'test-full' + - pygit2 ; extra == 'test-full' + - pytest ; extra == 'test-full' + - pytest-asyncio!=0.22.0 ; extra == 'test-full' + - pytest-benchmark ; extra == 'test-full' + - pytest-cov ; extra == 'test-full' + - pytest-mock ; extra == 'test-full' + - pytest-recording ; extra == 'test-full' + - pytest-rerunfailures ; extra == 'test-full' + - python-snappy ; extra == 'test-full' + - requests ; extra == 'test-full' + - smbprotocol ; extra == 'test-full' + - tqdm ; extra == 'test-full' + - urllib3 ; extra == 'test-full' + - zarr ; extra == 'test-full' + - zstandard ; python_full_version < '3.14' and extra == 'test-full' + - tqdm ; extra == 'tqdm' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/d5/22/492f2246bb5b534abd44804292e81eeaf835388901f0c574bac4eeec73c5/multidict-6.7.1-cp314-cp314-macosx_10_15_x86_64.whl + name: multidict + version: 6.7.1 + sha256: a407f13c188f804c759fc6a9f88286a565c242a76b27626594c133b82883b5c2 requires_dist: - - brotli>=1.2.0 ; platform_python_implementation == 'CPython' and extra == 'brotli' - - brotlicffi>=1.2.0.0 ; platform_python_implementation != 'CPython' and extra == 'brotli' - - h2>=4,<5 ; extra == 'h2' - - pysocks>=1.5.6,!=1.5.7,<2.0 ; extra == 'socks' - - backports-zstd>=1.0.0 ; python_full_version < '3.14' and extra == 'zstd' + - typing-extensions>=4.1.0 ; python_full_version < '3.11' requires_python: '>=3.9' -- conda: https://conda.anaconda.org/conda-forge/noarch/virtualenv-20.36.1-pyhd8ed1ab_0.conda - sha256: fa0a21fdcd0a8e6cf64cc8cd349ed6ceb373f09854fd3c4365f0bc4586dccf9a - md5: 6b0259cea8ffa6b66b35bae0ca01c447 - depends: - - distlib >=0.3.7,<1 - - filelock >=3.20.1,<4 - - platformdirs >=3.9.1,<5 - - python >=3.10 - - typing_extensions >=4.13.2 - license: MIT - license_family: MIT - purls: - - pkg:pypi/virtualenv?source=hash-mapping - size: 4404318 - timestamp: 1768069793682 -- conda: https://conda.anaconda.org/conda-forge/linux-64/voms-2.1.0rc3-h25bd2b9_0.conda - sha256: e468adc4ee9de5abbf421d8b4e9463e258840e6e59ded58afe016f28d5aa931c - md5: 5e6a396c2fb7f88c0a87d6fa360e40c7 - depends: - - expat >=2.5.0,<3.0a0 - - gsoap >=2.8.123,<2.8.124.0a0 - - libgcc-ng >=12 - - libstdcxx-ng >=12 - - libzlib >=1.2.13,<2.0.0a0 - - openssl >=3.0.8,<4.0a0 - constrains: - - voms-clients ==9999999 - license: Apache-2.0 - license_family: Apache - purls: [] - size: 461879 - timestamp: 1676298873445 -- pypi: https://files.pythonhosted.org/packages/3c/c1/d73f12f8cdb1891334a2ccf7389eed244d3941e74d80dd220badb937f3fb/wcwidth-0.5.3-py3-none-any.whl - name: wcwidth - version: 0.5.3 - sha256: d584eff31cd4753e1e5ff6c12e1edfdb324c995713f75d26c29807bb84bf649e - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/95/a0/1c2396e272f91efe6b16a6a8bce7ad53856c8f9ae4f34ceaa711d63ec9e1/wrapt-2.1.1-cp314-cp314-macosx_10_15_x86_64.whl - name: wrapt - version: 2.1.1 - sha256: 9aa1765054245bb01a37f615503290d4e207e3fd59226e78341afb587e9c1236 +- pypi: https://files.pythonhosted.org/packages/d7/4c/f3b97c7d6008b3a895bbadb2deb44ad3446ae5fe204c72cd540dc222e57d/lbenv-2.4.0-py3-none-any.whl + name: lbenv + version: 2.4.0 + sha256: 5fb13304ea4d2c9f9b9a4f0710d3931ec9cd45f173581afa17a330d2635bed7e requires_dist: - - pytest ; extra == 'dev' - - setuptools ; extra == 'dev' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/b0/9a/d2faba7e61072a7507b5722db63562fdb22f5a24e237d460d18755627f15/wrapt-2.1.1-cp314-cp314-macosx_11_0_arm64.whl - name: wrapt - version: 2.1.1 - sha256: feff14b63a6d86c1eee33a57f77573649f2550935981625be7ff3cb7342efe05 + - lbplatformutils>=4.2.3 + - xenv<1.0.0 + - importlib-resources + - importlib-metadata + - pytest ; extra == 'testing' + - pytest-cov ; extra == 'testing' + - coverage ; extra == 'testing' + requires_python: '>=3.7' +- pypi: https://files.pythonhosted.org/packages/d8/da/a8bb48a4fee86b5dad8a358559b70b010cd7effaa70ca5bb4e6e82e13703/hyperscan-0.8.2-cp314-cp314-macosx_11_0_arm64.whl + name: hyperscan + version: 0.8.2 + sha256: 4e9f8d1ae2c9596385d906e062b9e0081ae843e3975fd4a656e5fcf6bbc48c13 + requires_python: '>=3.9,<4.0' +- pypi: https://files.pythonhosted.org/packages/db/2b/1239938a2629c29363e07724d7bd4c87a8b566947ecee2afb5f5ac34e1bb/cwl_upgrader-1.2.14-py3-none-any.whl + name: cwl-upgrader + version: 1.2.14 + sha256: 7c4ed6dfe082d56a58bf4e7451303213b5ee7b4e3621237dbbaad8d13018afbe requires_dist: - - pytest ; extra == 'dev' - - setuptools ; extra == 'dev' - requires_python: '>=3.9' + - ruamel-yaml>=0.16.0,<0.19 + - schema-salad + - pytest<10 ; extra == 'testing' + requires_python: '>=3.10' - pypi: https://files.pythonhosted.org/packages/db/56/073989deb4b5d7d6e7ea424476a4ae4bda02140f2dbeaafb14ba4864dd60/wrapt-2.1.1-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl name: wrapt version: 2.1.1 @@ -6305,202 +6221,265 @@ packages: - pytest ; extra == 'dev' - setuptools ; extra == 'dev' requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/1c/1c/ab905d19a1349e847e37e02933316d17adfd1dd70b64d366885ab0bd959d/xattr-1.3.0-cp314-cp314-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl - name: xattr - version: 1.3.0 - sha256: c6992eb5da32c0a1375a9eeacfab15c66eebc8bd34be63ebd1eae80cc2f8bf03 +- pypi: https://files.pythonhosted.org/packages/dc/80/12235e5b75bb2c586733280854f131b86051e0bbdfb55349ff70d0f72cf9/dogpile_cache-1.5.0-py3-none-any.whl + name: dogpile-cache + version: 1.5.0 + sha256: dc7b47d37844db15e8fdc0243c1b58857a2ddc52a5118237a97127bac200e18d requires_dist: - - cffi>=1.16.0 - - pytest ; extra == 'test' + - decorator>=4.0.0 + - stevedore>=3.0.0 + - typing-extensions>=4.0.1 ; python_full_version < '3.11' + - pifpaf>=3.3.0 ; extra == 'pifpaf' + - pymemcache ; extra == 'pymemcache' + - python-memcached ; extra == 'memcached' + - python-binary-memcached ; extra == 'bmemcached' + - pylibmc ; extra == 'pylibmc' + - redis ; extra == 'redis' + - valkey ; extra == 'valkey' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/dc/9b/47798a6c91d8bdb567fe2698fe81e0c6b7cb7ef4d13da4114b41d239f65d/typing_inspection-0.4.2-py3-none-any.whl + name: typing-inspection + version: 0.4.2 + sha256: 4ed1cacbdc298c220f1bd249ed5287caa16f34d44ef4e9c3d0cbad5b521545e7 + requires_dist: + - typing-extensions>=4.12.0 requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/3d/36/9ab4f0b5c3d10df3aceaecf7e395cabe7fb7c7c004b2dc3f3cff0ef70fc3/xattr-1.3.0-cp314-cp314-macosx_11_0_arm64.whl - name: xattr - version: 1.3.0 - sha256: 88557c0769f64b1d014aada916c9630cfefa38b0be6c247eae20740d2d8f7b47 +- pypi: https://files.pythonhosted.org/packages/de/07/a1051cdbbe6d723df16d756b97f09da7c1adb69e29695c58f0392bc12515/cramjam-2.11.0-cp314-cp314-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl + name: cramjam + version: 2.11.0 + sha256: 7ba5e38c9fbd06f086f4a5a64a1a5b7b417cd3f8fc07a20e5c03651f72f36100 requires_dist: - - cffi>=1.16.0 - - pytest ; extra == 'test' + - black==22.3.0 ; extra == 'dev' + - numpy ; extra == 'dev' + - pytest>=5.30 ; extra == 'dev' + - pytest-xdist ; extra == 'dev' + - pytest-benchmark ; extra == 'dev' + - hypothesis==6.60.0 ; extra == 'dev' + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/de/15/545e2b6cf2e3be84bc1ed85613edd75b8aea69807a71c26f4ca6a9258e82/email_validator-2.3.0-py3-none-any.whl + name: email-validator + version: 2.3.0 + sha256: 80f13f623413e6b197ae73bb10bf4eb0908faf509ad8362c5edeb0be7fd450b4 + requires_dist: + - dnspython>=2.0.0 + - idna>=2.0.0 + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/e0/f9/0595336914c5619e5f28a1fb793285925a8cd4b432c9da0a987836c7f822/shellingham-1.5.4-py2.py3-none-any.whl + name: shellingham + version: 1.5.4 + sha256: 7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686 + requires_python: '>=3.7' +- pypi: https://files.pythonhosted.org/packages/e3/d1/e30e537a15f53485b61f5be525f2157da719819e8377298502aebac45536/aiohttp-3.13.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + name: aiohttp + version: 3.13.3 + sha256: bbe7d4cecacb439e2e2a8a1a7b935c25b812af7a5fd26503a66dadf428e79ec1 + requires_dist: + - aiohappyeyeballs>=2.5.0 + - aiosignal>=1.4.0 + - async-timeout>=4.0,<6.0 ; python_full_version < '3.11' + - attrs>=17.3.0 + - frozenlist>=1.1.1 + - multidict>=4.5,<7.0 + - propcache>=0.2.0 + - yarl>=1.17.0,<2.0 + - aiodns>=3.3.0 ; extra == 'speedups' + - brotli>=1.2 ; platform_python_implementation == 'CPython' and extra == 'speedups' + - brotlicffi>=1.2 ; platform_python_implementation != 'CPython' and extra == 'speedups' + - backports-zstd ; python_full_version < '3.14' and platform_python_implementation == 'CPython' and extra == 'speedups' requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/9d/0a/03192e78071cfb86e6d8ceae0e5dcec4bacf0fd734755263aabd01532e50/xattr-1.3.0-cp314-cp314-macosx_10_15_x86_64.whl - name: xattr - version: 1.3.0 - sha256: 95f1e14a4d9ca160b4b78c527bf2bac6addbeb0fd9882c405fc0b5e3073a8752 +- pypi: https://files.pythonhosted.org/packages/e4/04/3532d990fdbab02e5ede063676b5c4260e7f3abea2151099c2aa745acc4c/yarl-1.22.0-cp314-cp314-macosx_10_13_x86_64.whl + name: yarl + version: 1.22.0 + sha256: 0dd9a702591ca2e543631c2a017e4a547e38a5c0f29eece37d9097e04a7ac683 requires_dist: - - cffi>=1.16.0 - - pytest ; extra == 'test' + - idna>=2.0 + - multidict>=4.0 + - propcache>=0.2.1 requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/ca/6d/b1a49f9712a910acdcb8dc5765e57d60c2be9fe9b001a21b6a98a1d85adb/xenv-0.0.6-py3-none-any.whl - name: xenv - version: 0.0.6 - sha256: b0407192f7b3e489375231dbb17439d928ca381d0f58057a5e078375f2125cea +- pypi: https://files.pythonhosted.org/packages/e6/51/aac7e419521d5519e13087a7198623655648c939822bd7f4bdc9ccbe07f9/botocore-1.42.42-py3-none-any.whl + name: botocore + version: 1.42.42 + sha256: 1c9df5fc31e9073a9aa956271c4007d72f5d342cafca5f4154ea099bc6f83085 + requires_dist: + - jmespath>=0.7.1,<2.0.0 + - python-dateutil>=2.1,<3.0.0 + - urllib3>=1.25.4,<1.27 ; python_full_version < '3.10' + - urllib3>=1.25.4,!=2.2.0,<3 ; python_full_version >= '3.10' + - awscrt==0.29.2 ; extra == 'crt' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/e6/ad/3cc14f097111b4de0040c83a525973216457bbeeb63739ef1ed275c1c021/certifi-2026.1.4-py3-none-any.whl + name: certifi + version: 2026.1.4 + sha256: 9943707519e4add1115f44c2bc244f782c0249876bf51b6599fee1ffbedd685c + requires_python: '>=3.7' +- pypi: https://files.pythonhosted.org/packages/e8/0b/b97660c5fd05d3495b4eb27f2d0ef18dc1dc4eff7511a9bf371397ff0264/aiohttp-3.13.3-cp314-cp314-macosx_11_0_arm64.whl + name: aiohttp + version: 3.13.3 + sha256: c685f2d80bb67ca8c3837823ad76196b3694b0159d232206d1e461d3d434666f + requires_dist: + - aiohappyeyeballs>=2.5.0 + - aiosignal>=1.4.0 + - async-timeout>=4.0,<6.0 ; python_full_version < '3.11' + - attrs>=17.3.0 + - frozenlist>=1.1.1 + - multidict>=4.5,<7.0 + - propcache>=0.2.0 + - yarl>=1.17.0,<2.0 + - aiodns>=3.3.0 ; extra == 'speedups' + - brotli>=1.2 ; platform_python_implementation == 'CPython' and extra == 'speedups' + - brotlicffi>=1.2 ; platform_python_implementation != 'CPython' and extra == 'speedups' + - backports-zstd ; python_full_version < '3.14' and platform_python_implementation == 'CPython' and extra == 'speedups' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/e9/f8/5ecdfc73383ec496de038ed1614de9e740a82db9ad67e6e4514ebc0708a3/sqlalchemy-2.0.46-cp314-cp314-macosx_11_0_arm64.whl + name: sqlalchemy + version: 2.0.46 + sha256: 56bdd261bfd0895452006d5316cbf35739c53b9bb71a170a331fa0ea560b2ada requires_dist: - - coverage ; extra == 'testing' + - importlib-metadata ; python_full_version < '3.8' + - greenlet>=1 ; platform_machine == 'AMD64' or platform_machine == 'WIN32' or platform_machine == 'aarch64' or platform_machine == 'amd64' or platform_machine == 'ppc64le' or platform_machine == 'win32' or platform_machine == 'x86_64' + - typing-extensions>=4.6.0 + - greenlet>=1 ; extra == 'asyncio' + - mypy>=0.910 ; extra == 'mypy' + - pyodbc ; extra == 'mssql' + - pymssql ; extra == 'mssql-pymssql' + - pyodbc ; extra == 'mssql-pyodbc' + - mysqlclient>=1.4.0 ; extra == 'mysql' + - mysql-connector-python ; extra == 'mysql-connector' + - mariadb>=1.0.1,!=1.1.2,!=1.1.5,!=1.1.10 ; extra == 'mariadb-connector' + - cx-oracle>=8 ; extra == 'oracle' + - oracledb>=1.0.1 ; extra == 'oracle-oracledb' + - psycopg2>=2.7 ; extra == 'postgresql' + - pg8000>=1.29.1 ; extra == 'postgresql-pg8000' + - greenlet>=1 ; extra == 'postgresql-asyncpg' + - asyncpg ; extra == 'postgresql-asyncpg' + - psycopg2-binary ; extra == 'postgresql-psycopg2binary' + - psycopg2cffi ; extra == 'postgresql-psycopg2cffi' + - psycopg>=3.0.7 ; extra == 'postgresql-psycopg' + - psycopg[binary]>=3.0.7 ; extra == 'postgresql-psycopgbinary' + - pymysql ; extra == 'pymysql' + - greenlet>=1 ; extra == 'aiomysql' + - aiomysql>=0.2.0 ; extra == 'aiomysql' + - greenlet>=1 ; extra == 'aioodbc' + - aioodbc ; extra == 'aioodbc' + - greenlet>=1 ; extra == 'asyncmy' + - asyncmy>=0.2.3,!=0.2.4,!=0.2.6 ; extra == 'asyncmy' + - greenlet>=1 ; extra == 'aiosqlite' + - aiosqlite ; extra == 'aiosqlite' + - typing-extensions!=3.10.0.1 ; extra == 'aiosqlite' + - sqlcipher3-binary ; extra == 'sqlcipher' requires_python: '>=3.7' -- pypi: https://files.pythonhosted.org/packages/38/34/98a2f52245f4d47be93b580dae5f9861ef58977d73a79eb47c58f1ad1f3a/xmltodict-1.0.4-py3-none-any.whl - name: xmltodict - version: 1.0.4 - sha256: a4a00d300b0e1c59fc2bfccb53d7b2e88c32f200df138a0dd2229f842497026a +- pypi: https://files.pythonhosted.org/packages/ea/28/46b7c5c9635ae96ea0fbb779e271a38129df2550f763937659ee6c5dbc65/pydantic_core-2.41.5-cp314-cp314-macosx_10_12_x86_64.whl + name: pydantic-core + version: 2.41.5 + sha256: 3f37a19d7ebcdd20b96485056ba9e8b304e27d9904d233d7b1015db320e51f0a requires_dist: - - pytest ; extra == 'test' - - pytest-cov ; extra == 'test' + - typing-extensions>=4.14.1 requires_python: '>=3.9' -- conda: https://conda.anaconda.org/conda-forge/linux-64/xrootd-5.9.1-py314h75aeccf_0.conda - sha256: 2351cace7322d68dd834c276f4cb19bc35a68d90642dd7083b4924bb26a66228 - md5: d9b7e0eeecec187f4344983ba341c2d7 - depends: - - openssl - - python - - readline - - libxml2-devel - - krb5 - - zlib - - ncurses - - __glibc >=2.17,<3.0.a0 - - libstdcxx >=14 - - libgcc >=14 - - libcurl >=8.18.0,<9.0a0 - - scitokens-cpp >=1.2.0,<2.0a0 - - libxcrypt >=4.4.36 - - libuuid >=2.41.3,<3.0a0 - - ncurses >=6.5,<7.0a0 - - openssl >=3.5.4,<4.0a0 - - python_abi 3.14.* *_cp314 - - readline >=8.3,<9.0a0 - - libzlib >=1.3.1,<2.0a0 - - libxml2 - - libxml2-16 >=2.14.6 - - krb5 >=1.21.3,<1.22.0a0 - license: LGPL-3.0-or-later - license_family: LGPL - purls: - - pkg:pypi/xrootd?source=hash-mapping - size: 4201796 - timestamp: 1769447927303 -- conda: https://conda.anaconda.org/conda-forge/osx-64/xrootd-5.9.1-py314hb36820e_0.conda - sha256: 85669c3b2ba7186b7f1b5c6440c09b16ab1d52424ece1d1eb145afb9237b3011 - md5: a6cf55d7323840b381a89b36f0947e96 - depends: - - openssl - - python - - readline - - libxml2-devel - - krb5 - - zlib - - ncurses - - libcxx >=19 - - __osx >=10.13 - - libcurl >=8.18.0,<9.0a0 - - libxml2 - - libxml2-16 >=2.14.6 - - readline >=8.3,<9.0a0 - - python_abi 3.14.* *_cp314 - - libzlib >=1.3.1,<2.0a0 - - libxcrypt >=4.4.36 - - krb5 >=1.21.3,<1.22.0a0 - - ncurses >=6.5,<7.0a0 - - openssl >=3.5.4,<4.0a0 - - scitokens-cpp >=1.2.0,<2.0a0 - license: LGPL-3.0-or-later - license_family: LGPL - purls: - - pkg:pypi/xrootd?source=hash-mapping - size: 3529962 - timestamp: 1769447937537 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/xrootd-5.9.1-py314h6e96a01_0.conda - sha256: 2c3a4a6ed0e8c9163eef9967b6ff3ca72145e08d90349052ebf48c9e89a5dbd7 - md5: e7a71484b64ce6e45fd9d85645641f4a - depends: - - openssl - - python - - readline - - libxml2-devel - - krb5 - - zlib - - ncurses - - libcxx >=19 - - __osx >=11.0 - - python 3.14.* *_cp314 - - libxml2 - - libxml2-16 >=2.14.6 - - openssl >=3.5.4,<4.0a0 - - libxcrypt >=4.4.36 - - libzlib >=1.3.1,<2.0a0 - - scitokens-cpp >=1.2.0,<2.0a0 - - python_abi 3.14.* *_cp314 - - readline >=8.3,<9.0a0 - - krb5 >=1.21.3,<1.22.0a0 - - libcurl >=8.18.0,<9.0a0 - - ncurses >=6.5,<7.0a0 - license: LGPL-3.0-or-later - license_family: LGPL - purls: - - pkg:pypi/xrootd?source=hash-mapping - size: 3347452 - timestamp: 1769448002819 -- pypi: https://files.pythonhosted.org/packages/18/d7/5dac2eb2ec75fd771957a13e5dda560efb2176d5203f39502a5fc571f899/xxhash-3.6.0-cp314-cp314-macosx_11_0_arm64.whl - name: xxhash - version: 3.6.0 - sha256: a54844be970d3fc22630b32d515e79a90d0a3ddb2644d8d7402e3c4c8da61405 - requires_python: '>=3.7' -- pypi: https://files.pythonhosted.org/packages/7e/5e/0138bc4484ea9b897864d59fce9be9086030825bc778b76cb5a33a906d37/xxhash-3.6.0-cp314-cp314-macosx_10_13_x86_64.whl - name: xxhash - version: 3.6.0 - sha256: a40a3d35b204b7cc7643cbcf8c9976d818cb47befcfac8bbefec8038ac363f3e - requires_python: '>=3.7' +- pypi: https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl + name: python-dateutil + version: 2.9.0.post0 + sha256: a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427 + requires_dist: + - six>=1.5 + requires_python: '>=2.7,!=3.0.*,!=3.1.*,!=3.2.*' - pypi: https://files.pythonhosted.org/packages/ed/ba/603ce3961e339413543d8cd44f21f2c80e2a7c5cfe692a7b1f2cccf58f3c/xxhash-3.6.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl name: xxhash version: 3.6.0 sha256: 0226aa89035b62b6a86d3c68df4d7c1f47a342b8683da2b60cedcddb46c4d95b requires_python: '>=3.7' -- conda: https://conda.anaconda.org/conda-forge/linux-64/yaml-0.2.5-h280c20c_3.conda - sha256: 6d9ea2f731e284e9316d95fa61869fe7bbba33df7929f82693c121022810f4ad - md5: a77f85f77be52ff59391544bfe73390a - depends: - - libgcc >=14 - - __glibc >=2.17,<3.0.a0 - license: MIT - license_family: MIT - purls: [] - size: 85189 - timestamp: 1753484064210 -- conda: https://conda.anaconda.org/conda-forge/osx-64/yaml-0.2.5-h4132b18_3.conda - sha256: a335161bfa57b64e6794c3c354e7d49449b28b8d8a7c4ed02bf04c3f009953f9 - md5: a645bb90997d3fc2aea0adf6517059bd - depends: - - __osx >=10.13 - license: MIT - license_family: MIT - purls: [] - size: 79419 - timestamp: 1753484072608 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/yaml-0.2.5-h925e9cb_3.conda - sha256: b03433b13d89f5567e828ea9f1a7d5c5d697bf374c28a4168d71e9464f5dafac - md5: 78a0fe9e9c50d2c381e8ee47e3ea437d - depends: - - __osx >=11.0 - license: MIT - license_family: MIT - purls: [] - size: 83386 - timestamp: 1753484079473 -- pypi: https://files.pythonhosted.org/packages/11/63/ff458113c5c2dac9a9719ac68ee7c947cb621432bcf28c9972b1c0e83938/yarl-1.22.0-cp314-cp314-macosx_11_0_arm64.whl - name: yarl - version: 1.22.0 - sha256: 594fcab1032e2d2cc3321bb2e51271e7cd2b516c7d9aee780ece81b07ff8244b +- pypi: https://files.pythonhosted.org/packages/ed/c9/d7977eaacb9df673210491da99e6a247e93df98c715fc43fd136ce1d3d33/arrow-1.4.0-py3-none-any.whl + name: arrow + version: 1.4.0 + sha256: 749f0769958ebdc79c173ff0b0670d59051a535fa26e8eba02953dc19eb43205 + requires_dist: + - python-dateutil>=2.7.0 + - backports-zoneinfo==0.2.1 ; python_full_version < '3.9' + - tzdata ; python_full_version >= '3.9' + - doc8 ; extra == 'doc' + - sphinx>=7.0.0 ; extra == 'doc' + - sphinx-autobuild ; extra == 'doc' + - sphinx-autodoc-typehints ; extra == 'doc' + - sphinx-rtd-theme>=1.3.0 ; extra == 'doc' + - dateparser==1.* ; extra == 'test' + - pre-commit ; extra == 'test' + - pytest ; extra == 'test' + - pytest-cov ; extra == 'test' + - pytest-mock ; extra == 'test' + - pytz==2025.2 ; extra == 'test' + - simplejson==3.* ; extra == 'test' + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/ef/45/615f5babd880b4bd7d405cc0dc348234c5ffb6ed1ea33e152ede08b2072d/rich-14.3.2-py3-none-any.whl + name: rich + version: 14.3.2 + sha256: 08e67c3e90884651da3239ea668222d19bea7b589149d8014a21c633420dbb69 + requires_dist: + - ipywidgets>=7.5.1,<9 ; extra == 'jupyter' + - markdown-it-py>=2.2.0 + - pygments>=2.13.0,<3.0.0 + requires_python: '>=3.8.0' +- pypi: https://files.pythonhosted.org/packages/ef/79/c45f2d53efe6ada1110cf6f9fca095e4ff47a0454444aefdde6ac4789179/cachecontrol-0.14.4-py3-none-any.whl + name: cachecontrol + version: 0.14.4 + sha256: b7ac014ff72ee199b5f8af1de29d60239954f223e948196fa3d84adaffc71d2b + requires_dist: + - requests>=2.16.0 + - msgpack>=0.5.2,<2.0.0 + - cachecontrol[filecache,redis] ; extra == 'dev' + - cherrypy ; extra == 'dev' + - cheroot>=11.1.2 ; extra == 'dev' + - codespell ; extra == 'dev' + - furo ; extra == 'dev' + - mypy ; extra == 'dev' + - pytest ; extra == 'dev' + - pytest-cov ; extra == 'dev' + - ruff ; extra == 'dev' + - sphinx ; extra == 'dev' + - sphinx-copybutton ; extra == 'dev' + - types-redis ; extra == 'dev' + - types-requests ; extra == 'dev' + - filelock>=3.8.0 ; extra == 'filecache' + - redis>=2.10.5 ; extra == 'redis' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/f0/0f/310fb31e39e2d734ccaa2c0fb981ee41f7bd5056ce9bc29b2248bd569169/humanfriendly-10.0-py2.py3-none-any.whl + name: humanfriendly + version: '10.0' + sha256: 1697e1a8a8f550fd43c2865cd84542fc175a61dcb779b6fee18cf6b6ccba1477 + requires_dist: + - monotonic ; python_full_version == '2.7.*' + - pyreadline ; python_full_version < '3.8' and sys_platform == 'win32' + - pyreadline3 ; python_full_version >= '3.8' and sys_platform == 'win32' + requires_python: '>=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*' +- pypi: https://files.pythonhosted.org/packages/f1/4f/733c48f270565d78b4544f2baddc2fb2a245e5a8640254b12c36ac7ac68e/multidict-6.7.1-cp314-cp314-macosx_11_0_arm64.whl + name: multidict + version: 6.7.1 + sha256: 0e161ddf326db5577c3a4cc2d8648f81456e8a20d40415541587a71620d7a7d1 requires_dist: - - idna>=2.0 - - multidict>=4.0 - - propcache>=0.2.1 + - typing-extensions>=4.1.0 ; python_full_version < '3.11' requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/e4/04/3532d990fdbab02e5ede063676b5c4260e7f3abea2151099c2aa745acc4c/yarl-1.22.0-cp314-cp314-macosx_10_13_x86_64.whl - name: yarl - version: 1.22.0 - sha256: 0dd9a702591ca2e543631c2a017e4a547e38a5c0f29eece37d9097e04a7ac683 +- pypi: https://files.pythonhosted.org/packages/f2/61/0c78d9778bffd844863d3173a5fefb506d7131ceebecee523a9e27024aa1/diracx_client-0.0.8-py3-none-any.whl + name: diracx-client + version: 0.0.8 + sha256: 9c8406add1f14c103ac91440fa41bb93e400d98bcad60f32e987ff6b233fa18b requires_dist: - - idna>=2.0 - - multidict>=4.0 - - propcache>=0.2.1 - requires_python: '>=3.9' + - azure-core + - diracx-core + - httpx + - isodate + - pyjwt + - diracx-testing ; extra == 'testing' + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/f3/e1/2f705da403f865a5fa3449b155738dc9c53021698fd6926253a9af03180b/levenshtein-0.27.3-cp314-cp314-macosx_10_15_x86_64.whl + name: levenshtein + version: 0.27.3 + sha256: a6728bfae9a86002f0223576675fc7e2a6e7735da47185a1d13d1eaaa73dd4be + requires_dist: + - rapidfuzz>=3.9.0,<4.0.0 + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/f4/40/8561ce06dc46fd17242c7724ab25b257a2ac1b35f4ebf551b40ce6105cfa/stevedore-5.6.0-py3-none-any.whl + name: stevedore + version: 5.6.0 + sha256: 4a36dccefd7aeea0c70135526cecb7766c4c84c473b1af68db23d541b6dc1820 + requires_python: '>=3.10' - pypi: https://files.pythonhosted.org/packages/f5/e7/d8c5a7752fef68205296201f8ec2bf718f5c805a7a7e9880576c67600658/yarl-1.22.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl name: yarl version: 1.22.0 @@ -6510,118 +6489,140 @@ packages: - multidict>=4.0 - propcache>=0.2.1 requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/2e/54/647ade08bf0db230bfea292f893923872fd20be6ac6f53b2b936ba839d75/zipp-3.23.0-py3-none-any.whl - name: zipp - version: 3.23.0 - sha256: 071652d6115ed432f5ce1d34c336c0adfd6a884660d1e9712a256d3d3bd4b14e +- pypi: https://files.pythonhosted.org/packages/f7/49/459327f0d5bcd8c6c9ca69e60fdeebc3622861e696490d8674a6d0cb90a6/aiohttp-3.13.3-cp314-cp314-macosx_10_13_x86_64.whl + name: aiohttp + version: 3.13.3 + sha256: 6fc0e2337d1a4c3e6acafda6a78a39d4c14caea625124817420abceed36e2415 + requires_dist: + - aiohappyeyeballs>=2.5.0 + - aiosignal>=1.4.0 + - async-timeout>=4.0,<6.0 ; python_full_version < '3.11' + - attrs>=17.3.0 + - frozenlist>=1.1.1 + - multidict>=4.5,<7.0 + - propcache>=0.2.0 + - yarl>=1.17.0,<2.0 + - aiodns>=3.3.0 ; extra == 'speedups' + - brotli>=1.2 ; platform_python_implementation == 'CPython' and extra == 'speedups' + - brotlicffi>=1.2 ; platform_python_implementation != 'CPython' and extra == 'speedups' + - backports-zstd ; python_full_version < '3.14' and platform_python_implementation == 'CPython' and extra == 'speedups' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/f8/b2/ad8e7e63fdf5add3ceb7a0805d700e9fd7cb7d5743f765a4994b4ec286d7/diraccommon-9.1.6-py3-none-any.whl + name: diraccommon + version: 9.1.6 + sha256: 53c765edf120eff9764d49e57d4073c0f2d671ed391f52a2ca940abef0810963 + requires_dist: + - diraccfg + - pydantic>=2.0.0 + - typing-extensions>=4.0.0 + - pytest-cov>=4.0.0 ; extra == 'testing' + - pytest>=7.0.0 ; extra == 'testing' + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/f9/38/8b6fc7a8153cb49eb3a9a13acfa9eeb6cc476e37888781e593e6f02ac05e/spython-0.3.14-py3-none-any.whl + name: spython + version: 0.3.14 + sha256: 72968583e498bc2a51f9acd0ed6bc0d7d1f7ccd491feaba5e2f7d944bc51da3a +- pypi: https://files.pythonhosted.org/packages/fa/5e/f8e9a1d23b9c20a551a8a02ea3637b4642e22c2626e3a13a9a29cdea99eb/importlib_metadata-8.7.1-py3-none-any.whl + name: importlib-metadata + version: 8.7.1 + sha256: 5a1f80bf1daa489495071efbb095d75a634cf28a8bc299581244063b53176151 requires_dist: + - zipp>=3.20 - pytest>=6,!=8.1.* ; extra == 'test' - - jaraco-itertools ; extra == 'test' - - jaraco-functools ; extra == 'test' - - more-itertools ; extra == 'test' - - big-o ; extra == 'test' - - pytest-ignore-flaky ; extra == 'test' - - jaraco-test ; extra == 'test' + - packaging ; extra == 'test' + - pyfakefs ; extra == 'test' + - flufl-flake8 ; extra == 'test' + - pytest-perf>=0.9.2 ; extra == 'test' + - jaraco-test>=5.4 ; extra == 'test' - sphinx>=3.5 ; extra == 'doc' - jaraco-packaging>=9.3 ; extra == 'doc' - rst-linker>=1.9 ; extra == 'doc' - furo ; extra == 'doc' - sphinx-lint ; extra == 'doc' - jaraco-tidelift>=1.4 ; extra == 'doc' + - ipython ; extra == 'perf' - pytest-checkdocs>=2.4 ; extra == 'check' - pytest-ruff>=0.2.1 ; sys_platform != 'cygwin' and extra == 'check' - pytest-cov ; extra == 'cover' - - pytest-enabler>=2.2 ; extra == 'enabler' - - pytest-mypy ; extra == 'type' + - pytest-enabler>=3.4 ; extra == 'enabler' + - pytest-mypy>=1.0.1 ; extra == 'type' + - mypy<1.19 ; platform_python_implementation == 'PyPy' and extra == 'type' requires_python: '>=3.9' -- conda: https://conda.anaconda.org/conda-forge/linux-64/zlib-1.3.1-hb9d3cd8_2.conda - sha256: 5d7c0e5f0005f74112a34a7425179f4eb6e73c92f5d109e6af4ddeca407c92ab - md5: c9f075ab2f33b3bbee9e62d4ad0a6cd8 - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=13 - - libzlib 1.3.1 hb9d3cd8_2 - license: Zlib - license_family: Other - purls: [] - size: 92286 - timestamp: 1727963153079 -- conda: https://conda.anaconda.org/conda-forge/osx-64/zlib-1.3.1-hd23fc13_2.conda - sha256: 219edbdfe7f073564375819732cbf7cc0d7c7c18d3f546a09c2dfaf26e4d69f3 - md5: c989e0295dcbdc08106fe5d9e935f0b9 - depends: - - __osx >=10.13 - - libzlib 1.3.1 hd23fc13_2 - license: Zlib - license_family: Other - purls: [] - size: 88544 - timestamp: 1727963189976 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/zlib-1.3.1-h8359307_2.conda - sha256: 58f8860756680a4831c1bf4f294e2354d187f2e999791d53b1941834c4b37430 - md5: e3170d898ca6cb48f1bb567afb92f775 - depends: - - __osx >=11.0 - - libzlib 1.3.1 h8359307_2 - license: Zlib - license_family: Other - purls: [] - size: 77606 - timestamp: 1727963209370 -- pypi: https://files.pythonhosted.org/packages/31/dc/cc50210e11e465c975462439a492516a73300ab8caa8f5e0902544fd748b/zstandard-0.25.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - name: zstandard - version: 0.25.0 - sha256: e09bb6252b6476d8d56100e8147b803befa9a12cea144bbe629dd508800d1ad0 +- pypi: https://files.pythonhosted.org/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl + name: aiosignal + version: 1.4.0 + sha256: 053243f8b92b990551949e63930a839ff0cf0b0ebbe0597b0f3fb19e1a0fe82e requires_dist: - - cffi~=1.17 ; python_full_version < '3.14' and platform_python_implementation != 'PyPy' and extra == 'cffi' - - cffi>=2.0.0b0 ; python_full_version >= '3.14' and platform_python_implementation != 'PyPy' and extra == 'cffi' + - frozenlist>=1.1.0 + - typing-extensions>=4.2 ; python_full_version < '3.13' requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/3d/5c/f8923b595b55fe49e30612987ad8bf053aef555c14f05bb659dd5dbe3e8a/zstandard-0.25.0-cp314-cp314-macosx_10_13_x86_64.whl - name: zstandard - version: 0.25.0 - sha256: e29f0cf06974c899b2c188ef7f783607dbef36da4c242eb6c82dcd8b512855e3 +- pypi: https://files.pythonhosted.org/packages/fb/b9/0978fa6f21f504b617ccee4843210d7ab8921a10e94e3bbf084498dcfad7/awkward_cpp-52-cp314-cp314-macosx_11_0_arm64.whl + name: awkward-cpp + version: '52' + sha256: 626e75125267c7ce51fdb891fa628e7cf3ea9c37df19126e25dd9587917f94ab requires_dist: - - cffi~=1.17 ; python_full_version < '3.14' and platform_python_implementation != 'PyPy' and extra == 'cffi' - - cffi>=2.0.0b0 ; python_full_version >= '3.14' and platform_python_implementation != 'PyPy' and extra == 'cffi' + - numpy>=1.21.3 + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/fc/51/727abb13f44c1fcf6d145979e1535a35794db0f6e450a0cb46aa24732fe2/s3transfer-0.16.0-py3-none-any.whl + name: s3transfer + version: 0.16.0 + sha256: 18e25d66fed509e3868dc1572b3f427ff947dd2c56f844a5bf09481ad3f3b2fe + requires_dist: + - botocore>=1.37.4,<2.0a0 + - botocore[crt]>=1.37.4,<2.0a0 ; extra == 'crt' requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/8d/09/d0a2a14fc3439c5f874042dca72a79c70a532090b7ba0003be73fee37ae2/zstandard-0.25.0-cp314-cp314-macosx_11_0_arm64.whl - name: zstandard - version: 0.25.0 - sha256: 05df5136bc5a011f33cd25bc9f506e7426c0c9b3f9954f056831ce68f3b6689f +- pypi: https://files.pythonhosted.org/packages/fc/a1/9c4efa03300926601c19c18582531b45aededfb961ab3c3585f1e24f120b/sqlalchemy-2.0.46-py3-none-any.whl + name: sqlalchemy + version: 2.0.46 + sha256: f9c11766e7e7c0a2767dda5acb006a118640c9fc0a4104214b96269bfb78399e requires_dist: - - cffi~=1.17 ; python_full_version < '3.14' and platform_python_implementation != 'PyPy' and extra == 'cffi' - - cffi>=2.0.0b0 ; python_full_version >= '3.14' and platform_python_implementation != 'PyPy' and extra == 'cffi' + - importlib-metadata ; python_full_version < '3.8' + - greenlet>=1 ; platform_machine == 'AMD64' or platform_machine == 'WIN32' or platform_machine == 'aarch64' or platform_machine == 'amd64' or platform_machine == 'ppc64le' or platform_machine == 'win32' or platform_machine == 'x86_64' + - typing-extensions>=4.6.0 + - greenlet>=1 ; extra == 'asyncio' + - mypy>=0.910 ; extra == 'mypy' + - pyodbc ; extra == 'mssql' + - pymssql ; extra == 'mssql-pymssql' + - pyodbc ; extra == 'mssql-pyodbc' + - mysqlclient>=1.4.0 ; extra == 'mysql' + - mysql-connector-python ; extra == 'mysql-connector' + - mariadb>=1.0.1,!=1.1.2,!=1.1.5,!=1.1.10 ; extra == 'mariadb-connector' + - cx-oracle>=8 ; extra == 'oracle' + - oracledb>=1.0.1 ; extra == 'oracle-oracledb' + - psycopg2>=2.7 ; extra == 'postgresql' + - pg8000>=1.29.1 ; extra == 'postgresql-pg8000' + - greenlet>=1 ; extra == 'postgresql-asyncpg' + - asyncpg ; extra == 'postgresql-asyncpg' + - psycopg2-binary ; extra == 'postgresql-psycopg2binary' + - psycopg2cffi ; extra == 'postgresql-psycopg2cffi' + - psycopg>=3.0.7 ; extra == 'postgresql-psycopg' + - psycopg[binary]>=3.0.7 ; extra == 'postgresql-psycopgbinary' + - pymysql ; extra == 'pymysql' + - greenlet>=1 ; extra == 'aiomysql' + - aiomysql>=0.2.0 ; extra == 'aiomysql' + - greenlet>=1 ; extra == 'aioodbc' + - aioodbc ; extra == 'aioodbc' + - greenlet>=1 ; extra == 'asyncmy' + - asyncmy>=0.2.3,!=0.2.4,!=0.2.6 ; extra == 'asyncmy' + - greenlet>=1 ; extra == 'aiosqlite' + - aiosqlite ; extra == 'aiosqlite' + - typing-extensions!=3.10.0.1 ; extra == 'aiosqlite' + - sqlcipher3-binary ; extra == 'sqlcipher' + requires_python: '>=3.7' +- pypi: https://files.pythonhosted.org/packages/fc/d8/b8fcba9464f02b121f39de2db2bf57f0b216fe11d014513d666e8634380d/azure_core-1.38.0-py3-none-any.whl + name: azure-core + version: 1.38.0 + sha256: ab0c9b2cd71fecb1842d52c965c95285d3cfb38902f6766e4a471f1cd8905335 + requires_dist: + - requests>=2.21.0 + - typing-extensions>=4.6.0 + - aiohttp>=3.0 ; extra == 'aio' + - opentelemetry-api~=1.26 ; extra == 'tracing' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/fe/3b/8ec5074bcfc450fe84273713b4b0a0dd47c0249358f5d82eb8104ffe2520/multidict-6.7.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + name: multidict + version: 6.7.1 + sha256: 7eee46ccb30ff48a1e35bb818cc90846c6be2b68240e42a78599166722cea709 + requires_dist: + - typing-extensions>=4.1.0 ; python_full_version < '3.11' requires_python: '>=3.9' -- conda: https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda - sha256: 68f0206ca6e98fea941e5717cec780ed2873ffabc0e1ed34428c061e2c6268c7 - md5: 4a13eeac0b5c8e5b8ab496e6c4ddd829 - depends: - - __glibc >=2.17,<3.0.a0 - - libzlib >=1.3.1,<2.0a0 - license: BSD-3-Clause - license_family: BSD - purls: [] - size: 601375 - timestamp: 1764777111296 -- conda: https://conda.anaconda.org/conda-forge/osx-64/zstd-1.5.7-h3eecb57_6.conda - sha256: 47101a4055a70a4876ffc87b750ab2287b67eca793f21c8224be5e1ee6394d3f - md5: 727109b184d680772e3122f40136d5ca - depends: - - __osx >=10.13 - - libzlib >=1.3.1,<2.0a0 - license: BSD-3-Clause - license_family: BSD - purls: [] - size: 528148 - timestamp: 1764777156963 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/zstd-1.5.7-hbf9d68e_6.conda - sha256: 9485ba49e8f47d2b597dd399e88f4802e100851b27c21d7525625b0b4025a5d9 - md5: ab136e4c34e97f34fb621d2592a393d8 - depends: - - __osx >=11.0 - - libzlib >=1.3.1,<2.0a0 - license: BSD-3-Clause - license_family: BSD - purls: [] - size: 433413 - timestamp: 1764777166076 diff --git a/src/dirac_cwl/commands/analyze_xml_summary.py b/src/dirac_cwl/commands/analyze_xml_summary.py index adf4222..9d2b269 100644 --- a/src/dirac_cwl/commands/analyze_xml_summary.py +++ b/src/dirac_cwl/commands/analyze_xml_summary.py @@ -2,84 +2,61 @@ import os -from DIRAC.TransformationSystem.Client.FileReport import FileReport -from DIRAC.WorkloadManagementSystem.Client.JobReport import JobReport -from LHCbDIRAC.Core.Utilities.XMLSummaries import XMLSummary from LHCbDIRAC.Workflow.Modules.AnalyseXMLSummary import _areInputsOK, _isXMLSummaryOK from LHCbDIRAC.Workflow.Modules.BookkeepingReport import _generate_xml_object from dirac_cwl.core.exceptions import WorkflowProcessingException from .core import PostProcessCommand -from .utils import prepare_lhcb_workflow_commons, save_workflow_commons +from .workflow_commons import StepStatus, WorkflowCommons class AnalyseXmlSummary(PostProcessCommand): """Performs a series of checks on the XMLSummary output to make sure the execution was done correctly.""" - def execute(self, job_path, **kwargs): + def execute(self, job_path: os.PathLike, **kwargs): """Execute the command. :param job_path: Path to the job working directory. :param kwargs: Additional keyword arguments. """ failed = False - workflow_commons = {} + workflow_commons = None try: - workflow_commons_path = kwargs.get("workflow_commons_path", os.path.join(job_path, "workflow_commons.json")) + workflow_commons = WorkflowCommons.load(job_path) - workflow_commons = prepare_lhcb_workflow_commons( - workflow_commons_path, - extra_mandatory_values=[ - "bk_step_id", - ], - extra_default_values={ - "bookkeeping_LFNs": [], - "size": {}, - "md5": {}, - "guid": {}, - "sim_description": "NoSimConditions", - }, - ) - - if not workflow_commons["step_status"]["OK"]: + if workflow_commons.step_status == StepStatus.Failed: return - if "xml_summary_path" in workflow_commons: - xf_o = XMLSummary(workflow_commons["xml_summary_path"]) - else: - xf_o = _generate_xml_object( - workflow_commons["cleaned_application_name"], - workflow_commons["production_id"], - workflow_commons["prod_job_id"], - workflow_commons["command_number"], - workflow_commons["command_id"], + if not workflow_commons.xf_o: + workflow_commons.xf_o = _generate_xml_object( + workflow_commons.cleaned_application_name, + workflow_commons.production_id, + workflow_commons.prod_job_id, + workflow_commons.step_number, + workflow_commons.step_id, ) - file_report = FileReport() - job_report = JobReport(workflow_commons["job_id"]) - - file_report.statusDict = workflow_commons["file_report_files_dict"] - - jobOk = _isXMLSummaryOK(xf_o) + jobOk = _isXMLSummaryOK(workflow_commons.xf_o) if jobOk: jobOk = _areInputsOK( - xf_o, - workflow_commons["inputs"], - workflow_commons["number_of_events"], - workflow_commons["production_id"], - file_report, + workflow_commons.xf_o, + workflow_commons.inputs, + workflow_commons.number_of_events, + workflow_commons.production_id, + workflow_commons.file_report, ) if not jobOk: - job_report.setApplicationStatus("XMLSummary reports error") + workflow_commons.job_report.setApplicationStatus("XMLSummary reports error") raise WorkflowProcessingException("XMLSummary reports error") - job_report.setApplicationStatus(f"{workflow_commons['application_name']} Step OK") + workflow_commons.job_report.setApplicationStatus(f"{workflow_commons.application_name} Step OK") except Exception as e: failed = True raise WorkflowProcessingException(e) from e finally: - save_workflow_commons(workflow_commons, workflow_commons_path, failed=failed) + if workflow_commons: + workflow_commons.save(job_path, failed=failed) diff --git a/src/dirac_cwl/commands/bookkeeping_report.py b/src/dirac_cwl/commands/bookkeeping_report.py index 93aacc7..e2d0138 100644 --- a/src/dirac_cwl/commands/bookkeeping_report.py +++ b/src/dirac_cwl/commands/bookkeeping_report.py @@ -3,9 +3,7 @@ import os from DIRAC.Workflow.Utilities.Utils import getStepCPUTimes -from LHCbDIRAC.BookkeepingSystem.Client.BookkeepingClient import BookkeepingClient from LHCbDIRAC.Core.Utilities.ProductionData import constructProductionLFNs -from LHCbDIRAC.Core.Utilities.XMLSummaries import XMLSummary from LHCbDIRAC.Workflow.Modules.BookkeepingReport import ( _generate_xml_object, _generateInputFiles, @@ -18,105 +16,85 @@ from dirac_cwl.core.exceptions import WorkflowProcessingException from .core import PostProcessCommand -from .utils import prepare_lhcb_workflow_commons, save_workflow_commons +from .workflow_commons import StepStatus, WorkflowCommons class BookkeepingReport(PostProcessCommand): """Generates a bookkeeping report file based on the XMLSummary and the pool XML catalog.""" - def execute(self, job_path, **kwargs): + def execute(self, job_path: os.PathLike, **kwargs): """Execute the command. :param job_path: Path to the job working directory. :param kwargs: Additional keyword arguments. """ failed = False - workflow_commons = {} + workflow_commons = None try: # Obtain Workflow Commons - workflow_commons_path = kwargs.get("workflow_commons_path", os.path.join(job_path, "workflow_commons.json")) - - workflow_commons = prepare_lhcb_workflow_commons( - workflow_commons_path, - extra_mandatory_values=[ - "bk_step_id", - ], - extra_default_values={ - "bookkeeping_LFNs": [], - "size": {}, - "md5": {}, - "guid": {}, - "sim_description": "NoSimConditions", - }, - ) + workflow_commons = WorkflowCommons.load(job_path) - if not workflow_commons["step_status"]["OK"]: + if workflow_commons.step_status == StepStatus.Failed: return # Setup variables - start_time = workflow_commons.get("start_time", None) - cpu_times = {} - if start_time: - cpu_times["StartTime"] = start_time - if "start_stats" in workflow_commons: - cpu_times["StartStats"] = workflow_commons["start_stats"] + if workflow_commons.start_time: + cpu_times["StartTime"] = workflow_commons.start_time + if workflow_commons.start_stats: + cpu_times["StartStats"] = workflow_commons.start_stats exectime, cputime = getStepCPUTimes(cpu_times) number_of_processors = getNumberOfProcessorsToUse( - workflow_commons["job_id"], workflow_commons["max_number_of_processors"] + workflow_commons.job_id, workflow_commons.max_number_of_processors ) - bk_client = BookkeepingClient() - parameters = { - "PRODUCTION_ID": workflow_commons["production_id"], - "JOB_ID": workflow_commons["prod_job_id"], - "configVersion": workflow_commons["config_version"], - "outputList": workflow_commons["outputs"], - "configName": workflow_commons["config_name"], - "outputDataFileMask": workflow_commons["output_data_file_mask"], + "PRODUCTION_ID": workflow_commons.production_id, + "JOB_ID": workflow_commons.prod_job_id, + "configVersion": workflow_commons.config_version, + "outputList": workflow_commons.outputs, + "configName": workflow_commons.config_name, + "outputDataFileMask": workflow_commons.output_data_file_mask, } - if "bookkeeping_LFNs" in workflow_commons and "production_output_data" in workflow_commons: - bk_lfns = workflow_commons["bookkeeping_LFNs"] + if workflow_commons.bookkeeping_lfns and workflow_commons.production_output_data: + bk_lfns = workflow_commons.bookkeeping_lfns if not isinstance(bk_lfns, list): bk_lfns = [i.strip() for i in bk_lfns.split(";")] else: - result = constructProductionLFNs(parameters, bk_client) + result = constructProductionLFNs(parameters, workflow_commons.bk_client) if not result["OK"]: raise WorkflowProcessingException("Could not create production LFNs") bk_lfns = result["Value"]["BookkeepingLFNs"] - ldate, ltime, ldatestart, ltimestart = _process_time(start_time) + ldate, ltime, ldatestart, ltimestart = _process_time(workflow_commons.start_time) # Obtain XMLSummary - if "xml_summary_path" in workflow_commons: - xf_o = XMLSummary(workflow_commons["xml_summary_path"]) - else: - xf_o = _generate_xml_object( - workflow_commons["cleaned_application_name"], - workflow_commons["production_id"], - workflow_commons["prod_job_id"], - workflow_commons["command_number"], - workflow_commons["command_id"], + if not workflow_commons.xf_o: + workflow_commons.xf_o = _generate_xml_object( + workflow_commons.cleaned_application_name, + workflow_commons.production_id, + workflow_commons.prod_job_id, + workflow_commons.step_number, + workflow_commons.step_id, ) info_dict = { "exectime": exectime, "cputime": cputime, "numberOfProcessors": number_of_processors, - "production_id": workflow_commons["production_id"], - "jobID": workflow_commons["job_id"], - "siteName": workflow_commons["site_name"], - "jobType": workflow_commons["job_type"], - "applicationName": workflow_commons["application_name"], - "applicationVersion": workflow_commons["application_version"], - "numberOfEvents": workflow_commons["number_of_events"], + "production_id": workflow_commons.production_id, + "jobID": workflow_commons.job_id, + "siteName": workflow_commons.site_name, + "jobType": workflow_commons.job_type, + "applicationName": workflow_commons.application_name, + "applicationVersion": workflow_commons.application_version, + "numberOfEvents": workflow_commons.number_of_events, } # Generate job_info object @@ -126,38 +104,38 @@ def execute(self, job_path, **kwargs): ltimestart, ldate, ltime, - xf_o, - workflow_commons["inputs"], - workflow_commons["command_id"], - workflow_commons["bk_step_id"], - bk_client, - workflow_commons["config_name"], - workflow_commons["config_version"], + workflow_commons.xf_o, + workflow_commons.inputs, + workflow_commons.step_id, + workflow_commons.bk_step_id, + workflow_commons.bk_client, + workflow_commons.config_name, + workflow_commons.config_version, ) # Add input files to job_info - _generateInputFiles(job_info, bk_lfns, workflow_commons["inputs"]) + _generateInputFiles(job_info, bk_lfns, workflow_commons.inputs) # Add output files to job_info _generateOutputFiles( job_info, bk_lfns, - workflow_commons["event_type"], - workflow_commons["application_name"], - xf_o, - workflow_commons["outputs"], - workflow_commons["inputs"], + workflow_commons.event_type, + workflow_commons.application_name, + workflow_commons.xf_o, + workflow_commons.outputs, + workflow_commons.inputs, ) # Generate SimulationConditions - if workflow_commons["application_name"] == "Gauss": - job_info.simulation_condition = workflow_commons["sim_description"] + if workflow_commons.application_name == "Gauss": + job_info.simulation_condition = workflow_commons.sim_description # Convert job_info object to XML doc = job_info.to_xml() # Write to file - bfilename = f"bookkeeping_{workflow_commons['command_id']}.xml" + bfilename = f"bookkeeping_{workflow_commons.step_id}.xml" with open(bfilename, "wb") as bfile: bfile.write(doc) @@ -166,4 +144,5 @@ def execute(self, job_path, **kwargs): raise WorkflowProcessingException(e) from e finally: - save_workflow_commons(workflow_commons, workflow_commons_path, failed=failed) + if workflow_commons: + workflow_commons.save(job_path, failed=failed) diff --git a/src/dirac_cwl/commands/failover_request.py b/src/dirac_cwl/commands/failover_request.py index c578825..d4297bf 100644 --- a/src/dirac_cwl/commands/failover_request.py +++ b/src/dirac_cwl/commands/failover_request.py @@ -6,17 +6,13 @@ import json import os -from DIRAC.AccountingSystem.Client.DataStoreClient import DataStoreClient -from DIRAC.RequestManagementSystem.Client.Request import Request from DIRAC.RequestManagementSystem.private.RequestValidator import RequestValidator -from DIRAC.TransformationSystem.Client.FileReport import FileReport -from DIRAC.WorkloadManagementSystem.Client.JobReport import JobReport from LHCbDIRAC.Workflow.Modules.FailoverRequest import _prepareRequest from dirac_cwl.core.exceptions import WorkflowProcessingException from .core import PostProcessCommand -from .utils import prepare_lhcb_workflow_commons, save_workflow_commons +from .workflow_commons import StepStatus, WorkflowCommons class FailoverRequest(PostProcessCommand): @@ -25,91 +21,79 @@ class FailoverRequest(PostProcessCommand): The status will be "Processed" if everything ended properly or "Unused" if it did not. """ - def execute(self, job_path, **kwargs): + def execute(self, job_path: os.PathLike, **kwargs): """Execute the command. :param job_path: Path to the job working directory. :param kwargs: Additional keyword arguments. """ failed = False - workflow_commons = {} + workflow_commons = None try: - workflow_commons_path = kwargs.get("workflow_commons_path", os.path.join(job_path, "workflow_commons.json")) + workflow_commons = WorkflowCommons.load(job_path) - workflow_commons = prepare_lhcb_workflow_commons( - workflow_commons_path, - extra_mandatory_values=[], - extra_default_values={"accounting_registers": None}, - ) + _prepareRequest(workflow_commons.request, workflow_commons.job_id) - request = Request(workflow_commons["request_dict"]) - file_report = FileReport() - file_report.statusDict = workflow_commons["file_report_files_dict"] + filesInFileReport = workflow_commons.file_report.getFiles() - job_report = JobReport(workflow_commons["job_id"]) - - _prepareRequest(request, workflow_commons["job_id"]) - - filesInFileReport = file_report.getFiles() - - for lfn in workflow_commons["inputs"]: + for lfn in workflow_commons.inputs: if lfn not in filesInFileReport: - status = "Processed" if workflow_commons["step_status"]["OK"] else "Unused" - file_report.setFileStatus(int(workflow_commons["production_id"]), lfn, status) + status = "Processed" if workflow_commons.step_status == StepStatus.Done else "Unused" + workflow_commons.file_report.setFileStatus(int(workflow_commons.production_id), lfn, status) - file_report.commit() + workflow_commons.file_report.commit() - if workflow_commons["step_status"]["OK"]: - if file_report.getFiles(): - result = file_report.generateForwardDISET() + if workflow_commons.step_status == StepStatus.Done: + if workflow_commons.file_report.getFiles(): + result = workflow_commons.file_report.generateForwardDISET() if result["OK"] and result["Value"]: - request.addOperation(result["Value"]) + workflow_commons.request.addOperation(result["Value"]) - job_report.setApplicationStatus("Job Finished Successfully", True) + workflow_commons.job_report.setApplicationStatus("Job Finished Successfully", True) - self.generateFailoverFile(job_report, request, workflow_commons) + self.generateFailoverFile(workflow_commons) except Exception as e: failed = True raise WorkflowProcessingException(e) from e finally: - save_workflow_commons(workflow_commons, workflow_commons_path, request=request, failed=failed) + if workflow_commons: + workflow_commons.save(job_path, failed=failed) - def generateFailoverFile(self, job_report, request, workflow_commons): - """Create a request.json file.""" - result = job_report.generateForwardDISET() + def generateFailoverFile(self, workflow_commons: WorkflowCommons): + """Create a workflow_commons.request.json file.""" + result = workflow_commons.job_report.generateForwardDISET() if result["OK"]: if result["Value"]: - request.addOperation(result["Value"]) + workflow_commons.request.addOperation(result["Value"]) - if len(request): + if len(workflow_commons.request): # Try to optimize the request try: - request.optimize() - except: # noqa: E722 + workflow_commons.request.optimize() + except Exception: # noqa: E722 pass - # Validate request - result = RequestValidator().validate(request) + # Validate workflow_commons.request + result = RequestValidator().validate(workflow_commons.request) if not result["OK"]: raise WorkflowProcessingException( - "Failed to generate FailoverFile. Invalid request object", result["Message"] + "Failed to generate FailoverFile. Invalid workflow_commons.request object", result["Message"] ) - # Get the request as a Json - result = request.toJSON() + # Get the workflow_commons.request as a Json + result = workflow_commons.request.toJSON() if not result["OK"]: raise WorkflowProcessingException(result["Message"]) # Write it - fname = f"{workflow_commons['production_id']}_{workflow_commons['prod_job_id']}_request.json" + fname = f"{workflow_commons.production_id}_{workflow_commons.prod_job_id}_request.json" with open(fname, "w", encoding="utf-8") as f: json.dump(result["Value"], f) - if workflow_commons["accounting_registers"]: - dsc = DataStoreClient() - for register in workflow_commons["accounting_registers"]: - dsc.addRegister(register) - dsc.commit() + if workflow_commons.accounting_registers: + for register in workflow_commons.accounting_registers: + workflow_commons.dsc.addRegister(register) + workflow_commons.dsc.commit() diff --git a/src/dirac_cwl/commands/upload_log_file.py b/src/dirac_cwl/commands/upload_log_file.py index f26e6db..930c033 100644 --- a/src/dirac_cwl/commands/upload_log_file.py +++ b/src/dirac_cwl/commands/upload_log_file.py @@ -6,11 +6,7 @@ from DIRAC.ConfigurationSystem.Client.Helpers.Operations import Operations from DIRAC.Core.Utilities.ReturnValues import returnSingleResult from DIRAC.Core.Utilities.Subprocess import systemCall -from DIRAC.DataManagementSystem.Client.FailoverTransfer import FailoverTransfer -from DIRAC.RequestManagementSystem.Client.Request import Request from DIRAC.Resources.Storage.StorageElement import StorageElement -from DIRAC.WorkloadManagementSystem.Client.JobReport import JobReport -from LHCbDIRAC.BookkeepingSystem.Client.BookkeepingClient import BookkeepingClient from LHCbDIRAC.Core.Utilities.ProductionData import getLogPath from LHCbDIRAC.Workflow.Modules.FailoverRequest import _prepareRequest from LHCbDIRAC.Workflow.Modules.UploadLogFile import ( @@ -26,13 +22,13 @@ from dirac_cwl.core.exceptions import WorkflowProcessingException from .core import PostProcessCommand -from .utils import prepare_lhcb_workflow_commons, save_workflow_commons +from .workflow_commons import StepStatus, WorkflowCommons class UploadLogFile(PostProcessCommand): """Post-processing command for log file uploading.""" - def execute(self, job_path, **kwargs): + def execute(self, job_path: os.PathLike, **kwargs): """Execute the log uploading process. :param job_path: Path to the job working directory. @@ -40,30 +36,22 @@ def execute(self, job_path, **kwargs): """ # Obtain workflow information failed = False - workflow_commons = {} - request = None + workflow_commons = None try: - workflow_commons_path = kwargs.get("workflow_commons_path", os.path.join(job_path, "workflow_commons.json")) + workflow_commons = WorkflowCommons.load(job_path) - workflow_commons = prepare_lhcb_workflow_commons( - workflow_commons_path, - extra_mandatory_values=[], - extra_default_values={"log_target_path": None, "log_file_path": ""}, - ) - request = Request(workflow_commons["request_dict"]) - - if not workflow_commons["step_status"]["OK"]: + if workflow_commons.step_status == StepStatus.Failed: return - log_lfn_path = workflow_commons["log_target_path"] + log_lfn_path = workflow_commons.log_target_path if not log_lfn_path: parameters = { - "PRODUCTION_ID": workflow_commons["production_id"], - "JOB_ID": workflow_commons["job_id"], - "configName": workflow_commons["config_name"], - "configVersion": workflow_commons["config_version"], + "PRODUCTION_ID": workflow_commons.production_id, + "JOB_ID": workflow_commons.job_id, + "configName": workflow_commons.config_name, + "configVersion": workflow_commons.config_version, } - result = getLogPath(parameters, BookkeepingClient()) + result = getLogPath(parameters, workflow_commons.bk_client) if not result["OK"]: raise WorkflowProcessingException("Could not create LogFilePath", result["Message"]) log_lfn_path = result["Value"]["LogTargetPath"][0] @@ -71,22 +59,18 @@ def execute(self, job_path, **kwargs): if not isinstance(log_lfn_path, str): log_lfn_path = log_lfn_path[0] - workflow_commons["log_lfn_path"] = log_lfn_path + workflow_commons.log_lfn_path = log_lfn_path ops = Operations() log_se = ops.getValue("LogStorage/LogSE", "LogSE") log_extensions = ops.getValue("LogFiles/Extensions", []) - _prepareRequest(request, workflow_commons["job_id"]) - failover_transfer = FailoverTransfer(request) - job_report = JobReport(workflow_commons["job_id"]) + _prepareRequest(workflow_commons.request, workflow_commons.job_id) res = systemCall(0, shlex.split("ls -al")) - workflow_commons["log_dir"] = os.path.realpath( - os.path.join( - job_path, f"./job/log/{workflow_commons['production_id']}/{workflow_commons['prod_job_id']}" - ) + workflow_commons.log_dir = os.path.realpath( + os.path.join(job_path, f"./job/log/{workflow_commons.production_id}/{workflow_commons.prod_job_id}") ) ########################################## @@ -98,48 +82,44 @@ def execute(self, job_path, **kwargs): ######################################### # Create a temporary directory containing these files - res = _populateLogDirectory(selectedFiles, workflow_commons["log_dir"]) + res = _populateLogDirectory(selectedFiles, workflow_commons.log_dir) if not res["OK"]: - job_report.setApplicationStatus("Failed To Populate Log Dir") + workflow_commons.job_report.setApplicationStatus("Failed To Populate Log Dir") return ######################################### # Make sure all the files in the log directory have the correct permissions - result = _setLogFilePermissions(workflow_commons["log_dir"]) + result = _setLogFilePermissions(workflow_commons.log_dir) # zip all files - result = _zip_files(workflow_commons["prod_job_id"], selectedFiles) + result = _zip_files(workflow_commons.prod_job_id, selectedFiles) if not result["OK"]: - job_report.setApplicationStatus("Failed to create zip of log files") + workflow_commons.job_report.setApplicationStatus("Failed to create zip of log files") return zip_file_name = result["Value"] - # Instantiate the failover transfer client with the global request object - if not failover_transfer: - failover_transfer = FailoverTransfer(request) - # logFilePath is something like /lhcb/MC/2016/LOG/00095376/0000/ # the zipFileName should have the same name, e.g. 00000381.zip - zipPath = os.path.join(workflow_commons["log_file_path"], zip_file_name) + zipPath = os.path.join(workflow_commons.log_file_path, zip_file_name) logHttpsURL = _get_log_url(log_se, zipPath) res = returnSingleResult(StorageElement(log_se).putFile({zipPath: zip_file_name})) if not res["OK"]: result = _uploadLogToFailoverSE( - failover_transfer, zip_file_name, log_lfn_path, workflow_commons["site_name"] + workflow_commons.failover_request, zip_file_name, log_lfn_path, workflow_commons.site_name ) if not result["OK"]: - job_report.setApplicationStatus("Failed To Upload Logs") + workflow_commons.job_report.setApplicationStatus("Failed To Upload Logs") else: uploadedSE = result["Value"]["uploadedSE"] - request = failover_transfer.request + request = workflow_commons.failover_request.request _createLogUploadRequest(request, log_se, log_lfn_path, uploadedSE) # While it's the zip file that is uploaded, we set in job parameters its directory, # as the .zip is deflated automatically - job_report.setJobParameter( + workflow_commons.job_report.setJobParameter( "Log URL", f"Log file directory" ) @@ -148,4 +128,5 @@ def execute(self, job_path, **kwargs): raise WorkflowProcessingException(e) from e finally: - save_workflow_commons(workflow_commons, workflow_commons_path, request, failed=failed) + if workflow_commons: + workflow_commons.save(job_path, failed=failed) diff --git a/src/dirac_cwl/commands/upload_output_data.py b/src/dirac_cwl/commands/upload_output_data.py index 910e95b..b66ac2f 100644 --- a/src/dirac_cwl/commands/upload_output_data.py +++ b/src/dirac_cwl/commands/upload_output_data.py @@ -3,12 +3,6 @@ import os import random -from DIRAC.DataManagementSystem.Client.DataManager import DataManager -from DIRAC.DataManagementSystem.Client.FailoverTransfer import FailoverTransfer -from DIRAC.RequestManagementSystem.Client.Request import Request -from DIRAC.TransformationSystem.Client.FileReport import FileReport -from DIRAC.WorkloadManagementSystem.Client.JobReport import JobReport -from LHCbDIRAC.BookkeepingSystem.Client.BookkeepingClient import BookkeepingClient from LHCbDIRAC.Core.Utilities.ProductionData import constructProductionLFNs from LHCbDIRAC.Core.Utilities.ResolveSE import getDestinationSEList from LHCbDIRAC.DataManagementSystem.Client.ConsistencyChecks import getFileDescendents @@ -25,72 +19,51 @@ from dirac_cwl.core.exceptions import WorkflowProcessingException from .core import PostProcessCommand -from .utils import prepare_lhcb_workflow_commons, save_workflow_commons +from .workflow_commons import StepStatus, WorkflowCommons class UploadOutputData(PostProcessCommand): """Registers every output generated to the corresponding SE and Catalog or to the FailoverSE in case of failure.""" - def execute(self, job_path, **kwargs): + def execute(self, job_path: os.PathLike, **kwargs): """Execute the command. :param job_path: Path to the job working directory. :param kwargs: Additional keyword arguments. """ failed = False - workflow_commons = {} - request = None + workflow_commons = None try: - workflow_commons_path = kwargs.get("workflow_commons_path", os.path.join(job_path, "workflow_commons.json")) - - workflow_commons = prepare_lhcb_workflow_commons( - workflow_commons_path, - extra_mandatory_values=["output_data_step", "output_SEs"], - extra_default_values={ - "file_descendants": None, - "prod_output_LFNs": None, - "run_number": "Unknown", - "output_mode": "Any", - }, - ) - request = Request(workflow_commons["request_dict"]) + workflow_commons = WorkflowCommons.load(job_path) - if not workflow_commons["step_status"]["OK"]: + if workflow_commons.step_status == StepStatus.Failed: return - bk_client = BookkeepingClient() - data_manager = DataManager() - - failover_se_list = getDestinationSEList("Tier1-Failover", workflow_commons["site_name"], outputmode="Any") + failover_se_list = getDestinationSEList("Tier1-Failover", workflow_commons.site_name, outputmode="Any") random.shuffle(failover_se_list) - file_report = FileReport() - file_report.statusDict = workflow_commons["file_report_files_dict"] - - job_report = JobReport(workflow_commons["job_id"]) - - if not workflow_commons["prod_output_LFNs"]: + if not workflow_commons.prod_output_lfns: parameters = { - "PRODUCTION_ID": workflow_commons["production_id"], - "JOB_ID": workflow_commons["job_id"], - "configVersion": workflow_commons["config_version"], - "outputList": workflow_commons["outputs"], - "configName": workflow_commons["config_name"], - "outputDataFileMask": workflow_commons["output_data_file_mask"], + "PRODUCTION_ID": workflow_commons.production_id, + "JOB_ID": workflow_commons.job_id, + "configVersion": workflow_commons.config_version, + "outputList": workflow_commons.outputs, + "configName": workflow_commons.config_name, + "outputDataFileMask": workflow_commons.output_data_file_mask, } - result = constructProductionLFNs(parameters, bk_client) + result = constructProductionLFNs(parameters, workflow_commons.bk_client) if not result["OK"]: raise WorkflowProcessingException("Unable to construsct production LFNs") - workflow_commons["prod_output_LFNs"] = result["Value"]["ProductionOutputData"] + workflow_commons.prod_output_lfns = result["Value"]["ProductionOutputData"] file_metadata = _getFileMetada( - workflow_commons["outputs"], - workflow_commons["prod_output_LFNs"], - workflow_commons["output_data_file_mask"], - workflow_commons["output_data_step"], - workflow_commons["output_SEs"], + workflow_commons.outputs, + workflow_commons.prod_output_lfns, + workflow_commons.output_data_file_mask, + workflow_commons.output_data_step, + workflow_commons.output_SEs, ) if not file_metadata: @@ -99,25 +72,25 @@ def execute(self, job_path, **kwargs): final = _resolveSEs( file_metadata, None, - workflow_commons["site_name"], - workflow_commons["output_mode"], - workflow_commons["run_number"], + workflow_commons.site_name, + workflow_commons.output_mode, + workflow_commons.run_number, ) - if workflow_commons["inputs"]: - lfns_with_descendants = workflow_commons["file_descendants"] + if workflow_commons.inputs: + lfns_with_descendants = workflow_commons.file_descendants if not lfns_with_descendants: lfns_with_descendants = getFileDescendents( - workflow_commons["production_id"], - workflow_commons["inputs"], - dm=data_manager, - bkClient=bk_client, + workflow_commons.production_id, + workflow_commons.inputs, + dm=workflow_commons.data_manager, + bkClient=workflow_commons.bk_client, ) if lfns_with_descendants: - file_report.setFileStatus( - int(workflow_commons["production_id"]), lfns_with_descendants, "Processed" + workflow_commons.file_report.setFileStatus( + int(workflow_commons.production_id), lfns_with_descendants, "Processed" ) raise WorkflowProcessingException("Input Data Already Processed") @@ -127,9 +100,7 @@ def execute(self, job_path, **kwargs): with open(bkFile) as fd: bkXML = fd.read() - result = _sendBKReport(bk_client, request, bkXML) - - failover_transfer = FailoverTransfer(request) + result = _sendBKReport(workflow_commons.bk_client, workflow_commons.request, bkXML) perform_bk_registration = [] @@ -137,7 +108,7 @@ def execute(self, job_path, **kwargs): for file_name, metadata in final.items(): targetSE = metadata["resolvedSE"] file_meta_dict = _createMetaDict(metadata) - result = failover_transfer.transferAndRegisterFile( + result = workflow_commons.failover_request.transferAndRegisterFile( fileName=file_name, localPath=metadata["localpath"], lfn=metadata["filedict"]["LFN"], @@ -150,14 +121,14 @@ def execute(self, job_path, **kwargs): else: perform_bk_registration.append(metadata) - cleanUp = False + clean_up = False for file_name, metadata in failover.items(): random.shuffle(failover_se_list) targetSE = metadata["resolvedSE"][0] metadata["resolvedSE"] = failover_se_list file_meta_dict = _createMetaDict(metadata) - result = failover_transfer.transferAndRegisterFileFailover( + result = workflow_commons.failover_request.transferAndRegisterFileFailover( fileName=file_name, localPath=metadata["localpath"], lfn=metadata["filedict"]["LFN"], @@ -167,20 +138,20 @@ def execute(self, job_path, **kwargs): masterCatalogOnly=True, ) if not result["OK"]: - cleanUp = True + clean_up = True break - request = failover_transfer.request - if cleanUp: - request = _getCleanRequest(request, final) + workflow_commons.request = workflow_commons.failover_request.request + if clean_up: + workflow_commons.request = _getCleanRequest(workflow_commons.request, final) raise WorkflowProcessingException("Failed to upload output data") if final: report = ", ".join(final) - job_report.setJobParameter("UploadedOutputData", report) + workflow_commons.job_report.setJobParameter("UploadedOutputData", report) if perform_bk_registration: - result = _registerLFNs(request, perform_bk_registration) + result = _registerLFNs(workflow_commons.request, perform_bk_registration) if not result["OK"]: raise WorkflowProcessingException(result["Message"]) @@ -189,4 +160,5 @@ def execute(self, job_path, **kwargs): raise WorkflowProcessingException(e) from e finally: - save_workflow_commons(workflow_commons, workflow_commons_path, request=request, failed=failed) + if workflow_commons: + workflow_commons.save(job_path, failed=failed) diff --git a/src/dirac_cwl/commands/utils.py b/src/dirac_cwl/commands/utils.py deleted file mode 100644 index 4521452..0000000 --- a/src/dirac_cwl/commands/utils.py +++ /dev/null @@ -1,128 +0,0 @@ -""".""" - -import json -import os -import shutil - -from DIRAC import siteName -from DIRAC.Core.Utilities.ReturnValues import S_ERROR, S_OK - -from dirac_cwl.core.exceptions import WorkflowProcessingException - - -def prepare_lhcb_workflow_commons(workflow_commons_path, extra_mandatory_values=[], extra_default_values={}): - """Return a dictionary containing the values of a workflow_commons.json file. - - Also performs a series of checks to ensure everything is in order. - """ - if not os.path.exists(workflow_commons_path): - raise WorkflowProcessingException(f"{workflow_commons_path} file not found") - - with open(workflow_commons_path, "r", encoding="utf-8") as f: - workflow_commons = json.load(f) - - if not workflow_commons: - raise WorkflowProcessingException(f"{workflow_commons_path} cannot be empty") - - mandatory_values = [ - "job_id", - "job_type", - "production_id", - "prod_job_id", - "number_of_events", - "application_name", - "application_version", - "inputs", - "outputs", # outputList - "executable", - "command_id", # StepID - "command_number", - ] - - mandatory_values.extend(extra_mandatory_values) - missing_values = [] - - for value in mandatory_values: - if value not in workflow_commons: - missing_values.append(value) - - if missing_values: - raise WorkflowProcessingException( - f"The following values are missing in workflow_commons.json: {missing_values}" - ) - - commons_defaults = { - "output_data_file_mask": "", - "run_metadata": {}, - "log_target_path": "", - "production_output_data": [], - "CPUe": 0, - "max_number_of_events": "0", - "output_data_type": None, - "application_log": "", - "application_type": None, - "options_file": None, - "options_line": None, - "extra_packages": "", - "multi_core": False, - "max_number_of_processors": None, - "system_config": None, - "mcTCK": None, - "condDB_tag": None, - "DQ_tag": None, - "step_status": S_OK(), - "config_name": None, - "config_version": None, - "request_dict": {}, - "file_report_files_dict": {}, - "number_of_processors": 1, - } - - for k, v in extra_default_values.items(): - if k not in commons_defaults: - commons_defaults[k] = v - - for k, v in commons_defaults.items(): - if k not in workflow_commons: - workflow_commons[k] = v - - cleaned_application_name = workflow_commons["application_name"].replace("/", "") - workflow_commons["cleaned_application_name"] = cleaned_application_name - - workflow_commons["site_name"] = siteName() - - return workflow_commons - - -def save_workflow_commons(wf_commons, wf_file_path, request=None, failed=False): - """Update the workflow_commons file to accomodate for the new values. - - Ensures that no data is lost during the update by creating a backup. - """ - if not (os.path.exists(wf_file_path) and os.path.isfile(wf_file_path)): - raise WorkflowProcessingException(f"Workflow Commons file '{wf_file_path}' not found") - - wf_filename = os.path.basename(wf_file_path) - wf_base_path = os.path.dirname(wf_file_path) - wf_backup = os.path.join(wf_base_path, f"{wf_filename}.bak") - - shutil.move(wf_file_path, wf_backup) - - if failed: - wf_commons["step_status"] = S_ERROR() - - if request: - wf_commons["request_dict"] = json.loads(request.toJSON()["Value"]) - - try: - with open(wf_file_path, "x", encoding="utf-8") as f: - json.dump(wf_commons, f) - except Exception: - os.unlink(wf_file_path) - shutil.copy2(wf_backup, wf_file_path) - return False - - finally: - os.unlink(wf_backup) - - return True diff --git a/src/dirac_cwl/commands/workflow_accounting.py b/src/dirac_cwl/commands/workflow_accounting.py index 8758f54..29b75e1 100644 --- a/src/dirac_cwl/commands/workflow_accounting.py +++ b/src/dirac_cwl/commands/workflow_accounting.py @@ -3,102 +3,80 @@ Formerly known as StepAccounting. """ +import datetime import os -from datetime import datetime from DIRAC import gConfig -from DIRAC.AccountingSystem.Client.DataStoreClient import DataStoreClient from DIRAC.Workflow.Utilities.Utils import getStepCPUTimes from LHCbDIRAC.AccountingSystem.Client.Types.JobStep import JobStep -from LHCbDIRAC.Core.Utilities.XMLSummaries import XMLSummary -from LHCbDIRAC.Workflow.Modules.BookkeepingReport import _generate_xml_object from dirac_cwl.core.exceptions import WorkflowProcessingException from .core import PostProcessCommand -from .utils import prepare_lhcb_workflow_commons, save_workflow_commons +from .workflow_commons import WorkflowCommons class WorkflowAccounting(PostProcessCommand): """Prepares and sends accounting information to the DIRAC Accounting system.""" - def execute(self, job_path, **kwargs): + def execute(self, job_path: os.PathLike, **kwargs): """Execute the command. :param job_path: Path to the job working directory. :param kwargs: Additional keyword arguments. """ failed = False - workflow_commons = {} + workflow_commons = None try: # Obtain Workflow Commons - workflow_commons_path = kwargs.get("workflow_commons_path", os.path.join(job_path, "workflow_commons.json")) - workflow_commons = {} - workflow_commons = prepare_lhcb_workflow_commons( - workflow_commons_path, - extra_mandatory_values=["bk_step_id", "step_proc_pass", "event_type"], - extra_default_values={ - "step_proc_pass": "", - "run_number": "Unknown", - }, - ) + workflow_commons = WorkflowCommons.load(job_path) cpu_times = {} if "start_time" in workflow_commons: - cpu_times["StartTime"] = workflow_commons["start_time"] + cpu_times["StartTime"] = workflow_commons.start_time if "start_stats" in workflow_commons: - cpu_times["StartStats"] = workflow_commons["start_stats"] + cpu_times["StartStats"] = workflow_commons.start_stats exec_time, cpu_time = getStepCPUTimes(cpu_times) cpuNormFactor = gConfig.getValue("/LocalSite/CPUNormalizationFactor", 0.0) normCPU = cpu_time * cpuNormFactor - jobStep = JobStep() - - if "xml_summary_path" in workflow_commons: - xf_o = XMLSummary(workflow_commons["xml_summary_path"]) - else: - xf_o = _generate_xml_object( - workflow_commons["cleaned_application_name"], - workflow_commons["production_id"], - workflow_commons["prod_job_id"], - workflow_commons["command_number"], - workflow_commons["command_id"], - ) + job_step = JobStep() + + if not workflow_commons.xf_o: + return - now = datetime.utcnow() - jobStep.setStartTime(now) - jobStep.setEndTime(now) + now = datetime.datetime.now(datetime.UTC) + job_step.setStartTime(now) + job_step.setEndTime(now) dataDict = { - "JobGroup": str(workflow_commons["production_id"]), - "RunNumber": workflow_commons["run_number"], - "EventType": workflow_commons["event_type"], - "ProcessingType": workflow_commons["step_proc_pass"], # this is the processing pass of the step - "ProcessingStep": workflow_commons["bk_step_id"], # the step ID - "Site": workflow_commons["site_name"], - "FinalStepState": workflow_commons["step_status"], + "JobGroup": str(workflow_commons.production_id), + "RunNumber": workflow_commons.run_number, + "EventType": workflow_commons.event_type, + "ProcessingType": workflow_commons.step_proc_pass, # this is the processing pass of the step + "ProcessingStep": workflow_commons.bk_step_id, # the step ID + "Site": workflow_commons.site_name, + "FinalStepState": workflow_commons.step_status, "CPUTime": cpu_time, "NormCPUTime": normCPU, - "ExecTime": exec_time * workflow_commons["number_of_processors"], - "InputData": sum(xf_o.inputFileStats.values()), - "OutputData": sum(xf_o.outputFileStats.values()), - "InputEvents": xf_o.inputEventsTotal, - "OutputEvents": xf_o.outputEventsTotal, + "ExecTime": exec_time * workflow_commons.number_of_processors, + "InputData": sum(workflow_commons.xf_o.inputFileStats.values()), + "OutputData": sum(workflow_commons.xf_o.outputFileStats.values()), + "InputEvents": workflow_commons.xf_o.inputEventsTotal, + "OutputEvents": workflow_commons.xf_o.outputEventsTotal, } - jobStep.setValuesFromDict(dataDict) + job_step.setValuesFromDict(dataDict) - res = jobStep.checkValues() + res = job_step.checkValues() if not res["OK"]: raise WorkflowProcessingException( "Values for StepAccounting are wrong:", f"{res['Message']}. Here are the given data: {dataDict}" ) - dsc = DataStoreClient() - dsc.addRegister(jobStep) - workflow_commons["accounting_registers"] = dsc.__registersList + workflow_commons.accounting_registers.append(list(job_step.getValues())) except Exception as e: failed = True @@ -106,4 +84,4 @@ def execute(self, job_path, **kwargs): finally: if workflow_commons: - save_workflow_commons(workflow_commons, workflow_commons_path, failed=failed) + workflow_commons.save(job_path, failed=failed) diff --git a/src/dirac_cwl/commands/workflow_commons.py b/src/dirac_cwl/commands/workflow_commons.py new file mode 100644 index 0000000..895f007 --- /dev/null +++ b/src/dirac_cwl/commands/workflow_commons.py @@ -0,0 +1,221 @@ +"""Workflow common values shared between steps.""" + +import json +import os +import shutil +from enum import Enum +from pathlib import Path +from typing import Any, Optional + +from DIRAC import siteName +from DIRAC.AccountingSystem.Client.DataStoreClient import DataStoreClient +from DIRAC.DataManagementSystem.Client.DataManager import DataManager +from DIRAC.DataManagementSystem.Client.FailoverTransfer import FailoverTransfer +from DIRAC.RequestManagementSystem.Client.Request import Request +from DIRAC.TransformationSystem.Client.FileReport import FileReport +from DIRAC.WorkloadManagementSystem.Client.JobReport import JobReport +from LHCbDIRAC.BookkeepingSystem.Client.BookkeepingClient import BookkeepingClient +from LHCbDIRAC.Core.Utilities.XMLSummaries import XMLSummary +from pydantic import BaseModel, ConfigDict, PrivateAttr + + +class StepStatus(str, Enum): + """Workflow status.""" + + Done = "Done" + Failed = "Failed" + + +class WorkflowCommons(BaseModel): + """Workflow information for command processing.""" + + # Mandatory Values + job_id: int + job_type: str + production_id: str + prod_job_id: str + + inputs: list[str] + outputs: list[dict[str, Any]] + + number_of_events: int + event_type: str + + step_id: str + step_number: int + + config_version: str + config_name: str + + # Optional values + executable: str = "gaudirun.py" + application_name: str = "Unknown" + application_version: str = "Unknown" + + production_output_data: list[str] = [] + output_data_file_mask: str = "" + output_data_type: str = "" + output_data_step: str = "" + output_SEs: dict[str, str] = {} + output_mode: str = "" + + log_target_path: str = "" + log_file_path: str = "" + log_lfn_path: str = "" + log_dir: str = "" + + application_log: str = "" + application_type: str = "" + cleaned_application_name: str = "" + + number_of_processors: int = 1 + max_number_of_processors: int = 0 + + step_proc_pass: str = "" + run_number: str = "Unknown" + sim_description: str = "NoSimConditions" + + file_descendents: list[str] = [] + file_size_map: dict[str, str] = {} + file_md5_map: dict[str, str] = {} + file_guid_map: dict[str, str] = {} + + file_descendants: list[str] = [] + bookkeeping_lfns: list[str] = [] + prod_output_lfns: list[str] = [] + + file_report_files_dict: dict = {} + accounting_registers: list = [] + xml_summary_path: str = "" + request_dict: dict = {} + files_report_files_dict: dict = {} + + bk_step_id: Optional[int] = None + start_stats: Optional[tuple] = None + start_time: Optional[float] = None + + site_name: str = "" + step_status: StepStatus = StepStatus.Done + + # Private attributes + _request = PrivateAttr(default=None) + _failover_request = PrivateAttr(default=None) + _job_report = PrivateAttr(default=None) + _file_report = PrivateAttr(default=None) + _data_manager = PrivateAttr(default=None) + _bk_client = PrivateAttr(default=None) + _dsc = PrivateAttr(default=None) + _xf_o = PrivateAttr(default=None) + + model_config = ConfigDict( + validate_assignment=True, + ) + + def __init__(self, **data): + """WorkflowCommons constructor.""" + super().__init__(**data) + + self.cleaned_application_name = self.application_name.replace("/", "") + self.site_name = siteName() + + self._request = Request(fromDict=self.request_dict) + + self._failover_request = FailoverTransfer(self.request) + + self._job_report = JobReport(self.job_id) + + self._file_report = FileReport() + self._file_report.statusDict = self.file_report_files_dict + + self._data_manager = DataManager() + self._bk_client = BookkeepingClient() + self._dsc = DataStoreClient() + + if self.xml_summary_path: + self._xf_o = XMLSummary(self.xml_summary_path) + + def save(self, job_path: os.PathLike, failed: bool = False): + """Update the workflow_commons file to accomodate for the new values.""" + wf_path = Path(job_path).joinpath("workflow_commons.json") + wf_backup = Path(job_path).joinpath("workflow_commons.json.back") + + shutil.move(wf_path, wf_backup) + + if failed: + self.step_status = StepStatus.Failed + + self.request_dict = json.loads(self.request.toJSON()["Value"]) + + try: + wf_dict = self.model_dump(mode="json") + with open(wf_path, "w", encoding="utf-8") as f: + json.dump(wf_dict, f) + except Exception: + raise + finally: + wf_backup.unlink() + + @classmethod + def load(cls, job_path: os.PathLike): + """Return a WorkflowCommons containing the values of a workflow_commons.json file. + + :raises: ValidationError + """ + wf_path = os.path.join(job_path, "workflow_commons.json") + + with open(wf_path, "r", encoding="utf-8") as f: + wf_dict = json.load(f) + + return cls(**wf_dict) + + # Properties + + @property + def request(self) -> Request: + """Request property getter.""" + return self._request + + @request.setter + def request(self, value: Request) -> None: + """Request property setter.""" + self._request = value + + @property + def failover_request(self) -> FailoverTransfer: + """FailoverTransfer property getter.""" + return self._failover_request + + @property + def job_report(self) -> JobReport: + """JobReport property getter.""" + return self._job_report + + @property + def file_report(self) -> FileReport: + """FileReport property getter.""" + return self._file_report + + @property + def data_manager(self) -> DataManager: + """DataManager property getter.""" + return self._data_manager + + @property + def bk_client(self) -> BookkeepingClient: + """BookkeepingClient property getter.""" + return self._bk_client + + @property + def dsc(self) -> DataStoreClient: + """DataStoreClient property getter.""" + return self._dsc + + @property + def xf_o(self) -> XMLSummary: + """XMLSummary property getter.""" + return self._xf_o + + @xf_o.setter + def xf_o(self, xf_o: XMLSummary) -> None: + """XMLSummary property getter.""" + self._xf_o = xf_o diff --git a/test/test_commands.py b/test/test_commands.py index 574f0bc..c662b91 100644 --- a/test/test_commands.py +++ b/test/test_commands.py @@ -15,15 +15,10 @@ import LHCbDIRAC import pytest from DIRAC import siteName -from DIRAC.AccountingSystem.Client.DataStoreClient import DataStoreClient -from DIRAC.DataManagementSystem.Client.FailoverTransfer import FailoverTransfer from DIRAC.RequestManagementSystem.Client.File import File from DIRAC.RequestManagementSystem.Client.Operation import Operation from DIRAC.RequestManagementSystem.Client.Request import Request -from DIRAC.TransformationSystem.Client.FileReport import FileReport -from DIRAC.WorkloadManagementSystem.Client.JobReport import JobReport from DIRACCommon.Core.Utilities.ReturnValues import S_ERROR, S_OK -from LHCbDIRAC.BookkeepingSystem.Client.BookkeepingClient import BookkeepingClient from LHCbDIRAC.Core.Utilities.XMLSummaries import XMLSummary from pytest_mock import MockerFixture @@ -35,10 +30,11 @@ UploadOutputData, WorkflowAccounting, ) +from dirac_cwl.commands.workflow_commons import StepStatus, WorkflowCommons from dirac_cwl.core.exceptions import WorkflowProcessingException number_of_processors = 1 -job_path = "." +job_path = Path(".") @pytest.fixture @@ -55,12 +51,11 @@ def wf_commons(): "config_version": "aConfigVersion", "application_name": "someApp", "application_version": "v1r0", - "bk_step_id": "123", "inputs": [], "outputs": [], "executable": "", - "command_id": "1", - "command_number": 1, + "step_id": "1", + "step_number": 1, } Path(os.path.join(job_path, "workflow_commons.json")).unlink(missing_ok=True) @@ -71,7 +66,7 @@ def xml_summary_file(wf_commons): """XMLSummaryFile file path fixture.""" path = os.path.join( job_path, - f"summary{wf_commons['application_name']}_{wf_commons['production_id']}_{wf_commons['prod_job_id']}_{wf_commons['command_id']}.xml", + f"summary{wf_commons['application_name']}_{wf_commons['production_id']}_{wf_commons['prod_job_id']}_{wf_commons['step_id']}.xml", ) yield path Path(path).unlink(missing_ok=True) @@ -167,39 +162,29 @@ def prodconf_py(self): def test_uploadLogFile_success(self, mocker, uplogfile, wf_commons, prodconf_json, prodconf_py): """Test successful execution of UploadLogFile module.""" log_url = "notImportant" - mockSEMethod = mocker.patch( + mock_se_method = mocker.patch( "DIRAC.Resources.Storage.StorageElement.StorageElementItem._StorageElementItem__executeMethod", return_value=S_OK({"Failed": [], "Successful": {log_url: log_url}}), ) - mock_request = mocker.patch("dirac_cwl.commands.upload_log_file.Request") - mock_failover = mocker.patch("dirac_cwl.commands.upload_log_file.FailoverTransfer") - mock_job_report = mocker.patch("dirac_cwl.commands.upload_log_file.JobReport") - - req = Request() - mock_request.return_value = req - - failover = FailoverTransfer(req) - mocker.patch.object(failover, "transferAndRegisterFile", return_value=S_OK()) - mock_failover.return_value = failover - - jr = JobReport(wf_commons["job_id"]) - mocker.patch.object(jr, "setApplicationStatus") - mocker.patch.object(jr, "setJobParameter") - mock_job_report.return_value = jr - - uplogfile.request = Request() + mock_transferAndRegisterFile = mocker.patch( + "DIRAC.DataManagementSystem.Client.FailoverTransfer.FailoverTransfer.transferAndRegisterFile", + return_value=S_OK(), + ) + mock_setJobParameter = mocker.patch("DIRAC.WorkloadManagementSystem.Client.JobReport.JobReport.setJobParameter") + mock_setApplicationStatus = mocker.patch( + "DIRAC.WorkloadManagementSystem.Client.JobReport.JobReport.setApplicationStatus" + ) # Execute the module - wf_commons_path = create_workflow_commons(wf_commons) + create_workflow_commons(wf_commons) uplogfile.execute(job_path) - with open(wf_commons_path, "r", encoding="utf-8") as f: - updated_wf_commons = json.load(f) + updated_wf_commons = WorkflowCommons.load(job_path) # Check the log directory - assert updated_wf_commons["log_dir"] != "" - log_dir = Path(updated_wf_commons["log_dir"]) + assert updated_wf_commons.log_dir != "" + log_dir = Path(updated_wf_commons.log_dir) assert log_dir.exists() assert log_dir.is_dir() assert log_dir.joinpath(prodconf_json).exists() @@ -211,124 +196,108 @@ def test_uploadLogFile_success(self, mocker, uplogfile, wf_commons, prodconf_jso assert file.stat().st_mode & 0o777 == 0o755 # Check the generated zip file - zipFile = Path(f"{updated_wf_commons['prod_job_id']}.zip") + zipFile = Path(f"{updated_wf_commons.prod_job_id}.zip") assert zipFile.exists() zipfile.ZipFile(zipFile, "r").extractall("unzipped") - unzipped = Path("unzipped").joinpath(updated_wf_commons["prod_job_id"]) + unzipped = Path("unzipped").joinpath(updated_wf_commons.prod_job_id) assert unzipped.joinpath(prodconf_json).exists() assert unzipped.joinpath(prodconf_py).exists() assert unzipped.joinpath(prodconf_json).read_text() == '{"foo": "bar"}' assert unzipped.joinpath(prodconf_py).read_text() == 'foo = "bar"' # Make sure that StorageElement was called twice (getURL, putFile) - assert mockSEMethod.call_count == 2 + assert mock_se_method.call_count == 2 # Make sure that the request was not created - assert failover.transferAndRegisterFile.call_count == 0 + assert mock_transferAndRegisterFile.call_count == 0 # Make sure the application status was not changed - assert jr.setApplicationStatus.call_count == 0 + assert mock_setApplicationStatus.call_count == 0 # Check the jobReport.setParameter arguments - assert jr.setJobParameter.call_count == 1 - assert jr.setJobParameter.call_args_list - params = jr.setJobParameter.call_args_list[0][0] + assert mock_setJobParameter.call_count == 1 + assert mock_setJobParameter.call_args_list + params = mock_setJobParameter.call_args_list[0][0] assert params[0] == "Log URL" assert params[1] == f'Log file directory' - shutil.rmtree(updated_wf_commons["log_dir"], ignore_errors=True) + shutil.rmtree(updated_wf_commons.log_dir, ignore_errors=True) def test_uploadLogFile_noOutputFile(self, mocker, uplogfile, wf_commons): """Test execution of UploadLogFile module when there is no output files. * populateLogDirectory should return an error, because there is no "successful" files in log_dir. """ - mockSEMethod = mocker.patch( + mock_se_method = mocker.patch( "DIRAC.Resources.Storage.StorageElement.StorageElementItem._StorageElementItem__executeMethod", return_value=S_OK({"Failed": [], "Successful": {"notImportant": "notImportant"}}), ) - mock_request = mocker.patch("dirac_cwl.commands.upload_log_file.Request") - mock_failover = mocker.patch("dirac_cwl.commands.upload_log_file.FailoverTransfer") - mock_job_report = mocker.patch("dirac_cwl.commands.upload_log_file.JobReport") - - req = Request() - mock_request.return_value = req - - failover = FailoverTransfer(req) - mocker.patch.object(failover, "transferAndRegisterFile", return_value=S_OK()) - mock_failover.return_value = failover - - jr = JobReport(wf_commons["job_id"]) - mocker.patch.object(jr, "setApplicationStatus") - mocker.patch.object(jr, "setJobParameter") - mock_job_report.return_value = jr + mock_transferAndRegisterFile = mocker.patch( + "DIRAC.DataManagementSystem.Client.FailoverTransfer.FailoverTransfer.transferAndRegisterFile", + return_value=S_OK(), + ) + mock_setJobParameter = mocker.patch("DIRAC.WorkloadManagementSystem.Client.JobReport.JobReport.setJobParameter") + mock_setApplicationStatus = mocker.patch( + "DIRAC.WorkloadManagementSystem.Client.JobReport.JobReport.setApplicationStatus" + ) # Execute the module - wf_commons_path = create_workflow_commons(wf_commons) + create_workflow_commons(wf_commons) uplogfile.execute(job_path) - with open(wf_commons_path, "r", encoding="utf-8") as f: - updated_wf_commons = json.load(f) + updated_wf_commons = WorkflowCommons.load(job_path) # Check the log directory - assert updated_wf_commons["log_dir"] != "" - log_dir = Path(updated_wf_commons["log_dir"]) + assert updated_wf_commons.log_dir != "" + log_dir = Path(updated_wf_commons.log_dir) assert log_dir.exists() assert log_dir.is_dir() # Make sure log_dir is an empty directory assert not list(log_dir.iterdir()) # Check the generated zip file - zipFile = Path(f"{updated_wf_commons['prod_job_id']}.zip") + zipFile = Path(f"{updated_wf_commons.prod_job_id}.zip") assert not zipFile.exists() # Make sure that StorageElement was called twice (getURL, putFile) - assert mockSEMethod.call_count == 0 + assert mock_se_method.call_count == 0 # Make sure that the request was not created - assert failover.transferAndRegisterFile.call_count == 0 + assert mock_transferAndRegisterFile.call_count == 0 # Make sure the application status was changed - assert jr.setApplicationStatus.call_count == 1 - assert jr.setJobParameter.call_count == 0 + assert mock_setApplicationStatus.call_count == 1 + assert mock_setJobParameter.call_count == 0 - shutil.rmtree(updated_wf_commons["log_dir"], ignore_errors=True) + shutil.rmtree(updated_wf_commons.log_dir, ignore_errors=True) def test_uploadLogFile_zipException(self, mocker, uplogfile, wf_commons, prodconf_json, prodconf_py): """Test execution of UploadLogFile module when an exception is raised when zipping files.""" mocker.patch("LHCbDIRAC.Workflow.Modules.UploadLogFile.zipFiles", side_effect=OSError) - mockSEMethod = mocker.patch( + mock_se_method = mocker.patch( "DIRAC.Resources.Storage.StorageElement.StorageElementItem._StorageElementItem__executeMethod", return_value=S_OK({"Failed": [], "Successful": {"notImportant": "notImportant"}}), ) - mock_request = mocker.patch("dirac_cwl.commands.upload_log_file.Request") - mock_failover = mocker.patch("dirac_cwl.commands.upload_log_file.FailoverTransfer") - mock_job_report = mocker.patch("dirac_cwl.commands.upload_log_file.JobReport") - - req = Request() - mock_request.return_value = req - - failover = FailoverTransfer(req) - mocker.patch.object(failover, "transferAndRegisterFile", return_value=S_OK()) - mock_failover.return_value = failover - - jr = JobReport(wf_commons["job_id"]) - mocker.patch.object(jr, "setApplicationStatus") - mock_job_report.return_value = jr + mock_transferAndRegisterFile = mocker.patch( + "DIRAC.DataManagementSystem.Client.FailoverTransfer.FailoverTransfer.transferAndRegisterFile", + return_value=S_OK(), + ) + mock_setApplicationStatus = mocker.patch( + "DIRAC.WorkloadManagementSystem.Client.JobReport.JobReport.setApplicationStatus" + ) # Execute the module - wf_commons_path = create_workflow_commons(wf_commons) + create_workflow_commons(wf_commons) uplogfile.execute(job_path) - with open(wf_commons_path, "r", encoding="utf-8") as f: - updated_wf_commons = json.load(f) + updated_wf_commons = WorkflowCommons.load(job_path) # Check the log directory - assert updated_wf_commons["log_dir"] != "" - log_dir = Path(updated_wf_commons["log_dir"]) + assert updated_wf_commons.log_dir != "" + log_dir = Path(updated_wf_commons.log_dir) assert log_dir.exists() assert log_dir.is_dir() assert log_dir.joinpath(prodconf_json).exists() @@ -340,53 +309,45 @@ def test_uploadLogFile_zipException(self, mocker, uplogfile, wf_commons, prodcon assert file.stat().st_mode & 0o777 == 0o755 # Check the generated zip file - zipFile = Path(f"{updated_wf_commons['prod_job_id']}.zip") + zipFile = Path(f"{updated_wf_commons.prod_job_id}.zip") assert not zipFile.exists() # Make sure that StorageElement was called twice (getURL, putFile) - assert mockSEMethod.call_count == 0 + assert mock_se_method.call_count == 0 # Make sure that the request was not created - assert failover.transferAndRegisterFile.call_count == 0 + assert mock_transferAndRegisterFile.call_count == 0 # Make sure the application status was changed - assert jr.setApplicationStatus.call_count == 1 + assert mock_setApplicationStatus.call_count == 1 - shutil.rmtree(updated_wf_commons["log_dir"], ignore_errors=True) + shutil.rmtree(updated_wf_commons.log_dir, ignore_errors=True) def test_uploadLogFile_zipError(self, mocker, uplogfile, wf_commons, prodconf_json, prodconf_py): """Test execution of UploadLogFile module when an error is occurring when zipping files.""" mocker.patch("LHCbDIRAC.Workflow.Modules.UploadLogFile.zipFiles", return_value=S_ERROR("Error")) - mockSEMethod = mocker.patch( + mock_se_method = mocker.patch( "DIRAC.Resources.Storage.StorageElement.StorageElementItem._StorageElementItem__executeMethod", return_value=S_OK({"Failed": [], "Successful": {"notImportant": "notImportant"}}), ) - mock_request = mocker.patch("dirac_cwl.commands.upload_log_file.Request") - mock_failover = mocker.patch("dirac_cwl.commands.upload_log_file.FailoverTransfer") - mock_job_report = mocker.patch("dirac_cwl.commands.upload_log_file.JobReport") - - req = Request() - mock_request.return_value = req - - failover = FailoverTransfer(req) - mocker.patch.object(failover, "transferAndRegisterFile", return_value=S_OK()) - mock_failover.return_value = failover - - jr = JobReport(wf_commons["job_id"]) - mocker.patch.object(jr, "setApplicationStatus") - mock_job_report.return_value = jr + mock_transferAndRegisterFile = mocker.patch( + "DIRAC.DataManagementSystem.Client.FailoverTransfer.FailoverTransfer.transferAndRegisterFile", + return_value=S_OK(), + ) + mock_setApplicationStatus = mocker.patch( + "DIRAC.WorkloadManagementSystem.Client.JobReport.JobReport.setApplicationStatus" + ) # Execute the module - wf_commons_path = create_workflow_commons(wf_commons) + create_workflow_commons(wf_commons) uplogfile.execute(job_path) - with open(wf_commons_path, "r", encoding="utf-8") as f: - updated_wf_commons = json.load(f) + updated_wf_commons = WorkflowCommons.load(job_path) # Check the log directory - assert updated_wf_commons["log_dir"] != "" - log_dir = Path(updated_wf_commons["log_dir"]) + assert updated_wf_commons.log_dir != "" + log_dir = Path(updated_wf_commons.log_dir) assert log_dir.exists() assert log_dir.is_dir() assert log_dir.joinpath(prodconf_json).exists() @@ -398,53 +359,45 @@ def test_uploadLogFile_zipError(self, mocker, uplogfile, wf_commons, prodconf_js assert file.stat().st_mode & 0o777 == 0o755 # Check the generated zip file - zipFile = Path(f"{updated_wf_commons['prod_job_id']}.zip") + zipFile = Path(f"{updated_wf_commons.prod_job_id}.zip") assert not zipFile.exists() # Make sure that StorageElement was called twice (getURL, putFile) - assert mockSEMethod.call_count == 0 + assert mock_se_method.call_count == 0 # Make sure that the request was not created - assert failover.transferAndRegisterFile.call_count == 0 + assert mock_transferAndRegisterFile.call_count == 0 # Make sure the application status was changed - assert jr.setApplicationStatus.call_count == 1 + assert mock_setApplicationStatus.call_count == 1 - shutil.rmtree(updated_wf_commons["log_dir"], ignore_errors=True) + shutil.rmtree(updated_wf_commons.log_dir, ignore_errors=True) def test_uploadLogFile_SEError(self, mocker, uplogfile, wf_commons, prodconf_json, prodconf_py): """Test execution of UploadLogFile module when an error is occurring when calling StorageElement.""" mocker.patch("LHCbDIRAC.Workflow.Modules.UploadLogFile.getDestinationSEList", return_value=["SE1", "SE2"]) - mockSEMethod = mocker.patch( + mock_se_method = mocker.patch( "DIRAC.Resources.Storage.StorageElement.StorageElementItem._StorageElementItem__executeMethod", return_value=S_ERROR("Error"), ) - mock_request = mocker.patch("dirac_cwl.commands.upload_log_file.Request") - mock_failover = mocker.patch("dirac_cwl.commands.upload_log_file.FailoverTransfer") - mock_job_report = mocker.patch("dirac_cwl.commands.upload_log_file.JobReport") - - req = Request() - mock_request.return_value = req - - failover = FailoverTransfer(req) - mocker.patch.object(failover, "transferAndRegisterFile", return_value=S_OK({"uploadedSE": "SE1"})) - mock_failover.return_value = failover - - jr = JobReport(wf_commons["job_id"]) - mocker.patch.object(jr, "setApplicationStatus") - mock_job_report.return_value = jr + mock_transferAndRegisterFile = mocker.patch( + "DIRAC.DataManagementSystem.Client.FailoverTransfer.FailoverTransfer.transferAndRegisterFile", + return_value=S_OK({"uploadedSE": "SE1"}), + ) + mock_setApplicationStatus = mocker.patch( + "DIRAC.WorkloadManagementSystem.Client.JobReport.JobReport.setApplicationStatus" + ) # Execute the module - wf_commons_path = create_workflow_commons(wf_commons) + create_workflow_commons(wf_commons) uplogfile.execute(job_path) - with open(wf_commons_path, "r", encoding="utf-8") as f: - updated_wf_commons = json.load(f) + updated_wf_commons = WorkflowCommons.load(job_path) # Check the log directory - assert updated_wf_commons["log_dir"] != "" - log_dir = Path(updated_wf_commons["log_dir"]) + assert updated_wf_commons.log_dir != "" + log_dir = Path(updated_wf_commons.log_dir) assert log_dir.exists() assert log_dir.is_dir() assert log_dir.joinpath(prodconf_json).exists() @@ -456,72 +409,63 @@ def test_uploadLogFile_SEError(self, mocker, uplogfile, wf_commons, prodconf_jso assert file.stat().st_mode & 0o777 == 0o755 # Check the generated zip file - zipFile = Path(f"{updated_wf_commons['prod_job_id']}.zip") + zipFile = Path(f"{updated_wf_commons.prod_job_id}.zip") assert zipFile.exists() zipfile.ZipFile(zipFile, "r").extractall("unzipped") - unzipped = Path("unzipped").joinpath(updated_wf_commons["prod_job_id"]) + unzipped = Path("unzipped").joinpath(updated_wf_commons.prod_job_id) assert unzipped.joinpath(prodconf_json).exists() assert unzipped.joinpath(prodconf_py).exists() assert unzipped.joinpath(prodconf_json).read_text() == '{"foo": "bar"}' assert unzipped.joinpath(prodconf_py).read_text() == 'foo = "bar"' # Make sure that StorageElement was called twice (getURL, putFile) - assert mockSEMethod.call_count == 2 + assert mock_se_method.call_count == 2 # Make sure that the request was created - assert failover.transferAndRegisterFile.call_count == 1 + assert mock_transferAndRegisterFile.call_count == 1 - operations = updated_wf_commons["request_dict"]["Operations"] + operations = json.loads(updated_wf_commons.request.toJSON()["Value"])["Operations"] assert len(operations) == 2 assert operations[0]["Type"] == "LogUpload" assert len(operations[0]["Files"]) == 1 - assert operations[0]["Files"][0]["LFN"] == updated_wf_commons["log_lfn_path"] + assert operations[0]["Files"][0]["LFN"] == updated_wf_commons.log_lfn_path assert operations[1]["Type"] == "RemoveFile" assert len(operations[1]["Files"]) == 1 - assert operations[1]["Files"][0]["LFN"] == updated_wf_commons["log_lfn_path"] + assert operations[1]["Files"][0]["LFN"] == updated_wf_commons.log_lfn_path # Make sure the application status was not changed - assert jr.setApplicationStatus.call_count == 0 + assert mock_setApplicationStatus.call_count == 0 - shutil.rmtree(updated_wf_commons["log_dir"], ignore_errors=True) + shutil.rmtree(updated_wf_commons.log_dir, ignore_errors=True) def test_uploadLogFile_transferError(self, mocker, uplogfile, wf_commons, prodconf_json, prodconf_py): """Test execution of UploadLogFile module when calling StorageElement and FailoverTransfer fail.""" mocker.patch("LHCbDIRAC.Workflow.Modules.UploadLogFile.getDestinationSEList", return_value=["SE1", "SE2"]) - mockSEMethod = mocker.patch( + mock_se_method = mocker.patch( "DIRAC.Resources.Storage.StorageElement.StorageElementItem._StorageElementItem__executeMethod", return_value=S_ERROR("Error"), ) - mock_request = mocker.patch("dirac_cwl.commands.upload_log_file.Request") - mock_failover = mocker.patch("dirac_cwl.commands.upload_log_file.FailoverTransfer") - mock_job_report = mocker.patch("dirac_cwl.commands.upload_log_file.JobReport") - - req = Request() - mock_request.return_value = req - - failover = FailoverTransfer(req) - mocker.patch.object(failover, "transferAndRegisterFile", return_value=S_ERROR("Error")) - mock_failover.return_value = failover - - mock_job_report = mocker.patch("dirac_cwl.commands.upload_log_file.JobReport") - jr = JobReport(wf_commons["job_id"]) - mocker.patch.object(jr, "setApplicationStatus") - mock_job_report.return_value = jr + mock_transferAndRegisterFile = mocker.patch( + "DIRAC.DataManagementSystem.Client.FailoverTransfer.FailoverTransfer.transferAndRegisterFile", + return_value=S_ERROR("Error"), + ) + mock_setApplicationStatus = mocker.patch( + "DIRAC.WorkloadManagementSystem.Client.JobReport.JobReport.setApplicationStatus" + ) # Execute the module - wf_commons_path = create_workflow_commons(wf_commons) + create_workflow_commons(wf_commons) uplogfile.execute(job_path) - with open(wf_commons_path, "r", encoding="utf-8") as f: - updated_wf_commons = json.load(f) + updated_wf_commons = WorkflowCommons.load(job_path) # Check the log directory - assert updated_wf_commons["log_dir"] != "" - log_dir = Path(updated_wf_commons["log_dir"]) + assert updated_wf_commons.log_dir != "" + log_dir = Path(updated_wf_commons.log_dir) assert log_dir.exists() assert log_dir.is_dir() assert log_dir.joinpath(prodconf_json).exists() @@ -533,30 +477,30 @@ def test_uploadLogFile_transferError(self, mocker, uplogfile, wf_commons, prodco assert file.stat().st_mode & 0o777 == 0o755 # Check the generated zip file - zipFile = Path(f"{updated_wf_commons['prod_job_id']}.zip") + zipFile = Path(f"{updated_wf_commons.prod_job_id}.zip") assert zipFile.exists() zipfile.ZipFile(zipFile, "r").extractall("unzipped") - unzipped = Path("unzipped").joinpath(updated_wf_commons["prod_job_id"]) + unzipped = Path("unzipped").joinpath(updated_wf_commons.prod_job_id) assert unzipped.joinpath(prodconf_json).exists() assert unzipped.joinpath(prodconf_py).exists() assert unzipped.joinpath(prodconf_json).read_text() == '{"foo": "bar"}' assert unzipped.joinpath(prodconf_py).read_text() == 'foo = "bar"' # Make sure that StorageElement was called twice (getURL, putFile) - assert mockSEMethod.call_count == 2 + assert mock_se_method.call_count == 2 # Make sure that the request was not created - assert failover.transferAndRegisterFile.call_count == 1 + assert mock_transferAndRegisterFile.call_count == 1 - operations = updated_wf_commons["request_dict"]["Operations"] + operations = json.loads(updated_wf_commons.request.toJSON()["Value"])["Operations"] assert len(operations) == 0 # Make sure the application status was changed - assert jr.setApplicationStatus.call_count == 1 + assert mock_setApplicationStatus.call_count == 1 - shutil.rmtree(updated_wf_commons["log_dir"], ignore_errors=True) + shutil.rmtree(updated_wf_commons.log_dir, ignore_errors=True) class TestBookkeepingReport: @@ -565,7 +509,7 @@ class TestBookkeepingReport: @pytest.fixture def bookkeeping_file(self, wf_commons): """Bookkeeping report file fixture.""" - path = os.path.join(job_path, f"bookkeeping_{wf_commons['command_id']}.xml") + path = os.path.join(job_path, f"bookkeeping_{wf_commons['step_id']}.xml") yield path Path(path).unlink(missing_ok=True) @@ -590,7 +534,7 @@ def test_bkreport_prod_mcsimulation_success(self, bk_report, wf_commons, bookkee wf_commons["application_name"] = "Gauss" wf_commons["job_type"] = "MCSimulation" - wf_commons["bookkeeping_LFNs"] = [ + wf_commons["bookkeeping_lfns"] = [ "/lhcb/LHCb/Collision16/SIM/00209455/0000/00209455_00001537_1.sim", ] wf_commons["production_output_data"] = [ @@ -640,13 +584,12 @@ def test_bkreport_prod_mcsimulation_success(self, bk_report, wf_commons, bookkee wf_commons["xml_summary_path"] = xml_summary_file xf_o = prepare_XMLSummary_file(xml_summary_file, xml_content) - wf_commons_path = create_workflow_commons(wf_commons) + create_workflow_commons(wf_commons) # Execute the module bk_report.execute(job_path) - with open(wf_commons_path, "r", encoding="utf-8") as f: - updated_wf_commons = json.load(f) + updated_wf_commons = WorkflowCommons.load(job_path) xml_path = bookkeeping_file assert Path(xml_path).exists(), "XML report file not created." @@ -657,28 +600,28 @@ def test_bkreport_prod_mcsimulation_success(self, bk_report, wf_commons, bookkee # Extract fields from the XML and perform further operations assert root.tag == "Job", "Root tag should be Job." - assert root.attrib["ConfigName"] == updated_wf_commons["config_name"] - assert root.attrib["ConfigVersion"] == updated_wf_commons["config_version"] + assert root.attrib["ConfigName"] == updated_wf_commons.config_name + assert root.attrib["ConfigVersion"] == updated_wf_commons.config_version assert root.attrib["Date"] assert root.attrib["Time"] - assert get_typed_parameter_value("ProgramName", root) == updated_wf_commons["application_name"] - assert get_typed_parameter_value("ProgramVersion", root) == updated_wf_commons["application_version"] + assert get_typed_parameter_value("ProgramName", root) == updated_wf_commons.application_name + assert get_typed_parameter_value("ProgramVersion", root) == updated_wf_commons.application_version assert get_typed_parameter_value("DiracVersion", root) == LHCbDIRAC.__version__ - assert get_typed_parameter_value("Name", root) == updated_wf_commons["command_id"] + assert get_typed_parameter_value("Name", root) == updated_wf_commons.step_id assert float(get_typed_parameter_value("ExecTime", root)) > 1000 assert get_typed_parameter_value("CPUTIME", root) == "0" assert get_typed_parameter_value("FirstEventNumber", root) == "1" - assert get_typed_parameter_value("StatisticsRequested", root) == str(updated_wf_commons["number_of_events"]) + assert get_typed_parameter_value("StatisticsRequested", root) == str(updated_wf_commons.number_of_events) assert get_typed_parameter_value("NumberOfEvents", root) == str(xf_o.outputEventsTotal) - assert get_typed_parameter_value("Production", root) == updated_wf_commons["production_id"] - assert get_typed_parameter_value("DiracJobId", root) == str(updated_wf_commons["job_id"]) + assert get_typed_parameter_value("Production", root) == updated_wf_commons.production_id + assert get_typed_parameter_value("DiracJobId", root) == str(updated_wf_commons.job_id) assert get_typed_parameter_value("Location", root) == siteName() assert get_typed_parameter_value("JobStart", root) assert get_typed_parameter_value("JobEnd", root) - assert get_typed_parameter_value("JobType", root) == updated_wf_commons["job_type"] + assert get_typed_parameter_value("JobType", root) == updated_wf_commons.job_type assert get_typed_parameter_value("WorkerNode", root) assert get_typed_parameter_value("WNMEMORY", root) @@ -697,7 +640,7 @@ def test_bkreport_prod_mcsimulation_success(self, bk_report, wf_commons, bookkee assert output_files, "No OutputFile elements found." first_output_details = get_output_file_details(output_files[0]) - assert first_output_details["Name"] == updated_wf_commons["production_output_data"][0] + assert first_output_details["Name"] == updated_wf_commons.production_output_data[0] assert first_output_details["TypeName"] == "SIM" assert first_output_details["Parameters"]["FileSize"] == "0" assert "CreationDate" in first_output_details["Parameters"] @@ -721,7 +664,7 @@ def test_bkreport_prod_mcsimulation_noinputoutput_success( wf_commons["job_type"] = "MCSimulation" # This was obtained from a previous module (likely GaudiApplication) - wf_commons["bookkeeping_LFNs"] = [ + wf_commons["bookkeeping_lfns"] = [ "/lhcb/LHCb/Collision16/SIM/00209455/0000/00209455_00001537_1", ] wf_commons["production_output_data"] = [ @@ -765,13 +708,12 @@ def test_bkreport_prod_mcsimulation_noinputoutput_success( wf_commons["xml_summary_path"] = xml_summary_file xf_o = prepare_XMLSummary_file(xml_summary_file, xml_content) - wf_commons_path = create_workflow_commons(wf_commons) + create_workflow_commons(wf_commons) # Execute the module bk_report.execute(job_path) - with open(wf_commons_path, "r", encoding="utf-8") as f: - updated_wf_commons = json.load(f) + updated_wf_commons = WorkflowCommons.load(job_path) # Check if the XML report file is created xml_path = bookkeeping_file @@ -783,28 +725,28 @@ def test_bkreport_prod_mcsimulation_noinputoutput_success( # Extract fields from the XML and perform further operations assert root.tag == "Job", "Root tag should be Job." - assert root.attrib["ConfigName"] == updated_wf_commons["config_name"] - assert root.attrib["ConfigVersion"] == updated_wf_commons["config_version"] + assert root.attrib["ConfigName"] == updated_wf_commons.config_name + assert root.attrib["ConfigVersion"] == updated_wf_commons.config_version assert root.attrib["Date"] assert root.attrib["Time"] - assert get_typed_parameter_value("ProgramName", root) == updated_wf_commons["application_name"] - assert get_typed_parameter_value("ProgramVersion", root) == updated_wf_commons["application_version"] + assert get_typed_parameter_value("ProgramName", root) == updated_wf_commons.application_name + assert get_typed_parameter_value("ProgramVersion", root) == updated_wf_commons.application_version assert get_typed_parameter_value("DiracVersion", root) == LHCbDIRAC.__version__ - assert get_typed_parameter_value("Name", root) == updated_wf_commons["command_id"] + assert get_typed_parameter_value("Name", root) == updated_wf_commons.step_id assert float(get_typed_parameter_value("ExecTime", root)) > 1000 assert get_typed_parameter_value("CPUTIME", root) == "0" assert get_typed_parameter_value("FirstEventNumber", root) == "1" - assert get_typed_parameter_value("StatisticsRequested", root) == str(updated_wf_commons["number_of_events"]) + assert get_typed_parameter_value("StatisticsRequested", root) == str(updated_wf_commons.number_of_events) assert get_typed_parameter_value("NumberOfEvents", root) == str(xf_o.outputEventsTotal) - assert get_typed_parameter_value("Production", root) == updated_wf_commons["production_id"] - assert get_typed_parameter_value("DiracJobId", root) == str(updated_wf_commons["job_id"]) + assert get_typed_parameter_value("Production", root) == updated_wf_commons.production_id + assert get_typed_parameter_value("DiracJobId", root) == str(updated_wf_commons.job_id) assert get_typed_parameter_value("Location", root) == siteName() assert get_typed_parameter_value("JobStart", root) assert get_typed_parameter_value("JobEnd", root) - assert get_typed_parameter_value("JobType", root) == updated_wf_commons["job_type"] + assert get_typed_parameter_value("JobType", root) == updated_wf_commons.job_type assert get_typed_parameter_value("WorkerNode", root) assert get_typed_parameter_value("WNMEMORY", root) @@ -827,7 +769,7 @@ def test_bk_report_prod_mcreconstruction_success(self, bk_report, wf_commons, bo wf_commons["application_name"] = "Boole" wf_commons["job_type"] = "MCReconstruction" - wf_commons["bookkeeping_LFNs"] = [ + wf_commons["bookkeeping_lfns"] = [ "/lhcb/LHCb/Collision16/SIM/00209455/0000/00209455_00001537_1", ] wf_commons["log_file_path"] = "/lhcb/LHCb/Collision16/LOG/00209455/0000/" @@ -870,13 +812,12 @@ def test_bk_report_prod_mcreconstruction_success(self, bk_report, wf_commons, bo xf_o = prepare_XMLSummary_file(xml_summary_file, xml_content) - wf_commons_path = create_workflow_commons(wf_commons) + create_workflow_commons(wf_commons) # Execute the module bk_report.execute(job_path) - with open(wf_commons_path, "r", encoding="utf-8") as f: - updated_wf_commons = json.load(f) + updated_wf_commons = WorkflowCommons.load(job_path) # Check if the XML report file is created xml_path = bookkeeping_file @@ -888,28 +829,28 @@ def test_bk_report_prod_mcreconstruction_success(self, bk_report, wf_commons, bo # Extract fields from the XML and perform further operations assert root.tag == "Job", "Root tag should be Job." - assert root.attrib["ConfigName"] == updated_wf_commons["config_name"] - assert root.attrib["ConfigVersion"] == updated_wf_commons["config_version"] + assert root.attrib["ConfigName"] == updated_wf_commons.config_name + assert root.attrib["ConfigVersion"] == updated_wf_commons.config_version assert root.attrib["Date"] assert root.attrib["Time"] - assert get_typed_parameter_value("ProgramName", root) == updated_wf_commons["application_name"] - assert get_typed_parameter_value("ProgramVersion", root) == updated_wf_commons["application_version"] + assert get_typed_parameter_value("ProgramName", root) == updated_wf_commons.application_name + assert get_typed_parameter_value("ProgramVersion", root) == updated_wf_commons.application_version assert get_typed_parameter_value("DiracVersion", root) == LHCbDIRAC.__version__ - assert get_typed_parameter_value("Name", root) == updated_wf_commons["command_id"] + assert get_typed_parameter_value("Name", root) == updated_wf_commons.step_id assert float(get_typed_parameter_value("ExecTime", root)) > 1000 assert get_typed_parameter_value("CPUTIME", root) == "0" assert get_typed_parameter_value("FirstEventNumber", root) == "1" - assert get_typed_parameter_value("StatisticsRequested", root) == str(updated_wf_commons["number_of_events"]) + assert get_typed_parameter_value("StatisticsRequested", root) == str(updated_wf_commons.number_of_events) assert get_typed_parameter_value("NumberOfEvents", root) == str(xf_o.inputEventsTotal) - assert get_typed_parameter_value("Production", root) == updated_wf_commons["production_id"] - assert get_typed_parameter_value("DiracJobId", root) == str(updated_wf_commons["job_id"]) + assert get_typed_parameter_value("Production", root) == updated_wf_commons.production_id + assert get_typed_parameter_value("DiracJobId", root) == str(updated_wf_commons.job_id) assert get_typed_parameter_value("Location", root) == siteName() assert get_typed_parameter_value("JobStart", root) assert get_typed_parameter_value("JobEnd", root) - assert get_typed_parameter_value("JobType", root) == updated_wf_commons["job_type"] + assert get_typed_parameter_value("JobType", root) == updated_wf_commons.job_type assert get_typed_parameter_value("WorkerNode", root) assert get_typed_parameter_value("WNMEMORY", root) @@ -928,7 +869,7 @@ def test_bk_report_prod_mcreconstruction_success(self, bk_report, wf_commons, bo assert output_files, "No OutputFile elements found." first_output_details = get_output_file_details(output_files[0]) - assert first_output_details["Name"] == updated_wf_commons["production_output_data"][0] + assert first_output_details["Name"] == updated_wf_commons.production_output_data[0] assert first_output_details["TypeName"] == "DIGI" assert first_output_details["Parameters"]["FileSize"] == "0" assert "CreationDate" in first_output_details["Parameters"] @@ -946,7 +887,7 @@ def test_bkreport_previousError_success(self, mocker, bk_report, wf_commons, boo wf_commons["application_name"] = "Gauss" wf_commons["application_version"] = wf_commons["config_version"] wf_commons["job_type"] = "MCSimulation" - wf_commons["step_status"] = S_ERROR() + wf_commons["step_status"] = StepStatus.Failed create_workflow_commons(wf_commons) @@ -974,49 +915,44 @@ def test_failoverRequest_success(self, mocker: MockerFixture, failover_request, "/lhcb/data/2010/EW.DST/00008380/0000/00008380_00000287_1.ew.dst", ] - mock_file_report = mocker.patch("dirac_cwl.commands.failover_request.FileReport") - mock_job_report = mocker.patch("dirac_cwl.commands.failover_request.JobReport") - - fr = FileReport() - mocker.patch.object(fr, "getFiles", side_effect=[problematic_files, []]) - mocker.patch.object(fr, "commit", return_value=S_OK("Anything")) - mocker.patch.object(fr, "setFileStatus") - mock_file_report.return_value = fr - - jr = JobReport(wf_commons["job_id"]) - mocker.patch.object(jr, "setApplicationStatus") - mock_job_report.return_value = jr + mocker.patch( + "DIRAC.TransformationSystem.Client.FileReport.FileReport.getFiles", side_effect=[problematic_files, []] + ) + mocker.patch("DIRAC.TransformationSystem.Client.FileReport.FileReport.commit", return_value=S_OK("Anything")) + mock_setFileStatus = mocker.patch("DIRAC.TransformationSystem.Client.FileReport.FileReport.setFileStatus") + mock_setApplicationStatus = mocker.patch( + "DIRAC.WorkloadManagementSystem.Client.JobReport.JobReport.setApplicationStatus" + ) wf_commons["inputs"] = [ "/lhcb/data/2010/EW.DST/00008380/0000/00008380_00000281_1.ew.dst", "/lhcb/data/2011/EW.DST/00008380/0000/00008380_00000281_1.ew.dst", ] + problematic_files - wf_commons_path = create_workflow_commons(wf_commons) + create_workflow_commons(wf_commons) failover_request.execute(job_path) - with open(wf_commons_path, "r", encoding="utf-8") as f: - updated_wf_commons = json.load(f) + updated_wf_commons = WorkflowCommons.load(job_path) # Check the FileReport calls: the problematic file should not appear # The input files should be set to "Processed" - assert fr.setFileStatus.call_count == 2 - args = fr.setFileStatus.call_args_list - assert args[0][0][0] == int(updated_wf_commons["production_id"]) - assert args[0][0][1] == updated_wf_commons["inputs"][0] + assert mock_setFileStatus.call_count == 2 + args = mock_setFileStatus.call_args_list + assert args[0][0][0] == int(updated_wf_commons.production_id) + assert args[0][0][1] == updated_wf_commons.inputs[0] assert args[0][0][2] == "Processed" - assert args[1][0][0] == int(updated_wf_commons["production_id"]) - assert args[1][0][1] == updated_wf_commons["inputs"][1] + assert args[1][0][0] == int(updated_wf_commons.production_id) + assert args[1][0][1] == updated_wf_commons.inputs[1] assert args[1][0][2] == "Processed" # Make sure the appliction is successfully finished - assert jr.setApplicationStatus.call_count == 1 - assert jr.setApplicationStatus.call_args[0][0] == "Job Finished Successfully" + assert mock_setApplicationStatus.call_count == 1 + assert mock_setApplicationStatus.call_args[0][0] == "Job Finished Successfully" # Make sure the forward DISET is not generated - operations = updated_wf_commons["request_dict"]["Operations"] + operations = json.loads(updated_wf_commons.request.toJSON()["Value"])["Operations"] assert len(operations) == 0 # Make sure the request json does not exists @@ -1031,18 +967,17 @@ def test_failoverRequest_commitFailure1(self, mocker: MockerFixture, failover_re "/lhcb/data/2010/EW.DST/00008380/0000/00008380_00000287_1.ew.dst", ] # Both calla to getFiles() will return the problematic files because the commit did not work - mock_file_report = mocker.patch("dirac_cwl.commands.failover_request.FileReport") - mock_job_report = mocker.patch("dirac_cwl.commands.failover_request.JobReport") - - jr = JobReport(wf_commons["job_id"]) - mocker.patch.object(jr, "setApplicationStatus") - mock_job_report.return_value = jr - - fr = FileReport() - mocker.patch.object(fr, "getFiles", side_effect=[problematic_files, problematic_files]) - mocker.patch.object(fr, "commit", side_effect=[S_ERROR("Error"), S_OK(None)]) - mocker.patch.object(fr, "setFileStatus") - mock_file_report.return_value = fr + mocker.patch( + "DIRAC.TransformationSystem.Client.FileReport.FileReport.getFiles", + side_effect=[problematic_files, problematic_files], + ) + mocker.patch( + "DIRAC.TransformationSystem.Client.FileReport.FileReport.commit", side_effect=[S_ERROR("Error"), S_OK(None)] + ) + mock_setFileStatus = mocker.patch("DIRAC.TransformationSystem.Client.FileReport.FileReport.setFileStatus") + mock_setApplicationStatus = mocker.patch( + "DIRAC.WorkloadManagementSystem.Client.JobReport.JobReport.setApplicationStatus" + ) wf_commons["inputs"] = [ "/lhcb/data/2010/EW.DST/00008380/0000/00008380_00000281_1.ew.dst", @@ -1050,31 +985,30 @@ def test_failoverRequest_commitFailure1(self, mocker: MockerFixture, failover_re ] + problematic_files # Execute the module - wf_commons_path = create_workflow_commons(wf_commons) + create_workflow_commons(wf_commons) failover_request.execute(job_path) - with open(wf_commons_path, "r", encoding="utf-8") as f: - updated_wf_commons = json.load(f) + updated_wf_commons = WorkflowCommons.load(job_path) # Check the FileReport calls: the problematic file should not appear # The input files should be set to "Processed" - assert fr.setFileStatus.call_count == 2 - args = fr.setFileStatus.call_args_list - assert args[0][0][0] == int(updated_wf_commons["production_id"]) - assert args[0][0][1] == updated_wf_commons["inputs"][0] + assert mock_setFileStatus.call_count == 2 + args = mock_setFileStatus.call_args_list + assert args[0][0][0] == int(updated_wf_commons.production_id) + assert args[0][0][1] == updated_wf_commons.inputs[0] assert args[0][0][2] == "Processed" - assert args[1][0][0] == int(updated_wf_commons["production_id"]) - assert args[1][0][1] == updated_wf_commons["inputs"][1] + assert args[1][0][0] == int(updated_wf_commons.production_id) + assert args[1][0][1] == updated_wf_commons.inputs[1] assert args[1][0][2] == "Processed" # Make sure the appliction is successfully finished - assert jr.setApplicationStatus.call_count == 1 - assert jr.setApplicationStatus.call_args[0][0] == "Job Finished Successfully" + assert mock_setApplicationStatus.call_count == 1 + assert mock_setApplicationStatus.call_args[0][0] == "Job Finished Successfully" # Make sure the forward DISET is generated - operations = updated_wf_commons["request_dict"]["Operations"] + operations = json.loads(updated_wf_commons.request.toJSON()["Value"])["Operations"] assert len(operations) == 0 # Make sure the request json does not exists @@ -1089,50 +1023,51 @@ def test_failoverRequest_commitFailure2(self, mocker: MockerFixture, failover_re "/lhcb/data/2010/EW.DST/00008380/0000/00008380_00000287_1.ew.dst", ] # Both calla to getFiles() will return the problematic files because the commit did not work - mock_file_report = mocker.patch("dirac_cwl.commands.failover_request.FileReport") - mock_job_report = mocker.patch("dirac_cwl.commands.failover_request.JobReport") + mocker.patch( + "DIRAC.TransformationSystem.Client.FileReport.FileReport.getFiles", + side_effect=[problematic_files, problematic_files], + ) - fr = FileReport() - mocker.patch.object(fr, "getFiles", side_effect=[problematic_files, problematic_files]) - mocker.patch.object(fr, "commit", side_effect=[S_ERROR("Error"), S_ERROR("Error")]) - mocker.patch.object(fr, "setFileStatus") - mock_file_report.return_value = fr + mocker.patch( + "DIRAC.TransformationSystem.Client.FileReport.FileReport.commit", + side_effect=[S_ERROR("Error"), S_ERROR("Error")], + ) - jr = JobReport(wf_commons["job_id"]) - mocker.patch.object(jr, "setApplicationStatus") - mock_job_report.return_value = jr + mock_setFileStatus = mocker.patch("DIRAC.TransformationSystem.Client.FileReport.FileReport.setFileStatus") + mock_setApplicationStatus = mocker.patch( + "DIRAC.WorkloadManagementSystem.Client.JobReport.JobReport.setApplicationStatus" + ) wf_commons["inputs"] = [ "/lhcb/data/2010/EW.DST/00008380/0000/00008380_00000281_1.ew.dst", "/lhcb/data/2011/EW.DST/00008380/0000/00008380_00000281_1.ew.dst", ] + problematic_files - wf_commons_path = create_workflow_commons(wf_commons) + create_workflow_commons(wf_commons) # Execute the module failover_request.execute(job_path) - with open(wf_commons_path, "r", encoding="utf-8") as f: - updated_wf_commons = json.load(f) + updated_wf_commons = WorkflowCommons.load(job_path) # Check the FileReport calls: the problematic file should not appear # The input files should be set to "Processed" - assert fr.setFileStatus.call_count == 2 - args = fr.setFileStatus.call_args_list - assert args[0][0][0] == int(updated_wf_commons["production_id"]) - assert args[0][0][1] == updated_wf_commons["inputs"][0] + assert mock_setFileStatus.call_count == 2 + args = mock_setFileStatus.call_args_list + assert args[0][0][0] == int(updated_wf_commons.production_id) + assert args[0][0][1] == updated_wf_commons.inputs[0] assert args[0][0][2] == "Processed" - assert args[1][0][0] == int(updated_wf_commons["production_id"]) - assert args[1][0][1] == updated_wf_commons["inputs"][1] + assert args[1][0][0] == int(updated_wf_commons.production_id) + assert args[1][0][1] == updated_wf_commons.inputs[1] assert args[1][0][2] == "Processed" # Make sure the appliction is successfully finished - assert jr.setApplicationStatus.call_count == 1 - assert jr.setApplicationStatus.call_args[0][0] == "Job Finished Successfully" + assert mock_setApplicationStatus.call_count == 1 + assert mock_setApplicationStatus.call_args[0][0] == "Job Finished Successfully" # Make sure the forward DISET is generated - operations = updated_wf_commons["request_dict"]["Operations"] + operations = json.loads(updated_wf_commons.request.toJSON()["Value"])["Operations"] assert len(operations) == 1 assert operations[0]["Type"] == "SetFileStatus" @@ -1147,18 +1082,18 @@ def test_failoverRequest_previousError_fail( problematic_files = [ "/lhcb/data/2010/EW.DST/00008380/0000/00008380_00000287_1.ew.dst", ] - mock_file_report = mocker.patch("dirac_cwl.commands.failover_request.FileReport") - mock_job_report = mocker.patch("dirac_cwl.commands.failover_request.JobReport") - - fr = FileReport() - mocker.patch.object(fr, "getFiles", side_effect=[problematic_files, problematic_files]) - mocker.patch.object(fr, "commit", side_effect=[S_ERROR("Error"), S_ERROR("Error")]) - mocker.patch.object(fr, "setFileStatus") - mock_file_report.return_value = fr - - jr = JobReport(wf_commons["job_id"]) - mocker.patch.object(jr, "setApplicationStatus") - mock_job_report.return_value = jr + mocker.patch( + "DIRAC.TransformationSystem.Client.FileReport.FileReport.getFiles", + side_effect=[problematic_files, problematic_files], + ) + mocker.patch( + "DIRAC.TransformationSystem.Client.FileReport.FileReport.commit", + side_effect=[S_ERROR("Error"), S_OK("Error")], + ) + mock_setFileStatus = mocker.patch("DIRAC.TransformationSystem.Client.FileReport.FileReport.setFileStatus") + mock_setApplicationStatus = mocker.patch( + "DIRAC.WorkloadManagementSystem.Client.JobReport.JobReport.setApplicationStatus" + ) wf_commons["inputs"] = [ "/lhcb/data/2010/EW.DST/00008380/0000/00008380_00000281_1.ew.dst", @@ -1166,33 +1101,32 @@ def test_failoverRequest_previousError_fail( ] + problematic_files # Intentional error - wf_commons["step_status"] = S_ERROR() + wf_commons["step_status"] = "Failed" - wf_commons_path = create_workflow_commons(wf_commons) + create_workflow_commons(wf_commons) # Execute the module failover_request.execute(job_path) - with open(wf_commons_path, "r", encoding="utf-8") as f: - updated_wf_commons = json.load(f) + updated_wf_commons = WorkflowCommons.load(job_path) # Check the FileReport calls: the problematic file should not appear # The input files should be set to "Unused" - assert fr.setFileStatus.call_count == 2 - args = fr.setFileStatus.call_args_list - assert args[0][0][0] == int(updated_wf_commons["production_id"]) - assert args[0][0][1] == updated_wf_commons["inputs"][0] + assert mock_setFileStatus.call_count == 2 + args = mock_setFileStatus.call_args_list + assert args[0][0][0] == int(updated_wf_commons.production_id) + assert args[0][0][1] == updated_wf_commons.inputs[0] assert args[0][0][2] == "Unused" - assert args[1][0][0] == int(updated_wf_commons["production_id"]) - assert args[1][0][1] == updated_wf_commons["inputs"][1] + assert args[1][0][0] == int(updated_wf_commons.production_id) + assert args[1][0][1] == updated_wf_commons.inputs[1] assert args[1][0][2] == "Unused" # Make sure the appliction is not reported as a success - assert jr.setApplicationStatus.call_count == 0 + assert mock_setApplicationStatus.call_count == 0 # Make sure the forward DISET is not generated - operations = updated_wf_commons["request_dict"]["Operations"] + operations = json.loads(updated_wf_commons.request.toJSON()["Value"])["Operations"] assert len(operations) == 0 # Make sure the request json does not exists @@ -1251,33 +1185,23 @@ def test_uploadOutputData_success(self, mocker, upload_output, wf_commons, sim_f * The output should be uploaded and registered in the bookkeeping system. * The bookkeeping report should be sent and the job parameter updated. """ - mock_file_report = mocker.patch("dirac_cwl.commands.upload_output_data.FileReport") - mock_job_report = mocker.patch("dirac_cwl.commands.upload_output_data.JobReport") - mock_request = mocker.patch("dirac_cwl.commands.upload_output_data.Request") - mock_failover = mocker.patch("dirac_cwl.commands.upload_output_data.FailoverTransfer") - mock_bk_client = mocker.patch("dirac_cwl.commands.upload_output_data.BookkeepingClient") + mock_setFileStatus = mocker.patch("DIRAC.TransformationSystem.Client.FileReport.FileReport.setFileStatus") - fr = FileReport() - mocker.patch.object(fr, "setFileStatus") - mock_file_report.return_value = fr + mock_setJobParameter = mocker.patch("DIRAC.WorkloadManagementSystem.Client.JobReport.JobReport.setJobParameter") - jr = JobReport(wf_commons["job_id"]) - mocker.patch.object(jr, "setJobParameter") - mock_job_report.return_value = jr - - req = Request() - mock_request.return_value = req + mock_transferAndRegisterFile = mocker.patch( + "DIRAC.DataManagementSystem.Client.FailoverTransfer.FailoverTransfer.transferAndRegisterFile", + return_value=S_OK({"uploadedSE": "CERN", "lfn": sim_file}), + ) - failover = FailoverTransfer(req) - mocker.patch.object( - failover, "transferAndRegisterFile", return_value=S_OK({"uploadedSE": "CERN", "lfn": sim_file}) + mock_transferAndRegisterFileFailover = mocker.patch( + "DIRAC.DataManagementSystem.Client.FailoverTransfer.FailoverTransfer.transferAndRegisterFileFailover" ) - mocker.patch.object(failover, "transferAndRegisterFileFailover") - mock_failover.return_value = failover - bkClient = BookkeepingClient() - mocker.patch.object(bkClient, "sendXMLBookkeepingReport", return_value=S_OK()) - mock_bk_client.return_value = bkClient + mock_sendXMLBookkeepingReport = mocker.patch( + "LHCbDIRAC.BookkeepingSystem.Client.BookkeepingClient.BookkeepingClient.sendXMLBookkeepingReport", + return_value=S_OK(), + ) wf_commons["outputs"] = [ {"outputDataName": sim_file, "outputDataType": "sim", "outputBKType": "SIM", "stepName": "Gauss_1"} @@ -1287,28 +1211,27 @@ def test_uploadOutputData_success(self, mocker, upload_output, wf_commons, sim_f } wf_commons["output_data_step"] = self.OUTPUT_DATA_STEP - wf_commons_path = create_workflow_commons(wf_commons) + create_workflow_commons(wf_commons) # Execute module upload_output.execute(job_path) - with open(wf_commons_path, "r", encoding="utf-8") as f: - updated_wf_commons = json.load(f) + updated_wf_commons = WorkflowCommons.load(job_path) - assert fr.setFileStatus.call_count == 0 - assert bkClient.sendXMLBookkeepingReport.call_count == 1 + assert mock_setFileStatus.call_count == 0 + assert mock_sendXMLBookkeepingReport.call_count == 1 - assert failover.transferAndRegisterFile.call_count == 1 - assert failover.transferAndRegisterFile.call_args[1]["fileName"] == sim_file + assert mock_transferAndRegisterFile.call_count == 1 + assert mock_transferAndRegisterFile.call_args[1]["fileName"] == sim_file - assert failover.transferAndRegisterFileFailover.call_count == 0 + assert mock_transferAndRegisterFileFailover.call_count == 0 - assert jr.setJobParameter.call_count == 1 - assert jr.setJobParameter.call_args[0][0] == "UploadedOutputData" - assert jr.setJobParameter.call_args[0][1] == sim_file + assert mock_setJobParameter.call_count == 1 + assert mock_setJobParameter.call_args[0][0] == "UploadedOutputData" + assert mock_setJobParameter.call_args[0][1] == sim_file # Make sure the forward DISET is not generated - operations = updated_wf_commons["request_dict"]["Operations"] + operations = json.loads(updated_wf_commons.request.toJSON()["Value"])["Operations"] assert len(operations) == 0 def test_uploadOutputData_failedBKRegistration(self, mocker, upload_output, wf_commons, sim_file, bk_file): @@ -1316,33 +1239,23 @@ def test_uploadOutputData_failedBKRegistration(self, mocker, upload_output, wf_c * The output should be uploaded but not registered in the bookkeeping system now. """ - mock_file_report = mocker.patch("dirac_cwl.commands.upload_output_data.FileReport") - mock_job_report = mocker.patch("dirac_cwl.commands.upload_output_data.JobReport") - mock_request = mocker.patch("dirac_cwl.commands.upload_output_data.Request") - mock_failover = mocker.patch("dirac_cwl.commands.upload_output_data.FailoverTransfer") - mock_bk_client = mocker.patch("dirac_cwl.commands.upload_output_data.BookkeepingClient") - - fr = FileReport() - mocker.patch.object(fr, "setFileStatus") - mock_file_report.return_value = fr + mock_setFileStatus = mocker.patch("DIRAC.TransformationSystem.Client.FileReport.FileReport.setFileStatus") - jr = JobReport(wf_commons["job_id"]) - mocker.patch.object(jr, "setJobParameter") - mock_job_report.return_value = jr + mock_setJobParameter = mocker.patch("DIRAC.WorkloadManagementSystem.Client.JobReport.JobReport.setJobParameter") - req = Request() - mock_request.return_value = req + mock_transferAndRegisterFile = mocker.patch( + "DIRAC.DataManagementSystem.Client.FailoverTransfer.FailoverTransfer.transferAndRegisterFile", + return_value=S_OK({"uploadedSE": "CERN", "lfn": sim_file}), + ) - failover = FailoverTransfer(req) - mocker.patch.object( - failover, "transferAndRegisterFile", return_value=S_OK({"uploadedSE": "CERN", "lfn": sim_file}) + mock_transferAndRegisterFileFailover = mocker.patch( + "DIRAC.DataManagementSystem.Client.FailoverTransfer.FailoverTransfer.transferAndRegisterFileFailover" ) - mocker.patch.object(failover, "transferAndRegisterFileFailover") - mock_failover.return_value = failover - bkClient = BookkeepingClient() - mocker.patch.object(bkClient, "sendXMLBookkeepingReport", return_value=S_OK()) - mock_bk_client.return_value = bkClient + mock_sendXMLBookkeepingReport = mocker.patch( + "LHCbDIRAC.BookkeepingSystem.Client.BookkeepingClient.BookkeepingClient.sendXMLBookkeepingReport", + return_value=S_OK(), + ) # BK registration failure mocker.patch( @@ -1365,28 +1278,27 @@ def test_uploadOutputData_failedBKRegistration(self, mocker, upload_output, wf_c } wf_commons["output_data_step"] = self.OUTPUT_DATA_STEP - wf_commons_path = create_workflow_commons(wf_commons) + create_workflow_commons(wf_commons) # Execute module upload_output.execute(job_path) - with open(wf_commons_path, "r", encoding="utf-8") as f: - updated_wf_commons = json.load(f) + updated_wf_commons = WorkflowCommons.load(job_path) - assert fr.setFileStatus.call_count == 0 - assert bkClient.sendXMLBookkeepingReport.call_count == 1 + assert mock_setFileStatus.call_count == 0 + assert mock_sendXMLBookkeepingReport.call_count == 1 - assert failover.transferAndRegisterFile.call_count == 1 - assert failover.transferAndRegisterFile.call_args[1]["fileName"] == sim_file + assert mock_transferAndRegisterFile.call_count == 1 + assert mock_transferAndRegisterFile.call_args[1]["fileName"] == sim_file - assert failover.transferAndRegisterFileFailover.call_count == 0 + assert mock_transferAndRegisterFileFailover.call_count == 0 - assert jr.setJobParameter.call_count == 1 - assert jr.setJobParameter.call_args[0][0] == "UploadedOutputData" - assert jr.setJobParameter.call_args[0][1] == sim_file + assert mock_setJobParameter.call_count == 1 + assert mock_setJobParameter.call_args[0][0] == "UploadedOutputData" + assert mock_setJobParameter.call_args[0][1] == sim_file # Make sure the request is generated - operations = updated_wf_commons["request_dict"]["Operations"] + operations = json.loads(updated_wf_commons.request.toJSON()["Value"])["Operations"] assert len(operations) == 1 assert operations[0]["Type"] == "RegisterFile" @@ -1398,19 +1310,23 @@ def test_uploadOutputData_postponeBKRegistration(self, mocker, upload_output, wf * The output should be uploaded but not registered in the bookkeeping system now. """ - mock_file_report = mocker.patch("dirac_cwl.commands.upload_output_data.FileReport") - mock_job_report = mocker.patch("dirac_cwl.commands.upload_output_data.JobReport") - mock_request = mocker.patch("dirac_cwl.commands.upload_output_data.Request") - mock_failover = mocker.patch("dirac_cwl.commands.upload_output_data.FailoverTransfer") - mock_bk_client = mocker.patch("dirac_cwl.commands.upload_output_data.BookkeepingClient") + mock_setFileStatus = mocker.patch("DIRAC.TransformationSystem.Client.FileReport.FileReport.setFileStatus") + + mock_setJobParameter = mocker.patch("DIRAC.WorkloadManagementSystem.Client.JobReport.JobReport.setJobParameter") + + mock_transferAndRegisterFile = mocker.patch( + "DIRAC.DataManagementSystem.Client.FailoverTransfer.FailoverTransfer.transferAndRegisterFile", + return_value=S_OK({"uploadedSE": "CERN", "lfn": sim_file}), + ) - fr = FileReport() - mocker.patch.object(fr, "setFileStatus") - mock_file_report.return_value = fr + mock_transferAndRegisterFileFailover = mocker.patch( + "DIRAC.DataManagementSystem.Client.FailoverTransfer.FailoverTransfer.transferAndRegisterFileFailover" + ) - jr = JobReport(wf_commons["job_id"]) - mocker.patch.object(jr, "setJobParameter") - mock_job_report.return_value = jr + mock_sendXMLBookkeepingReport = mocker.patch( + "LHCbDIRAC.BookkeepingSystem.Client.BookkeepingClient.BookkeepingClient.sendXMLBookkeepingReport", + return_value=S_OK(), + ) # Mock a previous failover request: the BK registration should be postponed and added to the request req = Request() @@ -1423,18 +1339,7 @@ def test_uploadOutputData_postponeBKRegistration(self, mocker, upload_output, wf o1.Type = "RegisterFile" o1.addFile(file1) req.addOperation(o1) - mock_request.return_value = req - - failover = FailoverTransfer(req) - mocker.patch.object( - failover, "transferAndRegisterFile", return_value=S_OK({"uploadedSE": "CERN", "lfn": sim_file}) - ) - mocker.patch.object(failover, "transferAndRegisterFileFailover") - mock_failover.return_value = failover - - bkClient = BookkeepingClient() - mocker.patch.object(bkClient, "sendXMLBookkeepingReport", return_value=S_OK()) - mock_bk_client.return_value = bkClient + wf_commons["request_dict"] = json.loads(req.toJSON()["Value"]) wf_commons["outputs"] = [ {"outputDataName": sim_file, "outputDataType": "sim", "outputBKType": "SIM", "stepName": "Gauss_1"} @@ -1444,28 +1349,27 @@ def test_uploadOutputData_postponeBKRegistration(self, mocker, upload_output, wf } wf_commons["output_data_step"] = self.OUTPUT_DATA_STEP - wf_commons_path = create_workflow_commons(wf_commons) + create_workflow_commons(wf_commons) # Execute module upload_output.execute(job_path) - with open(wf_commons_path, "r", encoding="utf-8") as f: - updated_wf_commons = json.load(f) + updated_wf_commons = WorkflowCommons.load(job_path) - assert fr.setFileStatus.call_count == 0 - assert bkClient.sendXMLBookkeepingReport.call_count == 1 + assert mock_setFileStatus.call_count == 0 + assert mock_sendXMLBookkeepingReport.call_count == 1 - assert failover.transferAndRegisterFile.call_count == 1 - assert failover.transferAndRegisterFile.call_args[1]["fileName"] == sim_file + assert mock_transferAndRegisterFile.call_count == 1 + assert mock_transferAndRegisterFile.call_args[1]["fileName"] == sim_file - assert failover.transferAndRegisterFileFailover.call_count == 0 + assert mock_transferAndRegisterFileFailover.call_count == 0 - assert jr.setJobParameter.call_count == 1 - assert jr.setJobParameter.call_args[0][0] == "UploadedOutputData" - assert jr.setJobParameter.call_args[0][1] == sim_file + assert mock_setJobParameter.call_count == 1 + assert mock_setJobParameter.call_args[0][0] == "UploadedOutputData" + assert mock_setJobParameter.call_args[0][1] == sim_file # Make sure the request is generated - operations = updated_wf_commons["request_dict"]["Operations"] + operations = json.loads(updated_wf_commons.request.toJSON()["Value"])["Operations"] assert len(operations) == 2 assert operations[0]["Type"] == "RegisterFile" @@ -1481,33 +1385,23 @@ def test_uploadOutputData_errorBKRegistration(self, mocker, upload_output, wf_co * The output should be uploaded but not registered in the bookkeeping system at all. """ - mock_file_report = mocker.patch("dirac_cwl.commands.upload_output_data.FileReport") - mock_job_report = mocker.patch("dirac_cwl.commands.upload_output_data.JobReport") - mock_request = mocker.patch("dirac_cwl.commands.upload_output_data.Request") - mock_failover = mocker.patch("dirac_cwl.commands.upload_output_data.FailoverTransfer") - mock_bk_client = mocker.patch("dirac_cwl.commands.upload_output_data.BookkeepingClient") - - fr = FileReport() - mocker.patch.object(fr, "setFileStatus") - mock_file_report.return_value = fr + mock_setFileStatus = mocker.patch("DIRAC.TransformationSystem.Client.FileReport.FileReport.setFileStatus") - jr = JobReport(wf_commons["job_id"]) - mocker.patch.object(jr, "setJobParameter") - mock_job_report.return_value = jr + mock_setJobParameter = mocker.patch("DIRAC.WorkloadManagementSystem.Client.JobReport.JobReport.setJobParameter") - req = Request() - mock_request.return_value = req + mock_transferAndRegisterFile = mocker.patch( + "DIRAC.DataManagementSystem.Client.FailoverTransfer.FailoverTransfer.transferAndRegisterFile", + return_value=S_OK({"uploadedSE": "CERN", "lfn": sim_file}), + ) - failover = FailoverTransfer(req) - mocker.patch.object( - failover, "transferAndRegisterFile", return_value=S_OK({"uploadedSE": "CERN", "lfn": sim_file}) + mock_transferAndRegisterFileFailover = mocker.patch( + "DIRAC.DataManagementSystem.Client.FailoverTransfer.FailoverTransfer.transferAndRegisterFileFailover" ) - mocker.patch.object(failover, "transferAndRegisterFileFailover") - mock_failover.return_value = failover - bkClient = BookkeepingClient() - mocker.patch.object(bkClient, "sendXMLBookkeepingReport", return_value=S_OK()) - mock_bk_client.return_value = bkClient + mock_sendXMLBookkeepingReport = mocker.patch( + "LHCbDIRAC.BookkeepingSystem.Client.BookkeepingClient.BookkeepingClient.sendXMLBookkeepingReport", + return_value=S_OK(), + ) # BK registration failure mocker.patch( @@ -1529,29 +1423,28 @@ def test_uploadOutputData_errorBKRegistration(self, mocker, upload_output, wf_co return_value=lambda x: S_ERROR("Error registering file"), ) - wf_commons_path = create_workflow_commons(wf_commons) + create_workflow_commons(wf_commons) # Execute module with pytest.raises(WorkflowProcessingException, match="Could Not Perform BK Registration"): upload_output.execute(job_path) - with open(wf_commons_path, "r", encoding="utf-8") as f: - updated_wf_commons = json.load(f) + updated_wf_commons = WorkflowCommons.load(job_path) - assert fr.setFileStatus.call_count == 0 - assert bkClient.sendXMLBookkeepingReport.call_count == 1 + assert mock_setFileStatus.call_count == 0 + assert mock_sendXMLBookkeepingReport.call_count == 1 - assert failover.transferAndRegisterFile.call_count == 1 - assert failover.transferAndRegisterFile.call_args[1]["fileName"] == sim_file + assert mock_transferAndRegisterFile.call_count == 1 + assert mock_transferAndRegisterFile.call_args[1]["fileName"] == sim_file - assert failover.transferAndRegisterFileFailover.call_count == 0 + assert mock_transferAndRegisterFileFailover.call_count == 0 - assert jr.setJobParameter.call_count == 1 - assert jr.setJobParameter.call_args[0][0] == "UploadedOutputData" - assert jr.setJobParameter.call_args[0][1] == sim_file + assert mock_setJobParameter.call_count == 1 + assert mock_setJobParameter.call_args[0][0] == "UploadedOutputData" + assert mock_setJobParameter.call_args[0][1] == sim_file # Make sure the request is generated - operations = updated_wf_commons["request_dict"]["Operations"] + operations = json.loads(updated_wf_commons.request.toJSON()["Value"])["Operations"] assert len(operations) == 0 def test_uploadOutputData_failUpload1(self, mocker, upload_output, wf_commons, sim_file, bk_file): @@ -1559,31 +1452,24 @@ def test_uploadOutputData_failUpload1(self, mocker, upload_output, wf_commons, s * The output should be uploaded correctly with the second method. """ - mock_file_report = mocker.patch("dirac_cwl.commands.upload_output_data.FileReport") - mock_job_report = mocker.patch("dirac_cwl.commands.upload_output_data.JobReport") - mock_request = mocker.patch("dirac_cwl.commands.upload_output_data.Request") - mock_failover = mocker.patch("dirac_cwl.commands.upload_output_data.FailoverTransfer") - mock_bk_client = mocker.patch("dirac_cwl.commands.upload_output_data.BookkeepingClient") - - fr = FileReport() - mocker.patch.object(fr, "setFileStatus") - mock_file_report.return_value = fr + mock_setFileStatus = mocker.patch("DIRAC.TransformationSystem.Client.FileReport.FileReport.setFileStatus") - jr = JobReport(wf_commons["job_id"]) - mocker.patch.object(jr, "setJobParameter") - mock_job_report.return_value = jr + mock_setJobParameter = mocker.patch("DIRAC.WorkloadManagementSystem.Client.JobReport.JobReport.setJobParameter") - req = Request() - mock_request.return_value = req + mock_transferAndRegisterFile = mocker.patch( + "DIRAC.DataManagementSystem.Client.FailoverTransfer.FailoverTransfer.transferAndRegisterFile", + return_value=S_ERROR("Error uploading file"), + ) - failover = FailoverTransfer(req) - mocker.patch.object(failover, "transferAndRegisterFile", return_value=S_ERROR("Error uploading file")) - mocker.patch.object(failover, "transferAndRegisterFileFailover", return_value=S_OK()) - mock_failover.return_value = failover + mock_transferAndRegisterFileFailover = mocker.patch( + "DIRAC.DataManagementSystem.Client.FailoverTransfer.FailoverTransfer.transferAndRegisterFileFailover", + return_value=S_OK(), + ) - bkClient = BookkeepingClient() - mocker.patch.object(bkClient, "sendXMLBookkeepingReport", return_value=S_OK()) - mock_bk_client.return_value = bkClient + mock_sendXMLBookkeepingReport = mocker.patch( + "LHCbDIRAC.BookkeepingSystem.Client.BookkeepingClient.BookkeepingClient.sendXMLBookkeepingReport", + return_value=S_OK(), + ) wf_commons["outputs"] = [ {"outputDataName": sim_file, "outputDataType": "sim", "outputBKType": "SIM", "stepName": "Gauss_1"} @@ -1593,29 +1479,28 @@ def test_uploadOutputData_failUpload1(self, mocker, upload_output, wf_commons, s } wf_commons["output_data_step"] = self.OUTPUT_DATA_STEP - wf_commons_path = create_workflow_commons(wf_commons) + create_workflow_commons(wf_commons) # Execute module upload_output.execute(job_path) - with open(wf_commons_path, "r", encoding="utf-8") as f: - updated_wf_commons = json.load(f) + updated_wf_commons = WorkflowCommons.load(job_path) - assert fr.setFileStatus.call_count == 0 - assert bkClient.sendXMLBookkeepingReport.call_count == 1 + assert mock_setFileStatus.call_count == 0 + assert mock_sendXMLBookkeepingReport.call_count == 1 - assert failover.transferAndRegisterFile.call_count == 1 - assert failover.transferAndRegisterFile.call_args[1]["fileName"] == sim_file + assert mock_transferAndRegisterFile.call_count == 1 + assert mock_transferAndRegisterFile.call_args[1]["fileName"] == sim_file - assert failover.transferAndRegisterFileFailover.call_count == 1 - assert failover.transferAndRegisterFileFailover.call_args[1]["fileName"] == sim_file + assert mock_transferAndRegisterFileFailover.call_count == 1 + assert mock_transferAndRegisterFileFailover.call_args[1]["fileName"] == sim_file - assert jr.setJobParameter.call_count == 1 - assert jr.setJobParameter.call_args[0][0] == "UploadedOutputData" - assert jr.setJobParameter.call_args[0][1] == sim_file + assert mock_setJobParameter.call_count == 1 + assert mock_setJobParameter.call_args[0][0] == "UploadedOutputData" + assert mock_setJobParameter.call_args[0][1] == sim_file # Make sure the request is not generated - operations = updated_wf_commons["request_dict"]["Operations"] + operations = json.loads(updated_wf_commons.request.toJSON()["Value"])["Operations"] assert len(operations) == 0 def test_uploadOutputData_failUpload2(self, mocker, upload_output, wf_commons, sim_file, bk_file): @@ -1623,19 +1508,24 @@ def test_uploadOutputData_failUpload2(self, mocker, upload_output, wf_commons, s * A request should be generated to upload outputs later. """ - mock_file_report = mocker.patch("dirac_cwl.commands.upload_output_data.FileReport") - mock_job_report = mocker.patch("dirac_cwl.commands.upload_output_data.JobReport") - mock_request = mocker.patch("dirac_cwl.commands.upload_output_data.Request") - mock_failover = mocker.patch("dirac_cwl.commands.upload_output_data.FailoverTransfer") - mock_bk_client = mocker.patch("dirac_cwl.commands.upload_output_data.BookkeepingClient") + mock_setFileStatus = mocker.patch("DIRAC.TransformationSystem.Client.FileReport.FileReport.setFileStatus") + + mock_setJobParameter = mocker.patch("DIRAC.WorkloadManagementSystem.Client.JobReport.JobReport.setJobParameter") + + mock_transferAndRegisterFile = mocker.patch( + "DIRAC.DataManagementSystem.Client.FailoverTransfer.FailoverTransfer.transferAndRegisterFile", + return_value=S_ERROR("Error uploading file"), + ) - fr = FileReport() - mocker.patch.object(fr, "setFileStatus") - mock_file_report.return_value = fr + mock_transferAndRegisterFileFailover = mocker.patch( + "DIRAC.DataManagementSystem.Client.FailoverTransfer.FailoverTransfer.transferAndRegisterFileFailover", + return_value=S_ERROR("Error uploading file"), + ) - jr = JobReport(wf_commons["job_id"]) - mocker.patch.object(jr, "setJobParameter") - mock_job_report.return_value = jr + mock_sendXMLBookkeepingReport = mocker.patch( + "LHCbDIRAC.BookkeepingSystem.Client.BookkeepingClient.BookkeepingClient.sendXMLBookkeepingReport", + return_value=S_OK(), + ) # Mock a previous failover request: # Add the end of the execution, o1 should be removed @@ -1659,16 +1549,7 @@ def test_uploadOutputData_failUpload2(self, mocker, upload_output, wf_commons, s req.addOperation(o1) req.addOperation(o2) - mock_request.return_value = req - - failover = FailoverTransfer(req) - mocker.patch.object(failover, "transferAndRegisterFile", return_value=S_ERROR("Error uploading file")) - mocker.patch.object(failover, "transferAndRegisterFileFailover", return_value=S_ERROR("Error uploading file")) - mock_failover.return_value = failover - - bkClient = BookkeepingClient() - mocker.patch.object(bkClient, "sendXMLBookkeepingReport", return_value=S_OK()) - mock_bk_client.return_value = bkClient + wf_commons["request_dict"] = json.loads(req.toJSON()["Value"]) wf_commons["outputs"] = [ {"outputDataName": sim_file, "outputDataType": "sim", "outputBKType": "SIM", "stepName": "Gauss_1"} @@ -1678,29 +1559,28 @@ def test_uploadOutputData_failUpload2(self, mocker, upload_output, wf_commons, s } wf_commons["output_data_step"] = self.OUTPUT_DATA_STEP - wf_commons_path = create_workflow_commons(wf_commons) + create_workflow_commons(wf_commons) # Execute module with pytest.raises(WorkflowProcessingException, match="Failed to upload output data"): upload_output.execute(job_path) - with open(wf_commons_path, "r", encoding="utf-8") as f: - updated_wf_commons = json.load(f) + updated_wf_commons = WorkflowCommons.load(job_path) - assert fr.setFileStatus.call_count == 0 - assert bkClient.sendXMLBookkeepingReport.call_count == 1 + assert mock_setFileStatus.call_count == 0 + assert mock_sendXMLBookkeepingReport.call_count == 1 - assert failover.transferAndRegisterFile.call_count == 1 - assert failover.transferAndRegisterFile.call_args[1]["fileName"] == sim_file + assert mock_transferAndRegisterFile.call_count == 1 + assert mock_transferAndRegisterFile.call_args[1]["fileName"] == sim_file - assert failover.transferAndRegisterFileFailover.call_count == 1 - assert failover.transferAndRegisterFileFailover.call_args[1]["fileName"] == sim_file + assert mock_transferAndRegisterFileFailover.call_count == 1 + assert mock_transferAndRegisterFileFailover.call_args[1]["fileName"] == sim_file - assert jr.setJobParameter.call_count == 0 + assert mock_setJobParameter.call_count == 0 # Make sure the request is generated - operations = updated_wf_commons["request_dict"]["Operations"] + operations = json.loads(updated_wf_commons.request.toJSON()["Value"])["Operations"] assert len(operations) == 2 assert operations[0]["Type"] == "RegisterFile" @@ -1719,38 +1599,24 @@ def test_uploadOutputData_BKReportError(self, mocker, upload_output, wf_commons, * The output should be uploaded and registered in the bookkeeping system. * The bookkeeping report should be added to a failover request. """ - mock_file_report = mocker.patch("dirac_cwl.commands.upload_output_data.FileReport") - mock_job_report = mocker.patch("dirac_cwl.commands.upload_output_data.JobReport") - mock_request = mocker.patch("dirac_cwl.commands.upload_output_data.Request") - mock_failover = mocker.patch("dirac_cwl.commands.upload_output_data.FailoverTransfer") - mock_bk_client = mocker.patch("dirac_cwl.commands.upload_output_data.BookkeepingClient") + mock_setFileStatus = mocker.patch("DIRAC.TransformationSystem.Client.FileReport.FileReport.setFileStatus") - fr = FileReport() - mocker.patch.object(fr, "setFileStatus") - mock_file_report.return_value = fr + mock_setJobParameter = mocker.patch("DIRAC.WorkloadManagementSystem.Client.JobReport.JobReport.setJobParameter") - jr = JobReport(wf_commons["job_id"]) - mocker.patch.object(jr, "setJobParameter") - mock_job_report.return_value = jr - - req = Request() - mock_request.return_value = req + mock_transferAndRegisterFile = mocker.patch( + "DIRAC.DataManagementSystem.Client.FailoverTransfer.FailoverTransfer.transferAndRegisterFile", + return_value=S_OK({"uploadedSE": "CERN", "lfn": sim_file}), + ) - failover = FailoverTransfer(req) - mocker.patch.object( - failover, "transferAndRegisterFile", return_value=S_OK({"uploadedSE": "CERN", "lfn": sim_file}) + mock_transferAndRegisterFileFailover = mocker.patch( + "DIRAC.DataManagementSystem.Client.FailoverTransfer.FailoverTransfer.transferAndRegisterFileFailover", + return_value=S_ERROR("Error uploading file"), ) - mocker.patch.object(failover, "transferAndRegisterFileFailover", return_value=S_ERROR("Error uploading file")) - mock_failover.return_value = failover - bkClient = BookkeepingClient() - # Mock the sendXMLBookkeepingReport method - mocker.patch.object( - bkClient, - "sendXMLBookkeepingReport", + mock_sendXMLBookkeepingReport = mocker.patch( + "LHCbDIRAC.BookkeepingSystem.Client.BookkeepingClient.BookkeepingClient.sendXMLBookkeepingReport", return_value={"OK": False, "rpcStub": "Error", "Message": "Error sending BK report"}, ) - mock_bk_client.return_value = bkClient wf_commons["outputs"] = [ {"outputDataName": sim_file, "outputDataType": "sim", "outputBKType": "SIM", "stepName": "Gauss_1"} @@ -1760,28 +1626,27 @@ def test_uploadOutputData_BKReportError(self, mocker, upload_output, wf_commons, } wf_commons["output_data_step"] = self.OUTPUT_DATA_STEP - wf_commons_path = create_workflow_commons(wf_commons) + create_workflow_commons(wf_commons) # Execute module upload_output.execute(job_path) - with open(wf_commons_path, "r", encoding="utf-8") as f: - updated_wf_commons = json.load(f) + updated_wf_commons = WorkflowCommons.load(job_path) - assert fr.setFileStatus.call_count == 0 - assert bkClient.sendXMLBookkeepingReport.call_count == 1 + assert mock_setFileStatus.call_count == 0 + assert mock_sendXMLBookkeepingReport.call_count == 1 - assert failover.transferAndRegisterFile.call_count == 1 - assert failover.transferAndRegisterFile.call_args[1]["fileName"] == sim_file + assert mock_transferAndRegisterFile.call_count == 1 + assert mock_transferAndRegisterFile.call_args[1]["fileName"] == sim_file - assert failover.transferAndRegisterFileFailover.call_count == 0 + assert mock_transferAndRegisterFileFailover.call_count == 0 - assert jr.setJobParameter.call_count == 1 - assert jr.setJobParameter.call_args[0][0] == "UploadedOutputData" - assert jr.setJobParameter.call_args[0][1] == sim_file + assert mock_setJobParameter.call_count == 1 + assert mock_setJobParameter.call_args[0][0] == "UploadedOutputData" + assert mock_setJobParameter.call_args[0][1] == sim_file # Make sure the request is not generated - operations = updated_wf_commons["request_dict"]["Operations"] + operations = json.loads(updated_wf_commons.request.toJSON()["Value"])["Operations"] assert len(operations) == 1 assert operations[0]["Type"] == "ForwardDISET" @@ -1793,37 +1658,26 @@ def test_uploadOutputData_withDescendents(self, mocker, upload_output, wf_common * The output should not be uploaded and registered in the bookkeeping system. * The bookkeeping report should not be sent. """ - mock_file_report = mocker.patch("dirac_cwl.commands.upload_output_data.FileReport") - mock_job_report = mocker.patch("dirac_cwl.commands.upload_output_data.JobReport") - mock_request = mocker.patch("dirac_cwl.commands.upload_output_data.Request") - mock_failover = mocker.patch("dirac_cwl.commands.upload_output_data.FailoverTransfer") - mock_bk_client = mocker.patch("dirac_cwl.commands.upload_output_data.BookkeepingClient") - mocker.patch( "dirac_cwl.commands.upload_output_data.getFileDescendents", return_value=S_OK(["/path/to/other/file.txt"]) ) - fr = FileReport() - mocker.patch.object(fr, "setFileStatus") - mock_file_report.return_value = fr + mock_setFileStatus = mocker.patch("DIRAC.TransformationSystem.Client.FileReport.FileReport.setFileStatus") - jr = JobReport(wf_commons["job_id"]) - mocker.patch.object(jr, "setJobParameter") - mock_job_report.return_value = jr + mock_setJobParameter = mocker.patch("DIRAC.WorkloadManagementSystem.Client.JobReport.JobReport.setJobParameter") - req = Request() - mock_request.return_value = req + mock_transferAndRegisterFile = mocker.patch( + "DIRAC.DataManagementSystem.Client.FailoverTransfer.FailoverTransfer.transferAndRegisterFile", + return_value=S_OK({"uploadedSE": "CERN", "lfn": sim_file}), + ) - failover = FailoverTransfer(req) - mocker.patch.object( - failover, "transferAndRegisterFile", return_value=S_OK({"uploadedSE": "CERN", "lfn": sim_file}) + mock_transferAndRegisterFileFailover = mocker.patch( + "DIRAC.DataManagementSystem.Client.FailoverTransfer.FailoverTransfer.transferAndRegisterFileFailover" ) - mocker.patch.object(failover, "transferAndRegisterFileFailover") - mock_failover.return_value = failover - bkClient = BookkeepingClient() - mocker.patch.object(bkClient, "sendXMLBookkeepingReport") - mock_bk_client.return_value = bkClient + mock_sendXMLBookkeepingReport = mocker.patch( + "LHCbDIRAC.BookkeepingSystem.Client.BookkeepingClient.BookkeepingClient.sendXMLBookkeepingReport" + ) wf_commons["outputs"] = [ {"outputDataName": sim_file, "outputDataType": "sim", "outputBKType": "SIM", "stepName": "Gauss_1"} @@ -1834,57 +1688,45 @@ def test_uploadOutputData_withDescendents(self, mocker, upload_output, wf_common wf_commons["inputs"] = ["AnyInputFile1"] wf_commons["output_data_step"] = self.OUTPUT_DATA_STEP - wf_commons_path = create_workflow_commons(wf_commons) + create_workflow_commons(wf_commons) # Execute module with pytest.raises(WorkflowProcessingException): upload_output.execute(job_path) - with open(wf_commons_path, "r", encoding="utf-8") as f: - updated_wf_commons = json.load(f) + updated_wf_commons = WorkflowCommons.load(job_path) - assert fr.setFileStatus.call_count == 1 - assert fr.setFileStatus.call_args[0][0] == int(wf_commons["production_id"]) - assert bkClient.sendXMLBookkeepingReport.call_count == 0 + assert mock_setFileStatus.assert_called_once + assert mock_setFileStatus.call_args[0][0] == int(wf_commons["production_id"]) + assert mock_sendXMLBookkeepingReport.call_count == 0 - assert failover.transferAndRegisterFile.call_count == 0 - assert failover.transferAndRegisterFileFailover.call_count == 0 + assert mock_transferAndRegisterFile.call_count == 0 + assert mock_transferAndRegisterFileFailover.call_count == 0 - assert jr.setJobParameter.call_count == 0 + assert mock_setJobParameter.call_count == 0 # Make sure the request is not generated - operations = updated_wf_commons["request_dict"]["Operations"] + operations = json.loads(updated_wf_commons.request.toJSON()["Value"])["Operations"] assert len(operations) == 0 def test_uploadOutputData_noOutput(self, mocker, upload_output, wf_commons, sim_file): """Test UploadOutputData with no output data.""" - mock_file_report = mocker.patch("dirac_cwl.commands.upload_output_data.FileReport") - mock_job_report = mocker.patch("dirac_cwl.commands.upload_output_data.JobReport") - mock_request = mocker.patch("dirac_cwl.commands.upload_output_data.Request") - mock_failover = mocker.patch("dirac_cwl.commands.upload_output_data.FailoverTransfer") - mock_bk_client = mocker.patch("dirac_cwl.commands.upload_output_data.BookkeepingClient") + mock_setFileStatus = mocker.patch("DIRAC.TransformationSystem.Client.FileReport.FileReport.setFileStatus") - fr = FileReport() - mocker.patch.object(fr, "setFileStatus") - mock_file_report.return_value = fr + mock_setJobParameter = mocker.patch("DIRAC.WorkloadManagementSystem.Client.JobReport.JobReport.setJobParameter") - jr = JobReport(wf_commons["job_id"]) - mocker.patch.object(jr, "setJobParameter") - mock_job_report.return_value = jr - - req = Request() - mock_request.return_value = req + mock_transferAndRegisterFile = mocker.patch( + "DIRAC.DataManagementSystem.Client.FailoverTransfer.FailoverTransfer.transferAndRegisterFile", + return_value=S_OK({"uploadedSE": "CERN", "lfn": sim_file}), + ) - failover = FailoverTransfer(req) - mocker.patch.object( - failover, "transferAndRegisterFile", return_value=S_OK({"uploadedSE": "CERN", "lfn": sim_file}) + mock_transferAndRegisterFileFailover = mocker.patch( + "DIRAC.DataManagementSystem.Client.FailoverTransfer.FailoverTransfer.transferAndRegisterFileFailover" ) - mocker.patch.object(failover, "transferAndRegisterFileFailover") - mock_failover.return_value = failover - bkClient = BookkeepingClient() - mocker.patch.object(bkClient, "sendXMLBookkeepingReport") - mock_bk_client.return_value = bkClient + mock_sendXMLBookkeepingReport = mocker.patch( + "LHCbDIRAC.BookkeepingSystem.Client.BookkeepingClient.BookkeepingClient.sendXMLBookkeepingReport" + ) wf_commons["outputs"] = [ {"outputDataName": sim_file, "outputDataType": "sim", "outputBKType": "SIM", "stepName": "Gauss_1"} @@ -1897,55 +1739,44 @@ def test_uploadOutputData_noOutput(self, mocker, upload_output, wf_commons, sim_ # Remove the output Path(sim_file).unlink(missing_ok=True) - wf_commons_path = create_workflow_commons(wf_commons) + create_workflow_commons(wf_commons) # Execute module with pytest.raises(WorkflowProcessingException, match="Output data not found"): upload_output.execute(job_path) - with open(wf_commons_path, "r", encoding="utf-8") as f: - updated_wf_commons = json.load(f) + updated_wf_commons = WorkflowCommons.load(job_path) - assert fr.setFileStatus.call_count == 0 - assert bkClient.sendXMLBookkeepingReport.call_count == 0 + assert mock_setFileStatus.call_count == 0 + assert mock_sendXMLBookkeepingReport.call_count == 0 - assert failover.transferAndRegisterFile.call_count == 0 - assert failover.transferAndRegisterFileFailover.call_count == 0 + assert mock_transferAndRegisterFile.call_count == 0 + assert mock_transferAndRegisterFileFailover.call_count == 0 - assert jr.setJobParameter.call_count == 0 + assert mock_setJobParameter.call_count == 0 # Make sure the request is not generated print(updated_wf_commons) - operations = updated_wf_commons["request_dict"]["Operations"] + operations = json.loads(updated_wf_commons.request.toJSON()["Value"])["Operations"] assert len(operations) == 0 def test_uploadOutputData_previousError_fail(self, mocker, upload_output, wf_commons, sim_file): """Test UploadOutputData with an intentional failure.""" - mock_file_report = mocker.patch("dirac_cwl.commands.upload_output_data.FileReport") - mock_job_report = mocker.patch("dirac_cwl.commands.upload_output_data.JobReport") - mock_request = mocker.patch("dirac_cwl.commands.upload_output_data.Request") - mock_failover = mocker.patch("dirac_cwl.commands.upload_output_data.FailoverTransfer") - mock_bk_client = mocker.patch("dirac_cwl.commands.upload_output_data.BookkeepingClient") - - fr = FileReport() - mocker.patch.object(fr, "setFileStatus") - mock_file_report.return_value = fr + mock_setFileStatus = mocker.patch("DIRAC.TransformationSystem.Client.FileReport.FileReport.setFileStatus") - jr = JobReport(wf_commons["job_id"]) - mocker.patch.object(jr, "setJobParameter") - mock_job_report.return_value = jr + mock_setJobParameter = mocker.patch("DIRAC.WorkloadManagementSystem.Client.JobReport.JobReport.setJobParameter") - req = Request() - mock_request.return_value = req + mock_transferAndRegisterFile = mocker.patch( + "DIRAC.DataManagementSystem.Client.FailoverTransfer.FailoverTransfer.transferAndRegisterFile" + ) - failover = FailoverTransfer(req) - mocker.patch.object(failover, "transferAndRegisterFile") - mocker.patch.object(failover, "transferAndRegisterFileFailover") - mock_failover.return_value = failover + mock_transferAndRegisterFileFailover = mocker.patch( + "DIRAC.DataManagementSystem.Client.FailoverTransfer.FailoverTransfer.transferAndRegisterFileFailover" + ) - bkClient = BookkeepingClient() - mocker.patch.object(bkClient, "sendXMLBookkeepingReport") - mock_bk_client.return_value = bkClient + mock_sendXMLBookkeepingReport = mocker.patch( + "LHCbDIRAC.BookkeepingSystem.Client.BookkeepingClient.BookkeepingClient.sendXMLBookkeepingReport" + ) wf_commons["outputs"] = [ {"outputDataName": sim_file, "outputDataType": "sim", "outputBKType": "SIM", "stepName": "Gauss_1"} @@ -1955,27 +1786,26 @@ def test_uploadOutputData_previousError_fail(self, mocker, upload_output, wf_com } wf_commons["output_data_step"] = self.OUTPUT_DATA_STEP - wf_commons["step_status"] = S_ERROR() + wf_commons["step_status"] = StepStatus.Failed Path(sim_file).unlink(missing_ok=True) - wf_commons_path = create_workflow_commons(wf_commons) + create_workflow_commons(wf_commons) upload_output.execute(job_path) - with open(wf_commons_path, "r", encoding="utf-8") as f: - updated_wf_commons = json.load(f) + updated_wf_commons = WorkflowCommons.load(job_path) - assert fr.setFileStatus.call_count == 0 - assert bkClient.sendXMLBookkeepingReport.call_count == 0 + assert mock_setFileStatus.call_count == 0 + assert mock_sendXMLBookkeepingReport.call_count == 0 - assert failover.transferAndRegisterFile.call_count == 0 - assert failover.transferAndRegisterFileFailover.call_count == 0 + assert mock_transferAndRegisterFile.call_count == 0 + assert mock_transferAndRegisterFileFailover.call_count == 0 - assert jr.setJobParameter.call_count == 0 + assert mock_setJobParameter.call_count == 0 # Make sure the request is not generated - operations = updated_wf_commons["request_dict"]["Operations"] + operations = json.loads(updated_wf_commons.request.toJSON()["Value"])["Operations"] assert len(operations) == 0 @@ -1990,17 +1820,9 @@ def axlf(self, mocker): # Test scenarios def test_analyseXMLSummary_basic_success(self, mocker, axlf, wf_commons, xml_summary_file): """Test basic success scenario.""" - mock_file_report = mocker.patch("dirac_cwl.commands.analyze_xml_summary.FileReport") - mock_job_report = mocker.patch("dirac_cwl.commands.analyze_xml_summary.JobReport") - - fr = FileReport() - - jr = JobReport(wf_commons["job_id"]) - mocker.patch.object(jr, "setApplicationStatus") - jr.setApplicationStatus.return_value = S_OK() - - mock_file_report.return_value = fr - mock_job_report.return_value = jr + mock_setApplicationStatus = mocker.patch( + "DIRAC.WorkloadManagementSystem.Client.JobReport.JobReport.setApplicationStatus", return_value=S_OK() + ) xml_content = dedent(""" @@ -2632,15 +2383,13 @@ def test_accounting_noApplicationName_fail(self, mocker, accounting, wf_commons, with pytest.raises(WorkflowProcessingException): accounting.execute(job_path) - assert not dsc.addRegister.called, "No accounting data should be added." + updated_wf_commons = WorkflowCommons.load(job_path) + + # Make sure the dsc was not called + assert len(updated_wf_commons.accounting_registers) == 0 def test_accounting_incompleteData(self, mocker, accounting, wf_commons, xml_summary_file): """Test successful execution of WorkflowAccounting module.""" - mock_data_store = mocker.patch("dirac_cwl.commands.workflow_accounting.DataStoreClient") - dsc = DataStoreClient() - mocker.patch.object(dsc, "addRegister") - mock_data_store.return_value = dsc - xml_content = dedent(""" @@ -2670,15 +2419,13 @@ def test_accounting_incompleteData(self, mocker, accounting, wf_commons, xml_sum with pytest.raises(WorkflowProcessingException): accounting.execute(job_path) - assert not dsc.addRegister.called, "No accounting data should be added." + updated_wf_commons = WorkflowCommons.load(job_path) + + # Make sure the dsc was not called + assert len(updated_wf_commons.accounting_registers) == 0 def test_accounting_previousError_fail(self, mocker, accounting, wf_commons, xml_summary_file): """Test WorkflowAccounting with an intentional failure.""" - mock_data_store = mocker.patch("dirac_cwl.commands.workflow_accounting.DataStoreClient") - dsc = DataStoreClient() - mocker.patch.object(dsc, "addRegister") - mock_data_store.return_value = dsc - xml_content = dedent(""" @@ -2705,10 +2452,13 @@ def test_accounting_previousError_fail(self, mocker, accounting, wf_commons, xml wf_commons["bk_step_id"] = "12345" wf_commons["step_proc_pass"] = "Sim09m" wf_commons["event_type"] = "23103003" - wf_commons["step_status"] = S_ERROR() + wf_commons["step_status"] = StepStatus.Failed create_workflow_commons(wf_commons) accounting.execute(job_path) - assert dsc.addRegister.called, "Accounting data should be added." + updated_wf_commons = WorkflowCommons.load(job_path) + + # Make sure the dsc was called + assert len(updated_wf_commons.accounting_registers) == 1 From 396645e05bd0c4793cc37fb18a795e2363538c91 Mon Sep 17 00:00:00 2001 From: Jorge Lisa <64639359+AcquaDiGiorgio@users.noreply.github.com> Date: Fri, 15 May 2026 16:39:20 +0200 Subject: [PATCH 21/21] chore: fix typos --- src/dirac_cwl/commands/upload_output_data.py | 12 ++++++------ src/dirac_cwl/commands/workflow_commons.py | 1 - 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/dirac_cwl/commands/upload_output_data.py b/src/dirac_cwl/commands/upload_output_data.py index b66ac2f..44ee581 100644 --- a/src/dirac_cwl/commands/upload_output_data.py +++ b/src/dirac_cwl/commands/upload_output_data.py @@ -54,7 +54,7 @@ def execute(self, job_path: os.PathLike, **kwargs): result = constructProductionLFNs(parameters, workflow_commons.bk_client) if not result["OK"]: - raise WorkflowProcessingException("Unable to construsct production LFNs") + raise WorkflowProcessingException("Unable to construct production LFNs") workflow_commons.prod_output_lfns = result["Value"]["ProductionOutputData"] @@ -78,19 +78,19 @@ def execute(self, job_path: os.PathLike, **kwargs): ) if workflow_commons.inputs: - lfns_with_descendants = workflow_commons.file_descendants + lfns_with_descendents = workflow_commons.file_descendents - if not lfns_with_descendants: - lfns_with_descendants = getFileDescendents( + if not lfns_with_descendents: + lfns_with_descendents = getFileDescendents( workflow_commons.production_id, workflow_commons.inputs, dm=workflow_commons.data_manager, bkClient=workflow_commons.bk_client, ) - if lfns_with_descendants: + if lfns_with_descendents: workflow_commons.file_report.setFileStatus( - int(workflow_commons.production_id), lfns_with_descendants, "Processed" + int(workflow_commons.production_id), lfns_with_descendents, "Processed" ) raise WorkflowProcessingException("Input Data Already Processed") diff --git a/src/dirac_cwl/commands/workflow_commons.py b/src/dirac_cwl/commands/workflow_commons.py index 895f007..f733023 100644 --- a/src/dirac_cwl/commands/workflow_commons.py +++ b/src/dirac_cwl/commands/workflow_commons.py @@ -80,7 +80,6 @@ class WorkflowCommons(BaseModel): file_md5_map: dict[str, str] = {} file_guid_map: dict[str, str] = {} - file_descendants: list[str] = [] bookkeeping_lfns: list[str] = [] prod_output_lfns: list[str] = []