diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4443c81..8b5d251 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,6 +7,7 @@ Added functionality:
 * Added config option overrides for the command line
     * Can define in command line `--option parameter` or without a parameter `--option` for a user prompt
     * Use the `--help` option for more details on these options
+* The `directory` parser can now handle full (absolute) file paths in the sample list file
 
 Bug Fixes:
 * Fixed hard crash that sometimes occurred when valid url's were given as the base_url
diff --git a/parsers/directory/sample_parser.py b/parsers/directory/sample_parser.py
index 315c0fa..0af6cfc 100644
--- a/parsers/directory/sample_parser.py
+++ b/parsers/directory/sample_parser.py
@@ -79,6 +79,9 @@ def _parse_sample_list(sample_sheet_file):
     data_dir = path.dirname(sample_sheet_file)
     data_dir_file_list = next(walk(data_dir))[2]  # Create a file list of the data directory, only hit the os once
 
+    data_dir_file_list_full_path = []
+    for file_name in data_dir_file_list:
+        data_dir_file_list_full_path.append(path.join(path.abspath(data_dir), file_name))
     has_paired_end_read = False
     has_single_end_read = False
 
@@ -94,13 +97,15 @@ def _parse_sample_list(sample_sheet_file):
             has_single_end_read = True
 
         # Check if file names are in the files we found in the directory
-        if sample_dict['File_Forward'] not in data_dir_file_list:
+        if (sample_dict['File_Forward'] not in data_dir_file_list and
+           sample_dict['File_Forward'] not in data_dir_file_list_full_path):
             raise exceptions.SampleSheetError(
                 ("Your sample sheet is malformed. {} Does not match any file in the directory {}"
                  "".format(sample_dict['File_Forward'], data_dir)),
                 sample_sheet_file
             )
-        if paired_end_read and sample_dict['File_Reverse'] not in data_dir_file_list:
+        if ((paired_end_read and sample_dict['File_Reverse'] not in data_dir_file_list) and
+           (paired_end_read and sample_dict['File_Reverse'] not in data_dir_file_list_full_path)):
             raise exceptions.SampleSheetError(
                 ("Your sample sheet is malformed. {} Does not match any file in the directory {}"
                  "".format(sample_dict['File_Reverse'], data_dir)),
@@ -108,8 +113,9 @@ def _parse_sample_list(sample_sheet_file):
             )
 
         # Add the dir to each file to create the full path
-        sample_dict['File_Forward'] = path.join(data_dir, sample_dict['File_Forward'])
-        if paired_end_read:
+        if sample_dict['File_Forward'] not in data_dir_file_list_full_path:
+            sample_dict['File_Forward'] = path.join(data_dir, sample_dict['File_Forward'])
+        if paired_end_read and sample_dict['File_Reverse'] not in data_dir_file_list_full_path:
             sample_dict['File_Reverse'] = path.join(data_dir, sample_dict['File_Reverse'])
 
     # Verify we don't have both single end and paired end reads

Allow Directory Parser to use full file paths, in addition to file names.
Suggested by @happykhan 

Use case: Reads can sometimes be scattered around, so it would be nice to be able to just give the path directly in the SampleList.csv file.

Related code: `/parsers/directory/sample_parser.py` in `_parse_sample_list` search for `path.join`
diff --git a/tests/parsers/directory/test_sample_parser.py b/tests/parsers/directory/test_sample_parser.py
index 38735b1..671bb67 100644
--- a/tests/parsers/directory/test_sample_parser.py
+++ b/tests/parsers/directory/test_sample_parser.py
@@ -1,6 +1,9 @@
 import unittest
+from collections import OrderedDict
 from os import path
+from unittest.mock import patch
 
+import parsers.directory
 import parsers.directory.sample_parser as sample_parser
 from parsers.exceptions import SampleSheetError
 import model
@@ -196,6 +199,41 @@ class TestParseSampleList(unittest.TestCase):
         self.assertEqual(res[0]["File_Forward"], file_path_1)
         self.assertEqual(res[0]["File_Reverse"], file_path_2)
 
+    @patch("parsers.directory.sample_parser._parse_samples")
+    def test_valid_full_file_path(self, mock_parse_samples):
+        """
+        Given a valid sample sheet with full file paths, parse correctly
+        :return:
+        """
+        sheet_file = path.join(path_to_module, "fake_dir_data",
+                               "SampleList_simple.csv")
+
+        file_path_1 = path.join(path_to_module,
+                                "fake_dir_data", "file_1.fastq.gz")
+        file_path_2 = path.join(path_to_module,
+                                "fake_dir_data", "file_2.fastq.gz")
+
+
+        sample_dict_list = [OrderedDict([
+            ('Sample_Name', 'my-sample-1'),
+            ('Project_ID', '75'),
+            ('File_Forward', path.abspath(file_path_1)),
+            ('File_Reverse', path.abspath(file_path_2))
+        ])]
+
+        mock_parse_samples.return_value = sample_dict_list
+
+        res = parsers.directory.sample_parser._parse_sample_list(sheet_file)
+
+        mock_parse_samples.assert_called_with(sheet_file)
+        # Check we have 1 sample
+        self.assertEqual(len(res), 1)
+        # Check if data is correct
+        self.assertEqual(res[0]["Sample_Name"], "my-sample-1")
+        self.assertEqual(res[0]["Project_ID"], "75")
+        self.assertEqual(res[0]["File_Forward"], path.abspath(file_path_1))
+        self.assertEqual(res[0]["File_Reverse"], path.abspath(file_path_2))
+
     def test_no_forward_read(self):
         """
         No Valid files were found with names given in sample sheet

make
parse_log_pytest
requirements.txt
pytest
apt-get update apt-get install -y python3 python3-pip virtualenv
3.9
requirements.txt
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
appdirs==1.4.3
autopep8==1.4
Cerberus==1.3.7
certifi==2025.1.31
chardet==3.0.4
click==8.1.8
distlib==0.3.9
exceptiongroup==1.2.2
idna==2.8
importlib_metadata==8.6.1
iniconfig==2.1.0
Jinja2==3.1.6
livereload==2.7.1
Markdown==3.7
MarkupSafe==3.0.2
mkdocs==1.0
packaging==24.2
pluggy==1.5.0
pycodestyle==2.13.0
pynsist==2.3
pytest==8.3.5
PyYAML==6.0.2
rauth==0.7.3
requests==2.21.0
requests_download==0.1.2
selenium==3.141.0
tomli==2.2.1
tornado==6.4.2
urllib3==1.24.3
yarg==0.1.10
zipp==3.21.0

name: irida-uploader
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:
      - appdirs==1.4.3
      - argparse==1.4.0
      - autopep8==1.4
      - cerberus==1.3.7
      - certifi==2025.1.31
      - chardet==3.0.4
      - click==8.1.8
      - distlib==0.3.9
      - exceptiongroup==1.2.2
      - idna==2.8
      - importlib-metadata==8.6.1
      - iniconfig==2.1.0
      - jinja2==3.1.6
      - livereload==2.7.1
      - markdown==3.7
      - markupsafe==3.0.2
      - mkdocs==1.0
      - packaging==24.2
      - pluggy==1.5.0
      - pycodestyle==2.13.0
      - pynsist==2.3
      - pytest==8.3.5
      - pyyaml==6.0.2
      - rauth==0.7.3
      - requests==2.21.0
      - requests-download==0.1.2
      - selenium==3.141.0
      - tomli==2.2.1
      - tornado==6.4.2
      - urllib3==1.24.3
      - yarg==0.1.10
      - zipp==3.21.0
prefix: /opt/conda/envs/irida-uploader

tests/parsers/directory/test_sample_parser.py::TestParseSampleList::test_valid_full_file_path
tests/parsers/directory/test_sample_parser.py::TestBuildSequencingRunFromSamples::test_build_valid tests/parsers/directory/test_sample_parser.py::TestBuildSequencingRunFromSamples::test_build_valid_extra_line_on_sample_list tests/parsers/directory/test_sample_parser.py::TestBuildSequencingRunFromSamples::test_parse_samples_valid tests/parsers/directory/test_sample_parser.py::TestGetCsvReader::test_get_csv_reader_no_sheet tests/parsers/directory/test_sample_parser.py::TestGetCsvReader::test_get_csv_reader_valid_sheet tests/parsers/directory/test_sample_parser.py::TestParseSampleList::test_mixed_paired_and_single_reads tests/parsers/directory/test_sample_parser.py::TestParseSampleList::test_no_forward_read tests/parsers/directory/test_sample_parser.py::TestParseSampleList::test_no_reverse_read tests/parsers/directory/test_sample_parser.py::TestParseSampleList::test_valid tests/parsers/directory/test_sample_parser.py::TestParseSamples::test_no_forward_read tests/parsers/directory/test_sample_parser.py::TestParseSamples::test_no_read_files_in_list tests/parsers/directory/test_sample_parser.py::TestParseSamples::test_no_reverse_read tests/parsers/directory/test_sample_parser.py::TestParseSamples::test_no_reverse_read_with_comma tests/parsers/directory/test_sample_parser.py::TestParseSamples::test_valid
parsers/directory/sample_parser.py CHANGELOG.md
parsers/directory/sample_parser.py CHANGELOG.md