diff --git a/rac_aspace/serializers.py b/rac_aspace/serializers.py
index 9c327c4..534804f 100644
--- a/rac_aspace/serializers.py
+++ b/rac_aspace/serializers.py
@@ -1,7 +1,7 @@
 import csv
 
 
-class Serializer:
+class BaseSerializer:
 
     def __init__(self, filename, filemode="w"):
         """Sets initial attributes for serializers.
@@ -14,8 +14,6 @@ class Serializer:
             filename (str): a filename at which the data should be serialized.
             filemode (str): Optional argument used when opening files.
         """
-        if filemode.startswith("r"):
-            raise TypeError("Filemode must allow write operations.")
         self.filemode = filemode
         extension = filename.split(".")[-1]
         if extension != self.extension:
@@ -31,6 +29,8 @@ class Serializer:
         Args:
             data (dict or list): a sequence of dicts.
         """
+        if self.filemode.startswith("r"):
+            raise TypeError("Filemode must allow write operations.")
         fieldnames = list(
             data.keys() if isinstance(
                 data, dict) else data[0].keys())
@@ -40,15 +40,22 @@ class Serializer:
             writer.writeheader()
             writer.writerows(data)
 
+    def read_data(self):
+        if not self.filemode.startswith("r"):
+            raise TypeError("Read-only filemode required.")
+        with open(self.filename, self.filemode) as f:
+            reader = csv.DictReader(f)
+            return [row for row in reader]
+
 
-class CSVWriter(Serializer):
+class CSVSerializer(BaseSerializer):
     """Writes data to a CSV file."""
 
     delimiter = ","
     extension = "csv"
 
 
-class TSVWriter(Serializer):
+class TSVSerializer(BaseSerializer):
     """Writes data to a TSV file."""
 
     delimiter = "\t"

Add function to open data files and return an iterable
**Is your feature request related to a problem? Please describe.**
To address #30 @daremiyo and I think it would be good to have a function that can turn a file into something that a script can use natively.

**Describe the solution you'd like**
Create a function that takes a filepath for an input file (in CSV or Excel) and returns an iterable that can be used in a script.
diff --git a/tests/test_serializers.py b/tests/test_serializers.py
index 4563388..a47364c 100644
--- a/tests/test_serializers.py
+++ b/tests/test_serializers.py
@@ -39,12 +39,12 @@ class TestSerializers(unittest.TestCase):
                 remove(expected_filepath)
 
     def test_csv_serializer(self):
-        """Tests CSVWriter."""
-        self.check_serializer(serializers.CSVWriter)
+        """Tests CSVSerializer."""
+        self.check_serializer(serializers.CSVSerializer)
 
     def test_tsv_serializer(self):
-        """Tests TSVWriter."""
-        self.check_serializer(serializers.TSVWriter)
+        """Tests TSVSerializer."""
+        self.check_serializer(serializers.TSVSerializer)
 
     def test_filemodes(self):
         """Tests different filemodes.
@@ -53,16 +53,38 @@ class TestSerializers(unittest.TestCase):
         a meaningful exception.
         """
         for filemode in ["a", "a+", "w", "w+"]:
-            for serializer in [serializers.CSVWriter, serializers.TSVWriter]:
+            for serializer in [serializers.CSVSerializer,
+                               serializers.TSVSerializer]:
                 expected_filepath = "test.{}".format(serializer.extension)
                 s = serializer("test", filemode=filemode)
                 s.write_data(self.short_data)
                 self.assertTrue(isfile(expected_filepath))
-                remove(expected_filepath)
+                with self.assertRaises(TypeError):
+                    s.read_data()
         for filemode in ["r", "r+"]:
-            for serializer in [serializers.CSVWriter, serializers.TSVWriter]:
+            for serializer in [serializers.CSVSerializer,
+                               serializers.TSVSerializer]:
+                s = serializer("test", filemode=filemode)
+                read = s.read_data()
+                self.assertIsInstance(read, list)
                 with self.assertRaises(TypeError):
-                    serializer("test", filemode=filemode)
+                    s.write_data(self.short_data)
+        for filename in ["test.tsv", "test.csv"]:
+            remove(filename)
+
+    def test_read_data(self):
+        """Tests correct returned from a CSV or TSV file."""
+        filename = "read_file.csv"
+        fieldnames = list(self.long_data[0].keys())
+        with open(filename, "w") as f:
+            writer = csv.DictWriter(
+                f, fieldnames=fieldnames, delimiter=",")
+            writer.writeheader()
+            writer.writerows(self.long_data)
+        read = serializers.CSVSerializer(filename, filemode="r").read_data()
+        self.assertIsInstance(read, list)
+        self.assertEqual(read, self.long_data)
+        remove(filename)
 
     def tearDown(self):
         for filename in ["spreadsheet.csv", "spreadsheet.tsv"]:

pip install -e .[dev]
parse_log_pytest
requirements.txt
pytest pre-commit sphinx tox vcrpy
apt-get update apt-get install -y gcc
3.9
requirements/base.txt
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
alabaster==0.7.16
ArchivesSnake==0.8.1
attrs==25.3.0
babel==2.17.0
boltons==20.0.0
cachetools==5.5.2
certifi==2025.1.31
cfgv==3.4.0
chardet==5.2.0
charset-normalizer==3.4.1
colorama==0.4.6
distlib==0.3.9
docutils==0.21.2
exceptiongroup==1.2.2
filelock==3.18.0
fuzzywuzzy==0.17.0
identify==2.6.9
idna==3.10
imagesize==1.4.1
importlib_metadata==8.6.1
iniconfig==2.1.0
Jinja2==3.1.6
MarkupSafe==3.0.2
more-itertools==10.6.0
multidict==6.2.0
nodeenv==1.9.1
packaging==24.2
platformdirs==4.3.7
pluggy==1.5.0
pre_commit==4.2.0
propcache==0.3.1
Pygments==2.19.1
pyproject-api==1.9.0
pytest==8.3.5
PyYAML==5.2
-e git+https://github.com/RockefellerArchiveCenter/rac_aspace.git@7d8c39cf471c548476e14d5c8bf14e36347f9d73#egg=rac_aspace
requests==2.32.3
snowballstemmer==2.2.0
Sphinx==7.4.7
sphinxcontrib-applehelp==2.0.0
sphinxcontrib-devhelp==2.0.0
sphinxcontrib-htmlhelp==2.1.0
sphinxcontrib-jsmath==1.0.1
sphinxcontrib-qthelp==2.0.0
sphinxcontrib-serializinghtml==2.0.0
structlog==25.2.0
tomli==2.2.1
tox==4.25.0
typing_extensions==4.13.0
urllib3==1.26.20
vcrpy==7.0.0
virtualenv==20.29.3
wrapt==1.17.2
yarl==1.18.3
zipp==3.21.0

name: rac_aspace
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.4.4=h6a678d5_1
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=3.0.16=h5eee18b_0
  - pip=25.0=py39h06a4308_0
  - python=3.9.21=he870216_1
  - readline=8.2=h5eee18b_0
  - setuptools=75.8.0=py39h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - tzdata=2025a=h04d1e81_0
  - wheel=0.45.1=py39h06a4308_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - alabaster==0.7.16
      - archivessnake==0.8.1
      - attrs==25.3.0
      - babel==2.17.0
      - boltons==20.0.0
      - cachetools==5.5.2
      - certifi==2025.1.31
      - cfgv==3.4.0
      - chardet==5.2.0
      - charset-normalizer==3.4.1
      - colorama==0.4.6
      - distlib==0.3.9
      - docutils==0.21.2
      - exceptiongroup==1.2.2
      - filelock==3.18.0
      - fuzzywuzzy==0.17.0
      - identify==2.6.9
      - idna==3.10
      - imagesize==1.4.1
      - importlib-metadata==8.6.1
      - iniconfig==2.1.0
      - jinja2==3.1.6
      - markupsafe==3.0.2
      - more-itertools==10.6.0
      - multidict==6.2.0
      - nodeenv==1.9.1
      - packaging==24.2
      - platformdirs==4.3.7
      - pluggy==1.5.0
      - pre-commit==4.2.0
      - propcache==0.3.1
      - pygments==2.19.1
      - pyproject-api==1.9.0
      - pytest==8.3.5
      - pyyaml==5.2
      - requests==2.32.3
      - snowballstemmer==2.2.0
      - sphinx==7.4.7
      - sphinxcontrib-applehelp==2.0.0
      - sphinxcontrib-devhelp==2.0.0
      - sphinxcontrib-htmlhelp==2.1.0
      - sphinxcontrib-jsmath==1.0.1
      - sphinxcontrib-qthelp==2.0.0
      - sphinxcontrib-serializinghtml==2.0.0
      - structlog==25.2.0
      - tomli==2.2.1
      - tox==4.25.0
      - typing-extensions==4.13.0
      - urllib3==1.26.20
      - vcrpy==7.0.0
      - virtualenv==20.29.3
      - wrapt==1.17.2
      - yarl==1.18.3
      - zipp==3.21.0
prefix: /opt/conda/envs/rac_aspace

tests/test_serializers.py::TestSerializers::test_csv_serializer tests/test_serializers.py::TestSerializers::test_filemodes tests/test_serializers.py::TestSerializers::test_read_data tests/test_serializers.py::TestSerializers::test_tsv_serializer
rac_aspace/serializers.py
rac_aspace/serializers.py