跳转至

molop.io

本页面提供了 molop.io 模块的 API 参考。

单文件解析可使用轻量入口 AutoFileParser:它自动检测格式并直接返回一个 file 级对象, 不会构造 batch parser,也不会调度 worker 进程。对于调用方已经持有的文本、bytes 或文本/二进制流, 可使用 AutoMemoryParser、AutoTextParser 和 AutoBytesParser;传给 AutoMemoryParser 的字符串始终按源文本处理, 不会当作路径。批量解析仍使用 AutoParser,它接受单个路径、 glob 或路径可迭代对象并返回 FileBatchModelDisk。需要显式控制批量解析或路径模式拆分时,再使用 FileBatchParserDisk 和 split_path_pattern 等底层辅助 API。

Author: TMJ Date: 2025-01-15 23:01:22 LastEditors: TMJ LastEditTime: 2026-08-22 14:06:41 Description: 请填写简介

AutoFileParser(file_path, *, total_charge=None, total_multiplicity=None, only_extract_structure=False, only_last_frame=False, capture_source_evidence=False, source_encoding='utf-8', release_file_content=True, parser_detection='auto', parse_options=None)

Parse one file with automatic format detection.

Unlike :func:AutoParser, this entrypoint accepts exactly one file path and returns the parsed file model directly. It performs no glob expansion, batch preparation, or process scheduling, so callers can place the parse inside their own worker or process model.

parser_detection="auto" first uses the path extension and reader probes to narrow the candidates, then lets the parser’s format checks validate the complete source. Pass a format id to select a reader explicitly while retaining the same file-level return type.

Raises:

Type Description
TypeError

If file_path is not a text path-like object.

ValueError

If file_path is not an existing regular file.

UnsupportedFormatError

If no reader is registered for the input.

FormatMismatchError

If all candidate readers reject the input format.

ParseError

If a selected reader fails during parsing.

Source code in src/molop/io/__init__.py
Python
def AutoFileParser(
    file_path: PathSpec,
    *,
    total_charge: int | None = None,
    total_multiplicity: int | None = None,
    only_extract_structure: bool = False,
    only_last_frame: bool = False,
    capture_source_evidence: bool = False,
    source_encoding: str = "utf-8",
    release_file_content: bool = True,
    parser_detection: str = "auto",
    parse_options: ParseOptions | None = None,
) -> "FileDiskObj":
    """Parse one file with automatic format detection.

    Unlike :func:`AutoParser`, this entrypoint accepts exactly one file path and
    returns the parsed file model directly. It performs no glob expansion,
    batch preparation, or process scheduling, so callers can place the parse
    inside their own worker or process model.

    ``parser_detection="auto"`` first uses the path extension and reader
    probes to narrow the candidates, then lets the parser's format checks
    validate the complete source. Pass a format id to select a reader
    explicitly while retaining the same file-level return type.

    Raises:
        TypeError: If ``file_path`` is not a text path-like object.
        ValueError: If ``file_path`` is not an existing regular file.
        UnsupportedFormatError: If no reader is registered for the input.
        FormatMismatchError: If all candidate readers reject the input format.
        ParseError: If a selected reader fails during parsing.
    """
    try:
        path_value = os.fspath(file_path)
    except TypeError as exc:
        raise TypeError("file_path must be a path-like object") from exc
    if not isinstance(path_value, str):
        raise TypeError("file_path must resolve to a text path, not bytes")

    path = Path(os.path.abspath(path_value))
    if not path.is_file():
        raise ValueError(f"File {path} does not exist or is not a regular file.")

    hint_format = None if parser_detection == "auto" else parser_detection
    possible_readers = cast(
        tuple[_FileReaderCodec, ...],
        codec_registry.select_reader(path, hint_format=hint_format),
    )
    if parser_detection == "auto":
        possible_readers = _filter_readers_by_probe(str(path), possible_readers)

    outcome = _single_file_parser(
        file_path=str(path),
        possible_readers=possible_readers,
        total_charge=total_charge,
        total_multiplicity=total_multiplicity,
        only_extract_structure=only_extract_structure,
        only_last_frame=only_last_frame,
        capture_source_evidence=capture_source_evidence,
        source_encoding=source_encoding,
        release_file_content=release_file_content,
        parse_options=parse_options,
        return_outcome=True,
    )
    if outcome.succeeded and outcome.value is not None:
        return outcome.value

    failure = outcome.failure
    message = failure.message if failure is not None else f"Failed to parse file {path}."
    if outcome.status == "unsupported":
        raise UnsupportedFormatError(message)
    if outcome.status == "mismatch":
        raise FormatMismatchError(message)
    raise ParseError(message)

AutoMemoryParser(source, *, total_charge=None, total_multiplicity=None, only_extract_structure=False, only_last_frame=False, capture_source_evidence=False, source_encoding='utf-8', release_file_content=True, parser_detection='auto', parse_options=None)

Python
AutoMemoryParser(
    source: TextSource,
    *,
    total_charge: int | None = None,
    total_multiplicity: int | None = None,
    only_extract_structure: bool = False,
    only_last_frame: bool = False,
    capture_source_evidence: bool = False,
    source_encoding: str = "utf-8",
    release_file_content: bool = True,
    parser_detection: str = "auto",
    parse_options: ParseOptions | None = None,
) -> BaseChemFile[Any]
Python
AutoMemoryParser(
    source: BytesSource,
    *,
    total_charge: int | None = None,
    total_multiplicity: int | None = None,
    only_extract_structure: bool = False,
    only_last_frame: bool = False,
    capture_source_evidence: bool = False,
    source_encoding: str = "utf-8",
    release_file_content: bool = True,
    parser_detection: str = "auto",
    parse_options: ParseOptions | None = None,
) -> BaseChemFile[Any]

Parse already-loaded text or bytes with automatic format detection.

A string is treated as source text, never as a path. Use :func:AutoFileParser for path input. Binary and text streams are consumed from their current position.

Source code in src/molop/io/memory_parser.py
Python
def AutoMemoryParser(
    source: MemorySource,
    *,
    total_charge: int | None = None,
    total_multiplicity: int | None = None,
    only_extract_structure: bool = False,
    only_last_frame: bool = False,
    capture_source_evidence: bool = False,
    source_encoding: str = "utf-8",
    release_file_content: bool = True,
    parser_detection: str = "auto",
    parse_options: ParseOptions | None = None,
) -> BaseChemFile[Any]:
    """Parse already-loaded text or bytes with automatic format detection.

    A string is treated as source text, never as a path. Use :func:`AutoFileParser`
    for path input. Binary and text streams are consumed from their current position.
    """

    options = _resolved_options(
        total_charge=total_charge,
        total_multiplicity=total_multiplicity,
        only_extract_structure=only_extract_structure,
        only_last_frame=only_last_frame,
        capture_source_evidence=capture_source_evidence,
        source_encoding=source_encoding,
        release_file_content=release_file_content,
        parse_options=parse_options,
    )
    if isinstance(source, str):
        return _parse_loaded_source(
            source,
            source_kind="text",
            parser_detection=parser_detection,
            options=options,
        )
    if isinstance(source, (bytes, bytearray, memoryview)):
        return _parse_loaded_source(
            bytes(source),
            source_kind="bytes",
            parser_detection=parser_detection,
            options=options,
        )
    read = getattr(source, "read", None)
    if callable(read):
        value = read()
        if isinstance(value, str):
            return _parse_loaded_source(
                value,
                source_kind="text",
                parser_detection=parser_detection,
                options=options,
            )
        if isinstance(value, (bytes, bytearray, memoryview)):
            return _parse_loaded_source(
                bytes(value),
                source_kind="bytes",
                parser_detection=parser_detection,
                options=options,
            )
        raise TypeError("source stream must return str or bytes-like data")
    return _parse_loaded_source(
        _coerce_bytes(cast(BytesSource, source)),
        source_kind="bytes",
        parser_detection=parser_detection,
        options=options,
    )

AutoTextParser(text, *, total_charge=None, total_multiplicity=None, only_extract_structure=False, only_last_frame=False, capture_source_evidence=False, source_encoding='utf-8', release_file_content=True, parser_detection='auto', parse_options=None)

Parse text already held by the caller without creating a temporary file.

Source code in src/molop/io/memory_parser.py
Python
def AutoTextParser(
    text: TextSource,
    *,
    total_charge: int | None = None,
    total_multiplicity: int | None = None,
    only_extract_structure: bool = False,
    only_last_frame: bool = False,
    capture_source_evidence: bool = False,
    source_encoding: str = "utf-8",
    release_file_content: bool = True,
    parser_detection: str = "auto",
    parse_options: ParseOptions | None = None,
) -> BaseChemFile[Any]:
    """Parse text already held by the caller without creating a temporary file."""

    return AutoMemoryParser(
        _coerce_text(text),
        total_charge=total_charge,
        total_multiplicity=total_multiplicity,
        only_extract_structure=only_extract_structure,
        only_last_frame=only_last_frame,
        capture_source_evidence=capture_source_evidence,
        source_encoding=source_encoding,
        release_file_content=release_file_content,
        parser_detection=parser_detection,
        parse_options=parse_options,
    )

AutoBytesParser(raw_bytes, *, total_charge=None, total_multiplicity=None, only_extract_structure=False, only_last_frame=False, capture_source_evidence=False, source_encoding='utf-8', release_file_content=True, parser_detection='auto', parse_options=None)

Parse bytes already held by the caller without a filesystem round trip.

Source code in src/molop/io/memory_parser.py
Python
def AutoBytesParser(
    raw_bytes: BytesSource,
    *,
    total_charge: int | None = None,
    total_multiplicity: int | None = None,
    only_extract_structure: bool = False,
    only_last_frame: bool = False,
    capture_source_evidence: bool = False,
    source_encoding: str = "utf-8",
    release_file_content: bool = True,
    parser_detection: str = "auto",
    parse_options: ParseOptions | None = None,
) -> BaseChemFile[Any]:
    """Parse bytes already held by the caller without a filesystem round trip."""

    return AutoMemoryParser(
        _coerce_bytes(raw_bytes),
        total_charge=total_charge,
        total_multiplicity=total_multiplicity,
        only_extract_structure=only_extract_structure,
        only_last_frame=only_last_frame,
        capture_source_evidence=capture_source_evidence,
        source_encoding=source_encoding,
        release_file_content=release_file_content,
        parser_detection=parser_detection,
        parse_options=parse_options,
    )

split_path_pattern(path_str)

Source code in src/molop/io/__init__.py
Python
def split_path_pattern(path_str: str) -> tuple[Path, str]:
    p = Path(path_str)
    parts = p.parts

    split_index = len(parts)
    for i, part in enumerate(parts):
        if glob.has_magic(part):
            split_index = i
            break
    base_path = Path(*parts[:split_index])
    pattern = str(Path(*parts[split_index:])) if split_index < len(parts) else ""

    return base_path, pattern