• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

kit-data-manager / tomo_mapper / 21944637261

12 Feb 2026 11:24AM UTC coverage: 86.453% (+0.1%) from 86.341%
21944637261

push

github

web-flow
Merge pull request #77 from kit-data-manager/improv_code_cleanup

Various code fixes and cleanups
Cleaner type hints
Cleaner inheritance
More None checks

parse functions (parse_setup, parse_run, parse) do not return raw parse result anymore (was never used anywhere anyway)

Code now passes a static code check such as pyright.

159 of 198 new or added lines in 30 files covered. (80.3%)

3 existing lines in 3 files now uncovered.

2425 of 2805 relevant lines covered (86.45%)

0.86 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

57.14
/src/IO/sem/InputReader.py
1
import logging
1✔
2
import mimetypes
1✔
3
import os
1✔
4
from typing import List, Optional
1✔
5

6
from src.IO.MappingAbortionError import MappingAbortionError
1✔
7
from src.parser.ImageParser import ParserMode
1✔
8
from src.parser.ParserFactory import ParserFactory
1✔
9
from src.util import load_json, get_filetype_with_magica, robust_textfile_read
1✔
10

11

12
class InputReader:
1✔
13

14
    mapping = None
1✔
15
    parser_names = []
1✔
16

17
    def __init__(self, map_path, input_path):
1✔
18
        logging.info("Preparing parsers based on parsing map file and input.")
×
19
        self.mapping = load_json(map_path)
×
20

21
        if not os.path.exists(input_path):
×
22
            logging.error("Input file {} does not exist. Aborting".format(input_path))
×
23
            raise MappingAbortionError("Input file loading failed.")
×
24

25
        self.parser_names = self.get_applicable_parsers(input_path)
×
26

27
        if not self.parser_names:
×
28
            logging.error("No applicable parsers found for input {}".format(input_path))
×
29
            mimetype_set = list(set([v.expected_input_format() for v in ParserFactory.available_img_parsers.values()]))
×
30
            logging.info("Supported mimetypes: {}".format(mimetype_set))
×
31
            raise MappingAbortionError("Input file parsing aborted.")
×
32
        logging.info("Applicable parsers: {}".format(", ".join(self.parser_names)))
×
33

34

35
    @staticmethod
1✔
36
    def get_applicable_parsers(input_path, by_extension = False) -> List[str]:
1✔
37
        """
38
        Filters the available image parsers to those applicable to the input file format.
39
        It tries to determine by extension, but can fallback to using magica.
40
        :param by_extension: set to True if guessing by extension should be used.
41
        :param input_path: file path to input
42
        :return: list of parser names that can handle the provided input format
43
        """
44
        applicable_types = [ip.expected_input_format() for ip in ParserFactory.available_img_parsers.values()]
1✔
45

46
        mt = None
1✔
47
        if by_extension:
1✔
48
            mt, _ = mimetypes.guess_type(input_path)
×
49
            logging.debug("Mimetypes file identification result: {}".format(mt))
×
50
        if not mt or mt == "application/unknown" or mt not in applicable_types: #fallback, especially if file extension is not available
1✔
51
            #Text files are tricky with magica, so try to read as such first
52
            mt = get_filetype_with_magica(input_path)
1✔
53
            logging.debug("Magika file identification result: {}".format(mt))
1✔
54
            if mt not in applicable_types:
1✔
55
                try:
1✔
56
                    robust_textfile_read(input_path)
1✔
57
                    mt = "text/plain"
1✔
58
                except:
×
59
                    logging.error("Could not determine mimetype for input {}".format(input_path))
×
60
                    raise MappingAbortionError
×
61

62
        logging.debug("Determined input type: {}".format(mt))
1✔
63

64
        available_parsers = []
1✔
65
        for k, p in ParserFactory.available_img_parsers.items():
1✔
66
            expected = p.expected_input_format()
1✔
67
            if expected == mt:
1✔
68
                available_parsers.append(k)
1✔
69
        return available_parsers
1✔
70

71
    def retrieve_image_info(self, input_path) -> Optional[dict]:
1✔
72
        """
73
        Applies the applicable list of parsers to the provided input. Stops on the first successful parsing result and returns it.
74
        Usually we do not expect more than one applicable parser to be available. If so, it would be advised to add more checks to keep the list of parsers at len 1.
75
        :param input_path: path to input file
76
        :return:
77
        """
78
        for parser in self.parser_names:
×
79
            logging.debug("Trying to parse image with {}".format(parser))
×
80
            imgp = ParserFactory.create_img_parser(parser, mode=ParserMode.SEM)
×
81

NEW
82
            result = imgp.parse(input_path, self.mapping)
×
83
            if result and result.image_metadata:
×
84
                output_dict = result.image_metadata.to_schema_dict()
×
85
                return output_dict
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc