fix: disable advanced mode in read file components on cloud (#11124)

* disable advanced mode

* [autofix.ci] apply automated fixes

* [autofix.ci] apply automated fixes (attempt 2/3)

* fix ruff errors

* [autofix.ci] apply automated fixes

* [autofix.ci] apply automated fixes (attempt 2/3)

* add a helper method to handle cloud env

* [autofix.ci] apply automated fixes

* [autofix.ci] apply automated fixes (attempt 2/3)

* [autofix.ci] apply automated fixes (attempt 3/3)

* fix ruff errors

* [autofix.ci] apply automated fixes

* disable docling components on cloud

* fix ruff errors

* [autofix.ci] apply automated fixes

* fix ruff errors

* template updates

* [autofix.ci] apply automated fixes

* [autofix.ci] apply automated fixes

* [autofix.ci] apply automated fixes (attempt 2/3)

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
This commit is contained in:
Himavarsha
2025-12-23 12:50:32 -05:00
committed by GitHub
parent c8cd4d9dcc
commit d733b7d2ad
8 changed files with 2141 additions and 3016 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -644,3 +644,77 @@ class TestFileComponentToolMode:
)
new_temp_files = temp_files_after - temp_files_before
assert len(new_temp_files) == 0, f"Temp files not cleaned up: {new_temp_files}"
class TestFileComponentCloudEnvironment:
"""Test FileComponent behavior in cloud environments."""
def test_advanced_mode_disabled_in_cloud(self, monkeypatch):
"""Test that advanced_mode and all Docling fields are disabled when ASTRA_CLOUD_DISABLE_COMPONENT is set."""
# Set the environment variable to simulate cloud environment
monkeypatch.setenv("ASTRA_CLOUD_DISABLE_COMPONENT", "true")
component = FileComponent()
build_config = {
"advanced_mode": {"show": True, "value": False},
"pipeline": {"show": False},
"ocr_engine": {"show": False},
"doc_key": {"show": False},
"md_image_placeholder": {"show": False},
"md_page_break_placeholder": {"show": False},
"path": {"file_path": ["document.pdf"]},
}
result = component.update_build_config(build_config, ["document.pdf"], "path")
# In cloud, advanced_mode should be hidden regardless of file type
assert result["advanced_mode"]["show"] is False, "advanced_mode should be hidden in cloud"
assert result["advanced_mode"]["value"] is False, "advanced_mode value should be False in cloud"
# All related fields should be hidden
assert result["pipeline"]["show"] is False
assert result["ocr_engine"]["show"] is False
assert result["ocr_engine"]["value"] == "None"
assert result["doc_key"]["show"] is False
assert result["md_image_placeholder"]["show"] is False
assert result["md_page_break_placeholder"]["show"] is False
def test_advanced_mode_toggle_disabled_in_cloud(self, monkeypatch):
"""Test that toggling advanced_mode in cloud doesn't show Docling fields."""
monkeypatch.setenv("ASTRA_CLOUD_DISABLE_COMPONENT", "true")
component = FileComponent()
build_config = {
"advanced_mode": {"show": True, "value": True},
"pipeline": {"show": False},
"ocr_engine": {"show": False},
"doc_key": {"show": False},
"md_image_placeholder": {"show": False},
"md_page_break_placeholder": {"show": False},
}
result = component.update_build_config(build_config, field_value=True, field_name="advanced_mode")
# Even if advanced_mode is toggled to True, it should be disabled in cloud
assert result["advanced_mode"]["show"] is False
assert result["advanced_mode"]["value"] is False
# All Docling fields should remain hidden
assert result["pipeline"]["show"] is False
assert result["ocr_engine"]["show"] is False
assert result["ocr_engine"]["value"] == "None"
def test_pipeline_change_disabled_in_cloud(self, monkeypatch):
"""Test that changing pipeline in cloud doesn't show OCR engine."""
monkeypatch.setenv("ASTRA_CLOUD_DISABLE_COMPONENT", "true")
component = FileComponent()
build_config = {
"advanced_mode": {"show": False, "value": False},
"pipeline": {"show": False},
"ocr_engine": {"show": False, "value": "easyocr"},
}
result = component.update_build_config(build_config, "standard", "pipeline")
# Even if pipeline is set to "standard", OCR engine should be disabled in cloud
assert result["ocr_engine"]["show"] is False
assert result["ocr_engine"]["value"] == "None"

File diff suppressed because one or more lines are too long

View File

@ -3,35 +3,69 @@ from __future__ import annotations
from typing import TYPE_CHECKING, Any
from lfx.components._importing import import_mod
from lfx.utils.validate_cloud import is_astra_cloud_environment
if TYPE_CHECKING:
from .chunk_docling_document import ChunkDoclingDocumentComponent
from .docling_inline import DoclingInlineComponent
from .docling_remote import DoclingRemoteComponent
from .export_docling_document import ExportDoclingDocumentComponent
from .chunk_docling_document import ChunkDoclingDocumentComponent # noqa: F401
from .docling_inline import DoclingInlineComponent # noqa: F401
from .docling_remote import DoclingRemoteComponent # noqa: F401
from .export_docling_document import ExportDoclingDocumentComponent # noqa: F401
_dynamic_imports = {
"ChunkDoclingDocumentComponent": "chunk_docling_document",
"DoclingInlineComponent": "docling_inline",
"DoclingRemoteComponent": "docling_remote",
"ExportDoclingDocumentComponent": "export_docling_document",
}
__all__ = [
_all_components = [
"ChunkDoclingDocumentComponent",
"DoclingInlineComponent",
"DoclingRemoteComponent",
"ExportDoclingDocumentComponent",
]
_all_dynamic_imports = {
"ChunkDoclingDocumentComponent": "chunk_docling_document",
"DoclingInlineComponent": "docling_inline",
"DoclingRemoteComponent": "docling_remote",
"ExportDoclingDocumentComponent": "export_docling_document",
}
# Components that require local Docling/EasyOCR dependencies (disabled in cloud)
_cloud_disabled_components = {
"ChunkDoclingDocumentComponent",
"DoclingInlineComponent",
"ExportDoclingDocumentComponent",
}
def _get_available_components() -> list[str]:
"""Get list of available components, filtering out cloud-disabled ones."""
if is_astra_cloud_environment():
# Only show DoclingRemoteComponent (Docling Serve) in cloud
return [comp for comp in _all_components if comp not in _cloud_disabled_components]
return _all_components
def _get_dynamic_imports() -> dict[str, str]:
"""Get dynamic imports dict, filtering out cloud-disabled ones."""
if is_astra_cloud_environment():
# Only allow DoclingRemoteComponent (Docling Serve) in cloud
return {k: v for k, v in _all_dynamic_imports.items() if k not in _cloud_disabled_components}
return _all_dynamic_imports
# Dynamically set __all__ and _dynamic_imports based on cloud environment
__all__: list[str] = _get_available_components() # noqa: PLE0605
_dynamic_imports: dict[str, str] = _get_dynamic_imports()
def __getattr__(attr_name: str) -> Any:
"""Lazily import docling components on attribute access."""
if attr_name not in _dynamic_imports:
# Check if component is available (not disabled in cloud)
if is_astra_cloud_environment() and attr_name in _cloud_disabled_components:
msg = f"module '{__name__}' has no attribute '{attr_name}'"
raise AttributeError(msg)
if attr_name not in _all_dynamic_imports:
msg = f"module '{__name__}' has no attribute '{attr_name}'"
raise AttributeError(msg)
try:
result = import_mod(attr_name, _dynamic_imports[attr_name], __spec__.parent)
result = import_mod(attr_name, _all_dynamic_imports[attr_name], __spec__.parent)
except (ModuleNotFoundError, ImportError, AttributeError) as e:
msg = f"Could not import '{attr_name}' from '{__name__}': {e}"
raise AttributeError(msg) from e
@ -40,4 +74,4 @@ def __getattr__(attr_name: str) -> Any:
def __dir__() -> list[str]:
return list(__all__)
return _get_available_components()

View File

@ -189,7 +189,8 @@ class FileComponent(BaseFileComponent):
"Enable advanced document processing and export with Docling for PDFs, images, and office documents. "
"Note that advanced document processing can consume significant resources."
),
show=True,
# Disabled in cloud
show=not is_astra_cloud_environment(),
),
DropdownInput(
name="pipeline",
@ -345,6 +346,20 @@ class FileComponent(BaseFileComponent):
"""Return the list of currently selected file paths from the template."""
return template.get("path", {}).get("file_path", [])
def _disable_docling_fields_in_cloud(self, build_config: dict[str, Any]) -> None:
"""Disable all Docling-related fields in cloud environments."""
if "advanced_mode" in build_config:
build_config["advanced_mode"]["show"] = False
build_config["advanced_mode"]["value"] = False
# Hide all Docling-related fields
docling_fields = ("pipeline", "ocr_engine", "doc_key", "md_image_placeholder", "md_page_break_placeholder")
for field in docling_fields:
if field in build_config:
build_config[field]["show"] = False
# Also disable OCR engine specifically
if "ocr_engine" in build_config:
build_config["ocr_engine"]["value"] = "None"
def update_build_config(
self,
build_config: dict[str, Any],
@ -422,25 +437,50 @@ class FileComponent(BaseFileComponent):
if field_name == "path":
paths = self._path_value(build_config)
# If all files can be processed by docling, do so
allow_advanced = all(not file_path.endswith((".csv", ".xlsx", ".parquet")) for file_path in paths)
build_config["advanced_mode"]["show"] = allow_advanced
if not allow_advanced:
build_config["advanced_mode"]["value"] = False
for f in ("pipeline", "ocr_engine", "doc_key", "md_image_placeholder", "md_page_break_placeholder"):
if f in build_config:
build_config[f]["show"] = False
# Disable in cloud environments
if is_astra_cloud_environment():
self._disable_docling_fields_in_cloud(build_config)
else:
# If all files can be processed by docling, do so
allow_advanced = all(not file_path.endswith((".csv", ".xlsx", ".parquet")) for file_path in paths)
build_config["advanced_mode"]["show"] = allow_advanced
if not allow_advanced:
build_config["advanced_mode"]["value"] = False
docling_fields = (
"pipeline",
"ocr_engine",
"doc_key",
"md_image_placeholder",
"md_page_break_placeholder",
)
for field in docling_fields:
if field in build_config:
build_config[field]["show"] = False
# Docling Processing
elif field_name == "advanced_mode":
for f in ("pipeline", "ocr_engine", "doc_key", "md_image_placeholder", "md_page_break_placeholder"):
if f in build_config:
build_config[f]["show"] = bool(field_value)
if f == "pipeline":
build_config[f]["advanced"] = not bool(field_value)
# Disable in cloud environments - don't show Docling fields even if advanced_mode is toggled
if is_astra_cloud_environment():
self._disable_docling_fields_in_cloud(build_config)
else:
docling_fields = (
"pipeline",
"ocr_engine",
"doc_key",
"md_image_placeholder",
"md_page_break_placeholder",
)
for field in docling_fields:
if field in build_config:
build_config[field]["show"] = bool(field_value)
if field == "pipeline":
build_config[field]["advanced"] = not bool(field_value)
elif field_name == "pipeline":
if field_value == "standard":
# Disable in cloud environments - don't show OCR engine even if pipeline is changed
if is_astra_cloud_environment():
self._disable_docling_fields_in_cloud(build_config)
elif field_value == "standard":
build_config["ocr_engine"]["show"] = True
build_config["ocr_engine"]["value"] = "easyocr"
else:
@ -1043,10 +1083,16 @@ class FileComponent(BaseFileComponent):
for file in file_list:
extension = file.path.suffix[1:].lower()
if extension in self.DOCLING_ONLY_EXTENSIONS:
msg = (
f"File '{file.path.name}' has extension '.{extension}' which requires "
f"Advanced Parser mode. Please enable 'Advanced Parser' to process this file."
)
if is_astra_cloud_environment():
msg = (
f"File '{file.path.name}' has extension '.{extension}' which requires "
f"Advanced Parser mode. Advanced Parser is not available in cloud environments."
)
else:
msg = (
f"File '{file.path.name}' has extension '.{extension}' which requires "
f"Advanced Parser mode. Please enable 'Advanced Parser' to process this file."
)
self.log(msg)
raise ValueError(msg)