Repository: microsoft/graphrag
File: graphrag/query/cli.py (Python)

Code before:
            config=config,
            nodes=final_nodes,
            entities=final_entities,
            community_reports=final_community_reports,
            text_units=final_text_units,
            relationships=final_relationships,
            covariates=final_covariates,
            community_level=community_level,
            response_type=response_type,
            query=query,
        )
    )


def _configure_paths_and_settings(
    data_dir: str | None,
    root_dir: str | None,
    config_filepath: str | None,
) -> tuple[str, str | None, GraphRagConfig]:
    config = _create_graphrag_config(root_dir, config_filepath)
    if data_dir is None and root_dir is None:
        msg = "Either data_dir or root_dir must be provided."
        raise ValueError(msg)
    if data_dir is None:
        base_dir = Path(cast(str, root_dir)) / config.storage.base_dir
        data_dir = cast(str, resolve_timestamp_path(base_dir))
    return data_dir, root_dir, config


def _infer_data_dir(root: str) -> str:
    output = Path(root) / "output"
    # use the latest data-run folder
    if output.exists():
        expr = re.compile(r"\d{8}-\d{6}")
        filtered = [f for f in output.iterdir() if f.is_dir() and expr.match(f.name)]
        folders = sorted(filtered, key=lambda f: f.name, reverse=True)
        if len(folders) > 0:
            folder = folders[0]
            return str((folder / "artifacts").absolute())
    msg = f"Could not infer data directory from root={root}"
    raise ValueError(msg)


def _create_graphrag_config(
    root: str | None,
    config_filepath: str | None,
) -> GraphRagConfig:
    """Create a GraphRag configuration."""
    return _read_config_parameters(root or "./", config_filepath)



Review comment (suggestion):
Instead of cast you can do str(resolve_timestamp_path(base_dir))
Generally cast is used to tell the type checker to treat the item as str, whereas str() actually converts the itme.

Code after:
    response, context_data = asyncio.run(
        api.local_search(
            root_dir=root_dir,
            config=config,
            nodes=final_nodes,
            entities=final_entities,
            community_reports=final_community_reports,
            text_units=final_text_units,
            relationships=final_relationships,
            covariates=final_covariates,
            community_level=community_level,
            response_type=response_type,
            query=query,
        )
    )
    reporter.success(f"Local Search Response:\n{response}")
    # NOTE: we return the response and context data here purely as a complete demonstration of the API.
    # External users should use the API directly to get the response and context data.
    return response, context_data


def _configure_paths_and_settings(
    data_dir: str | None,
    root_dir: str | None,
    config_filepath: str | None,
) -> tuple[str, str | None, GraphRagConfig]:
    config = _create_graphrag_config(root_dir, config_filepath)
    if data_dir is None and root_dir is None:
        msg = "Either data_dir or root_dir must be provided."
        raise ValueError(msg)
    if data_dir is None:
        base_dir = Path(str(root_dir)) / config.storage.base_dir
        data_dir = str(resolve_timestamp_path(base_dir))
    return data_dir, root_dir, config


def _infer_data_dir(root: str) -> str:
    output = Path(root) / "output"
    # use the latest data-run folder
    if output.exists():
        expr = re.compile(r"\d{8}-\d{6}")
        filtered = [f for f in output.iterdir() if f.is_dir() and expr.match(f.name)]
        folders = sorted(filtered, key=lambda f: f.name, reverse=True)
        if len(folders) > 0:
            folder = folders[0]
            return str((folder / "artifacts").absolute())
    msg = f"Could not infer data directory from root={root}"
    raise ValueError(msg)


def _create_graphrag_config(