The ``file_handlers.py`` module
===============================
.. py:module:: ansys.fluent.mcp.common.file_handlers
Summary
-------
.. py:currentmodule:: file_handlers
.. tab-set::
.. tab-item:: Classes
.. list-table::
:header-rows: 0
:widths: auto
* - :py:obj:`~ansys.fluent.mcp.common.file_handlers.FileProbe`
- Result of probing a file for product-relevant metadata.
* - :py:obj:`~ansys.fluent.mcp.common.file_handlers.FileHandler`
- Describes one file type the agent can route to a backend.
.. tab-item:: Functions
.. list-table::
:header-rows: 0
:widths: auto
* - :py:obj:`~normalize_path_for_fluent`
- Return ``path`` as a forward-slash POSIX-style string.
* - :py:obj:`~register_handler`
- Register a new handler. First match (by longest suffix) wins.
* - :py:obj:`~list_handlers`
- Return a copy of the current registry (for introspection/tests).
* - :py:obj:`~find_handler`
- Return the first registered handler whose suffix matches ``path``.
* - :py:obj:`~find_all_handlers`
- Return every registered handler whose suffix matches ``path``.
* - :py:obj:`~supported_suffixes`
- Flat, de-duplicated list of every registered suffix.
.. toctree::
:titlesonly:
:maxdepth: 1
:hidden:
FileProbe
FileHandler
Description
-----------
Modular registry mapping file suffixes to product/component handlers.
Used by the ``read_file`` agent tool to:
1. Recognize a user-supplied filesystem path by suffix.
2. Probe the file (cheap, read-only) for product-relevant metadata, such
as dimension and precision for a Fluent ``.cas.h5`` archive.
3. Decide which backend (PyFluent solver, Fluids One solve, …) and
which launch options (precision, dimension, lightweight) to use.
Adding a new file type is a single registry call. See
:func:`register_handler`. The registry is intentionally tiny. Each
handler owns its own suffix list, candidate-product list, probe
function, and launch-argument builder.
Design constraints:
* No I/O at import time. All probing is lazy and read-only.
* Optional dependencies (``h5py``) are imported inside probe functions
so the agent works even when the extra is not installed.
* Probes never write to the file, never lock it, and never modify the
user's session.
..
!! processed by numpydoc !!
Module detail
-------------
.. py:function:: normalize_path_for_fluent(path: str | pathlib.Path) -> str
Return ``path`` as a forward-slash POSIX-style string.
Cross-platform safe: works whether the input is a ``pathlib.Path``
object, a Windows-style raw string (``"C:\\\\foo\\bar"``), a
Windows-style forward-slash string (``"C:/foo/bar"``), or a POSIX
path (``"/foo/bar"``). Output is safe to embed inside a Python
source code snippet bound for Fluent — no Python string-escape
pitfalls — and is accepted by Fluent's settings API on both
Windows and Linux solver builds.
Notable shapes preserved by the conversion:
* Drive letters: ``C:\\foo`` → ``C:/foo``.
* UNC paths: ``\\\\server\\share\\file`` → ``//server/share/file``.
* Mixed separators: ``C:/foo\\bar`` → ``C:/foo/bar``.
* No trailing slashes (matches Fluent's expected form).
Why not ``str(path).replace('\\', '/')``? That works for the common
case but leaves redundant separators and doesn't normalize mixed
``./``/``../`` segments. Routing through ``PureWindowsPath``
handles those cases consistently. ``..`` resolution is left to the
caller (we never want to silently rewrite ``..`` paths — the
``_validate_read_file_path`` guard rejects them outright).
:Parameters:
**path** : :class:`python:str` | :obj:`Path`
Fluent object path or file-system path to inspect.
:Returns:
:class:`python:str`
String result produced by the function.
..
!! processed by numpydoc !!
.. py:function:: register_handler(handler: FileHandler) -> None
Register a new handler. First match (by longest suffix) wins.
Registration is idempotent by ``handler.name``. Re-registering a
handler with the same name replaces the prior entry instead of
appending a duplicate. This lets an optional consuming layer (one
that adds non-solve geometry / Prime meshing CAD handlers) import its
registration module more than once without bloating the registry.
Boundary note: this OSS package is **solve-only**. It registers
ONLY Fluent solver file types (case/mesh/data/project/HDF5).
Geometry (CAD import) and Prime meshing (readcad) handlers are NOT
registered here. They belong to the geometry/mesh products and are
registered into this same registry by an optional higher-level layer
via :func:`register_handler`. A standalone ``ansys-fluent-mcp``
install therefore exposes a solve-only registry, which is correct
for the solve leaf's ``compare_files`` tool.
:Parameters:
**handler** : :obj:`FileHandler`
Callable inspected or registered by the helper.
:Returns:
:data:`python:None`
The function completes through its side effects.
..
!! processed by numpydoc !!
.. py:function:: list_handlers() -> list[FileHandler]
Return a copy of the current registry (for introspection/tests).
:Returns:
:class:`python:list`\[:obj:`FileHandler`]
Collection containing the operation results.
..
!! processed by numpydoc !!
.. py:function:: find_handler(path: str | pathlib.Path) -> FileHandler | None
Return the first registered handler whose suffix matches ``path``.
:Parameters:
**path** : :class:`python:str` | :obj:`Path`
Fluent object path or file-system path to inspect.
:Returns:
:obj:`FileHandler` | :data:`python:None`
Result produced by the function.
..
!! processed by numpydoc !!
.. py:function:: find_all_handlers(path: str | pathlib.Path) -> list[FileHandler]
Return every registered handler whose suffix matches ``path``.
Used by ``read_file`` to disambiguate suffixes that legitimately
belong to more than one component. For example, ``.fmd`` is valid as
both a CAD geometry import (Fluids One Geometry component) and a
Prime meshing CAD read (Mesh component). The caller resolves the
ambiguity by inspecting ``handler.component`` against a user-
supplied ``component`` argument or by prompting the user.
:Parameters:
**path** : :class:`python:str` | :obj:`Path`
Fluent object path or file-system path to inspect.
:Returns:
:class:`python:list`\[:obj:`FileHandler`]
Collection containing the operation results.
..
!! processed by numpydoc !!
.. py:function:: supported_suffixes() -> list[str]
Flat, de-duplicated list of every registered suffix.
:Returns:
:class:`python:list`\[:class:`python:str`]
Collection containing the operation results.
..
!! processed by numpydoc !!