From 78a0d6826e079becfba8e3dca4bd211283ccdfef Mon Sep 17 00:00:00 2001 From: Andres Rios Tascon Date: Mon, 5 Jan 2026 14:33:51 -0500 Subject: [PATCH 1/2] Removed minio dependency --- CONTRIBUTING.md | 1 - README.md | 2 +- pyproject.toml | 1 - src/uproot/__init__.py | 1 - src/uproot/extras.py | 20 -------- src/uproot/source/s3.py | 90 --------------------------------- tests/test_0916_read_from_s3.py | 8 +-- 7 files changed, 5 insertions(+), 118 deletions(-) delete mode 100644 src/uproot/source/s3.py diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 4ef422e57..a3d56383b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -32,7 +32,6 @@ This guide will help you get started with contributing. conda install root conda install pandas conda install dask - conda install minio # pip-only dependencies pip install scikit-hep-testdata diff --git a/README.md b/README.md index 9d4e54e0b..5ae4a04f2 100644 --- a/README.md +++ b/README.md @@ -81,7 +81,7 @@ The following libraries are also useful in conjunction with Uproot, but are not **For accessing remote files:** - * `minio`: if reading files with `s3://` URIs. + * `s3fs`: if reading files with `s3://` URIs. * `xrootd`: if reading files with `root://` URIs. * HTTP/S access is built in (Python standard library). diff --git a/pyproject.toml b/pyproject.toml index 6684b3228..0d9100c3e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -23,7 +23,6 @@ test = [ "deflate", "fsspec-xrootd>=0.5.0", "isal", - "minio", "paramiko", "pytest-rerunfailures", "rangehttpserver", diff --git a/src/uproot/__init__.py b/src/uproot/__init__.py index a324f4664..d06442972 100644 --- a/src/uproot/__init__.py +++ b/src/uproot/__init__.py @@ -89,7 +89,6 @@ from uproot.source.http import MultithreadedHTTPSource from uproot.source.xrootd import XRootDSource from uproot.source.xrootd import MultithreadedXRootDSource -from uproot.source.s3 import S3Source from uproot.source.object import ObjectSource from uproot.source.fsspec import FSSpecSource from uproot.source.cursor import Cursor diff --git a/src/uproot/extras.py b/src/uproot/extras.py index 45d86b229..82f099b71 100644 --- a/src/uproot/extras.py +++ b/src/uproot/extras.py @@ -60,26 +60,6 @@ def pandas(): return pandas -def Minio_client(): - """ - Imports and returns ``minio.Minio``. - """ - try: - from minio import Minio - except ModuleNotFoundError as err: - raise ModuleNotFoundError( - """install the 'minio' package with: - - pip install minio - -or - - conda install minio""" - ) from err - else: - return Minio - - def XRootD_client(): """ Imports and returns ``XRootD.client`` (after setting the diff --git a/src/uproot/source/s3.py b/src/uproot/source/s3.py deleted file mode 100644 index 19a9eb58c..000000000 --- a/src/uproot/source/s3.py +++ /dev/null @@ -1,90 +0,0 @@ -# BSD 3-Clause License; see https://github.com/scikit-hep/uproot5/blob/main/LICENSE - -""" -This module defines a physical layer for remote files, accessed via S3. -""" - -from __future__ import annotations - -import os -from urllib.parse import parse_qsl, urlparse - -import uproot.extras -import uproot.source.http - - -class S3Source(uproot.source.http.HTTPSource): - """ - Args: - file_path (str): A URL of the file to open. - endpoint: S3 endpoint (defaults to AWS) - access_key: Access key of your S3 account - secret_key: Secret key of your S3 account - session_token: Session token of your S3 account - secure: Flag to enable use of TLS - http_client (urllib3.poolmanager.PoolManager): Instance of :doc:`urllib3.poolmanager.PoolManager` - credentials (minio.credentials.Provider): Instance of :doc:`minio.credentials.Provider` - options: See :doc:`uproot.source.http.HTTPSource.__init__` - """ - - def __init__( - self, - file_path: str, - endpoint="s3.amazonaws.com", - access_key=None, - secret_key=None, - session_token=None, - secure=True, - region=None, - http_client=None, - credentials=None, - **options, - ): - Minio = uproot.extras.Minio_client() - - self._file_path = file_path - if access_key is None: - access_key = os.environ.get( - "S3_ACCESS_KEY", os.environ.get("AWS_ACCESS_KEY_ID", None) - ) - if secret_key is None: - secret_key = os.environ.get( - "S3_SECRET_KEY", os.environ.get("AWS_SECRET_ACCESS_KEY", None) - ) - if session_token is None: - session_token = os.environ.get( - "S3_SESSION_TOKEN", os.environ.get("AWS_SESSION_TOKEN", None) - ) - if region is None: - region = os.environ.get("AWS_DEFAULT_REGION", None) - - parsed_url = urlparse(file_path) - - bucket_name = parsed_url.netloc - assert parsed_url.path[0] == "/" - object_name = parsed_url.path[1:] - - parsed_query = dict(parse_qsl(parsed_url.query)) - # There is no standard scheme for s3:// URI query parameters, - # but some are often introduced to support extra flexibility: - if "endpoint" in parsed_query: - endpoint = parsed_query["endpoint"] - if "region" in parsed_query: - region = parsed_query["region"] - - client = Minio( - endpoint=endpoint, - access_key=access_key, - secret_key=secret_key, - session_token=session_token, - secure=secure, - region=region, - http_client=http_client, - credentials=credentials, - ) - - url = client.get_presigned_url( - method="GET", bucket_name=bucket_name, object_name=object_name - ) - - super().__init__(url, **options) diff --git a/tests/test_0916_read_from_s3.py b/tests/test_0916_read_from_s3.py index ef85a2949..6b86dcf03 100644 --- a/tests/test_0916_read_from_s3.py +++ b/tests/test_0916_read_from_s3.py @@ -6,15 +6,15 @@ import uproot -pytest.importorskip("minio") +pytest.importorskip("s3fs") @pytest.mark.network def test_s3_fail(): with pytest.raises((FileNotFoundError, TimeoutError, socket.timeout)): # Sometimes this raises a timeout error that doesn't go away for a long time, we might as well skip it. - with uproot.source.s3.S3Source( - "s3://pivarski-princeton/does-not-exist", timeout=0.1 + with uproot.source.fsspec.FSSpecSource( + "s3://pivarski-princeton/does-not-exist", timeout=0.1, anon=True ) as source: uproot._util.tobytes(source.chunk(0, 100).raw_data) @@ -23,7 +23,7 @@ def test_s3_fail(): def test_read_s3(): with uproot.open( "s3://pivarski-princeton/pythia_ppZee_run17emb.picoDst.root:PicoDst", - handler=uproot.source.s3.S3Source, + anon=True, ) as f: data = f["Event/Event.mEventId"].array(library="np") assert len(data) == 8004 From 5b42f298de8647e32e50599836ea6d7fdca6cb2e Mon Sep 17 00:00:00 2001 From: Andres Rios Tascon Date: Mon, 5 Jan 2026 14:41:03 -0500 Subject: [PATCH 2/2] Fixed tests --- tests/test_0692_fsspec_reading.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/test_0692_fsspec_reading.py b/tests/test_0692_fsspec_reading.py index eb6e3991c..564b43c83 100644 --- a/tests/test_0692_fsspec_reading.py +++ b/tests/test_0692_fsspec_reading.py @@ -14,7 +14,6 @@ import uproot.source.fsspec import uproot.source.file import uproot.source.xrootd -import uproot.source.s3 is_windows = sys.platform.startswith("win") @@ -91,7 +90,6 @@ def test_open_fsspec_local(): "handler", [ uproot.source.fsspec.FSSpecSource, - uproot.source.s3.S3Source, None, ], )