From 1dae3c383ed17b0a2e4675accf396bc73834de75 Mon Sep 17 00:00:00 2001 From: Harrison Chase Date: Tue, 19 Sep 2023 17:03:32 -0700 Subject: [PATCH] Harrison/add submodule to docs (#10803) --- docs/api_reference/create_api_rst.py | 28 +++++++++++++++++++----- libs/langchain/langchain/tools/render.py | 17 +++++++------- 2 files changed, 32 insertions(+), 13 deletions(-) diff --git a/docs/api_reference/create_api_rst.py b/docs/api_reference/create_api_rst.py index ee32f0d4cf..a9fe8e9c3a 100644 --- a/docs/api_reference/create_api_rst.py +++ b/docs/api_reference/create_api_rst.py @@ -1,9 +1,10 @@ """Script for auto-generating api_reference.rst.""" import importlib import inspect +import os import typing from pathlib import Path -from typing import TypedDict, Sequence, List, Dict, Literal, Union +from typing import TypedDict, Sequence, List, Dict, Literal, Union, Optional from enum import Enum from pydantic import BaseModel @@ -122,7 +123,8 @@ def _merge_module_members( def _load_package_modules( - package_directory: Union[str, Path] + package_directory: Union[str, Path], + submodule: Optional[str] = None ) -> Dict[str, ModuleMembers]: """Recursively load modules of a package based on the file system. @@ -131,6 +133,7 @@ def _load_package_modules( Parameters: package_directory: Path to the package directory. + submodule: Optional name of submodule to load. Returns: list: A list of loaded module objects. @@ -142,8 +145,13 @@ def _load_package_modules( ) modules_by_namespace = {} + # Get the high level package name package_name = package_path.name + # If we are loading a submodule, add it in + if submodule is not None: + package_path = package_path / submodule + for file_path in package_path.rglob("*.py"): if file_path.name.startswith("_"): continue @@ -160,9 +168,16 @@ def _load_package_modules( top_namespace = namespace.split(".")[0] try: - module_members = _load_module_members( - f"{package_name}.{namespace}", namespace - ) + # If submodule is present, we need to construct the paths in a slightly + # different way + if submodule is not None: + module_members = _load_module_members( + f"{package_name}.{submodule}.{namespace}", f"{submodule}.{namespace}" + ) + else: + module_members = _load_module_members( + f"{package_name}.{namespace}", namespace + ) # Merge module members if the namespace already exists if top_namespace in modules_by_namespace: existing_module_members = modules_by_namespace[top_namespace] @@ -269,6 +284,9 @@ Functions def main() -> None: """Generate the reference.rst file for each package.""" lc_members = _load_package_modules(PKG_DIR) + # Put tools.render at the top level + tools = _load_package_modules(PKG_DIR, "tools") + lc_members['tools.render'] = tools['render'] lc_doc = ".. _api_reference:\n\n" + _construct_doc("langchain", lc_members) with open(WRITE_FILE, "w") as f: f.write(lc_doc) diff --git a/libs/langchain/langchain/tools/render.py b/libs/langchain/langchain/tools/render.py index e057489450..7b2a92278e 100644 --- a/libs/langchain/langchain/tools/render.py +++ b/libs/langchain/langchain/tools/render.py @@ -8,10 +8,10 @@ def render_text_description(tools: List[BaseTool]) -> str: Output will be in the format of: - ``` - search: This tool is used for search - calculator: This tool is used for math - ``` + .. code-block:: markdown + + search: This tool is used for search + calculator: This tool is used for math """ return "\n".join([f"{tool.name}: {tool.description}" for tool in tools]) @@ -21,10 +21,11 @@ def render_text_description_and_args(tools: List[BaseTool]) -> str: Output will be in the format of: - ``` - search: This tool is used for search, args: {"query": {"type": "string"}} - calculator: This tool is used for math, args: {"expression": {"type": "string"}} - ``` + .. code-block:: markdown + + search: This tool is used for search, args: {"query": {"type": "string"}} + calculator: This tool is used for math, \ +args: {"expression": {"type": "string"}} """ tool_strings = [] for tool in tools: