Browse Source

CorticalParcellationStats.read: support pathlib.Path, http, s3 etc. via pandas.io.common.get_filepath_or_buffer

Fabian Peter Hammerle 4 years ago
parent
commit
35c2e51fa8
3 changed files with 43 additions and 3 deletions
  1. 4 0
      CHANGELOG.md
  2. 16 3
      freesurfer_stats/__init__.py
  3. 23 0
      tests/test_cortical_parcellation_stats.py

+ 4 - 0
CHANGELOG.md

@@ -5,6 +5,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
 and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
 
 ## [Unreleased]
+### Added
+- `CorticalParcellationStats.read` support `pathlib.Path`, `"http://…"`, `"https://…"`, `"s3://…"` etc.
+  via `pandas.io.common.get_filepath_or_buffer`
+  (https://github.com/fphammerle/freesurfer-stats/issues/6)
 
 ## [1.1.1] - 2020-05-07
 ### Fixed

+ 16 - 3
freesurfer_stats/__init__.py

@@ -47,6 +47,8 @@ along with this program.  If not, see <https://www.gnu.org/licenses/>.
 """
 
 import datetime
+import io
+import pathlib
 import re
 import typing
 
@@ -180,9 +182,20 @@ class CorticalParcellationStats:
             .apply(pandas.to_numeric, errors='ignore')
 
     @classmethod
-    def read(cls, path: str) -> 'CorticalParcellationStats':
+    def read(cls, path: typing.Union[str, pathlib.Path]) -> "CorticalParcellationStats":
+        # support http, s3 & gcs
+        # https://github.com/pandas-dev/pandas/blob/v0.25.3/pandas/io/common.py#L171
+        path_or_buffer, _, _, should_close = pandas.io.common.get_filepath_or_buffer(
+            path
+        )
         stats = cls()
-        with open(path, 'r') as stream:
+        if hasattr(path_or_buffer, "readline"):
             # pylint: disable=protected-access
-            stats._read(stream)
+            stats._read(io.TextIOWrapper(path_or_buffer))
+        else:
+            with open(path_or_buffer, "r") as stream:
+                # pylint: disable=protected-access
+                stats._read(stream)
+        if should_close:
+            path_or_buffer.close()
         return stats

+ 23 - 0
tests/test_cortical_parcellation_stats.py

@@ -17,6 +17,7 @@ along with this program.  If not, see <https://www.gnu.org/licenses/>.
 """
 import datetime
 import os
+import pathlib
 
 import numpy
 import pandas.util.testing
@@ -288,3 +289,25 @@ def test__parse_whole_brain_measurements_line_parse_error(line):
     # pylint: disable=protected-access
     with pytest.raises(ValueError):
         CorticalParcellationStats._parse_whole_brain_measurements_line(line)
+
+
+@pytest.mark.parametrize(
+    "path_str",
+    [os.path.join(SUBJECTS_DIR, "fabian", "stats", "lh.aparc.DKTatlas.stats.short"),],
+)
+def test_read_pathlib(path_str: str):
+    stats_str = CorticalParcellationStats.read(path_str)
+    stats_pathlib = CorticalParcellationStats.read(pathlib.Path(path_str))
+    assert stats_str.headers == stats_pathlib.headers
+
+
+@pytest.mark.parametrize(
+    "url",
+    [
+        "https://raw.githubusercontent.com/fphammerle/freesurfer-stats"
+        "/master/tests/subjects/fabian/stats/rh.aparc.stats"
+    ],
+)
+def test_read_https(url: str):
+    stats = CorticalParcellationStats.read(url)
+    assert stats.headers["generating_program"] == "mris_anatomical_stats"