Tony20100/langchain_full huggingface dataset:
prompt = ChatPromptTemplate.from_template("Tell me a short joke about
            {topic}")
            model = ChatOpenAI()
            output_parser = StrOutputParser()
            runnable = prompt | model | output_parser
            runnable_each = RunnableEach(bound=runnable)
            output = runnable_each.invoke([{'topic':'Computer Science'},
                                        {'topic':'Art'},
                                        {'topic':'Biology'}])
            print(output)  # noqa: T201
    """
[docs]    @classmethod
    def get_lc_namespace(cls) -> List[str]:
        """Get the namespace of the langchain object."""
        return ["langchain", "schema", "runnable"]
[docs]    def get_name(
        self, suffix: Optional[str] = None, *, name: Optional[str] = None
    ) -> str:
        name = name or self.name or f"RunnableEach<{self.bound.get_name()}>"
        return super().get_name(suffix, name=name)
[docs]    def bind(self, **kwargs: Any) -> RunnableEach[Input, Output]:
        return RunnableEach(bound=self.bound.bind(**kwargs))
[docs]    def with_config(
        self, config: Optional[RunnableConfig] = None, **kwargs: Any
    ) -> RunnableEach[Input, Output]:
        return RunnableEach(bound=self.bound.with_config(config, **kwargs))
[docs]    def with_listeners(
        self,
        *,
        on_start: Optional[
            Union[Callable[[Run], None], Callable[[Run, RunnableConfig], None]]
        ] = None,
        on_end: Optional[
            Union[Callable[[Run], None], Callable[[Run, RunnableConfig], None]]
        ] = None,
        on_error: Optional[
] = None,
        on_error: Optional[
            Union[Callable[[Run], None], Callable[[Run, RunnableConfig], None]]
        ] = None,
    ) -> RunnableEach[Input, Output]:
        """
        Bind lifecycle listeners to a Runnable, returning a new Runnable.
        on_start: Called before the runnable starts running, with the Run object.
        on_end: Called after the runnable finishes running, with the Run object.
        on_error: Called if the runnable throws an error, with the Run object.
        The Run object contains information about the run, including its id,
        type, input, output, error, start_time, end_time, and any tags or metadata
        added to the run.
        """
        return RunnableEach(
            bound=self.bound.with_listeners(
                on_start=on_start, on_end=on_end, on_error=on_error
            )
        )
[docs]    def with_alisteners(
        self,
        *,
        on_start: Optional[AsyncListener] = None,
        on_end: Optional[AsyncListener] = None,
        on_error: Optional[AsyncListener] = None,
    ) -> RunnableEach[Input, Output]:
        """
        Bind async lifecycle listeners to a Runnable, returning a new Runnable.
        on_start: Called asynchronously before the runnable starts running,
                  with the Run object.
        on_end: Called asynchronously after the runnable finishes running,
                with the Run object.
        on_error: Called asynchronously if the runnable throws an error,
                with the Run object.
        The Run object contains information about the run, including its id,
        type, input, output, error, start_time, end_time, and any tags or metadata
        added to the run.
        """
added to the run.
        """
        return RunnableEach(
            bound=self.bound.with_alisteners(
                on_start=on_start, on_end=on_end, on_error=on_error
            )
        )
[docs]class RunnableBindingBase(RunnableSerializable[Input, Output]):
    """Runnable that delegates calls to another Runnable with a set of kwargs.
    Use only if creating a new RunnableBinding subclass with different __init__ args.
    See documentation for RunnableBinding for more details.
    """
    bound: Runnable[Input, Output]
    """The underlying runnable that this runnable delegates to."""
    kwargs: Mapping[str, Any] = Field(default_factory=dict)
    """kwargs to pass to the underlying runnable when running.
    For example, when the runnable binding is invoked the underlying
    runnable will be invoked with the same input but with these additional
    kwargs.
    """
    config: RunnableConfig = Field(default_factory=dict)
    """The config to bind to the underlying runnable."""
    config_factories: List[Callable[[RunnableConfig], RunnableConfig]] = Field(
        default_factory=list
    )
    """The config factories to bind to the underlying runnable."""
    # Union[Type[Input], BaseModel] + things like List[str]
    custom_input_type: Optional[Any] = None
    """Override the input type of the underlying runnable with a custom type.
    The type can be a pydantic model, or a type annotation (e.g., `List[str]`).
    """
    # Union[Type[Output], BaseModel] + things like List[str]
    custom_output_type: Optional[Any] = None
    """Override the output type of the underlying runnable with a custom type.
"""Override the output type of the underlying runnable with a custom type.
    The type can be a pydantic model, or a type annotation (e.g., `List[str]`).
    """
    class Config:
        arbitrary_types_allowed = True
    def __init__(
        self,
        *,
        bound: Runnable[Input, Output],
        kwargs: Optional[Mapping[str, Any]] = None,
        config: Optional[RunnableConfig] = None,
        config_factories: Optional[
            List[Callable[[RunnableConfig], RunnableConfig]]
        ] = None,
        custom_input_type: Optional[Union[Type[Input], BaseModel]] = None,
        custom_output_type: Optional[Union[Type[Output], BaseModel]] = None,
        **other_kwargs: Any,
    ) -> None:
        """Create a RunnableBinding from a runnable and kwargs.
        Args:
            bound: The underlying runnable that this runnable delegates calls to.
            kwargs: optional kwargs to pass to the underlying runnable, when running
                    the underlying runnable (e.g., via `invoke`, `batch`,
                    `transform`, or `stream` or async variants)
            config: config_factories:
            config_factories: optional list of config factories to apply to the
            custom_input_type: Specify to override the input type of the underlying
                               runnable with a custom type.
            custom_output_type: Specify to override the output type of the underlying
                runnable with a custom type.
            **other_kwargs: Unpacked into the base class.
        """
        super().__init__(  # type: ignore[call-arg]
            bound=bound,
            kwargs=kwargs or {},
            config=config or {},
            config_factories=config_factories or [],
            custom_input_type=custom_input_type,
config_factories=config_factories or [],
            custom_input_type=custom_input_type,
            custom_output_type=custom_output_type,
            **other_kwargs,
        )
        # if we don't explicitly set config to the TypedDict here,
        # the pydantic init above will strip out any of the "extra"
        # fields even though total=False on the typed dict.
        self.config = config or {}
[docs]    def get_name(
        self, suffix: Optional[str] = None, *, name: Optional[str] = None
    ) -> str:
        return self.bound.get_name(suffix, name=name)
    @property
    def InputType(self) -> Type[Input]:
        return (
            cast(Type[Input], self.custom_input_type)
            if self.custom_input_type is not None
            else self.bound.InputType
        )
    @property
    def OutputType(self) -> Type[Output]:
        return (
            cast(Type[Output], self.custom_output_type)
            if self.custom_output_type is not None
            else self.bound.OutputType
        )
[docs]    def get_input_schema(
        self, config: Optional[RunnableConfig] = None
    ) -> Type[BaseModel]:
        if self.custom_input_type is not None:
            return super().get_input_schema(config)
        return self.bound.get_input_schema(merge_configs(self.config, config))
[docs]    def get_output_schema(
        self, config: Optional[RunnableConfig] = None
    ) -> Type[BaseModel]:
        if self.custom_output_type is not None:
            return super().get_output_schema(config)
        return self.bound.get_output_schema(merge_configs(self.config, config))
    @property
@property
    def config_specs(self) -> List[ConfigurableFieldSpec]:
        return self.bound.config_specs
[docs]    def get_graph(self, config: Optional[RunnableConfig] = None) -> Graph:
        return self.bound.get_graph(config)
[docs]    @classmethod
    def is_lc_serializable(cls) -> bool:
        return True
[docs]    @classmethod
    def get_lc_namespace(cls) -> List[str]:
        """Get the namespace of the langchain object."""
        return ["langchain", "schema", "runnable"]
    def _merge_configs(self, *configs: Optional[RunnableConfig]) -> RunnableConfig:
        config = merge_configs(self.config, *configs)
        return merge_configs(config, *(f(config) for f in self.config_factories))
[docs]    def invoke(
        self,
        input: Input,
        config: Optional[RunnableConfig] = None,
        **kwargs: Optional[Any],
    ) -> Output:
        return self.bound.invoke(
            input,
            self._merge_configs(config),
            **{**self.kwargs, **kwargs},
        )
[docs]    async def ainvoke(
        self,
        input: Input,
        config: Optional[RunnableConfig] = None,
        **kwargs: Optional[Any],
    ) -> Output:
        return await self.bound.ainvoke(
            input,
            self._merge_configs(config),
            **{**self.kwargs, **kwargs},
        )
[docs]    def batch(
        self,
        inputs: List[Input],
        config: Optional[Union[RunnableConfig, List[RunnableConfig]]] = None,
        *,
        return_exceptions: bool = False,
        **kwargs: Optional[Any],
*,
        return_exceptions: bool = False,
        **kwargs: Optional[Any],
    ) -> List[Output]:
        if isinstance(config, list):
            configs = cast(
                List[RunnableConfig],
                [self._merge_configs(conf) for conf in config],
            )
        else:
            configs = [self._merge_configs(config) for _ in range(len(inputs))]
        return self.bound.batch(
            inputs,
            configs,
            return_exceptions=return_exceptions,
            **{**self.kwargs, **kwargs},
        )
[docs]    async def abatch(
        self,
        inputs: List[Input],
        config: Optional[Union[RunnableConfig, List[RunnableConfig]]] = None,
        *,
        return_exceptions: bool = False,
        **kwargs: Optional[Any],
    ) -> List[Output]:
        if isinstance(config, list):
            configs = cast(
                List[RunnableConfig],
                [self._merge_configs(conf) for conf in config],
            )
        else:
            configs = [self._merge_configs(config) for _ in range(len(inputs))]
        return await self.bound.abatch(
            inputs,
            configs,
            return_exceptions=return_exceptions,
            **{**self.kwargs, **kwargs},
        )
    @overload
    def batch_as_completed(
        self,
        inputs: Sequence[Input],
        config: Optional[Union[RunnableConfig, Sequence[RunnableConfig]]] = None,
        *,
        return_exceptions: Literal[False] = False,
        **kwargs: Any,
    ) -> Iterator[Tuple[int, Output]]:
        ...
    @overload
    def batch_as_completed(
        self,
...
    @overload
    def batch_as_completed(
        self,
        inputs: Sequence[Input],
        config: Optional[Union[RunnableConfig, Sequence[RunnableConfig]]] = None,
        *,
        return_exceptions: Literal[True],
        **kwargs: Any,
    ) -> Iterator[Tuple[int, Union[Output, Exception]]]:
        ...
[docs]    def batch_as_completed(
        self,
        inputs: Sequence[Input],
        config: Optional[Union[RunnableConfig, Sequence[RunnableConfig]]] = None,
        *,
        return_exceptions: bool = False,
        **kwargs: Optional[Any],
    ) -> Iterator[Tuple[int, Union[Output, Exception]]]:
        if isinstance(config, Sequence):
            configs = cast(
                List[RunnableConfig],
                [self._merge_configs(conf) for conf in config],
            )
        else:
            configs = [self._merge_configs(config) for _ in range(len(inputs))]
        # lol mypy
        if return_exceptions:
            yield from self.bound.batch_as_completed(
                inputs,
                configs,
                return_exceptions=return_exceptions,
                **{**self.kwargs, **kwargs},
            )
        else:
            yield from self.bound.batch_as_completed(
                inputs,
                configs,
                return_exceptions=return_exceptions,
                **{**self.kwargs, **kwargs},
            )
    @overload
    def abatch_as_completed(
        self,
        inputs: Sequence[Input],
        config: Optional[Union[RunnableConfig, Sequence[RunnableConfig]]] = None,
        *,
        return_exceptions: Literal[False] = False,
        **kwargs: Optional[Any],
return_exceptions: Literal[False] = False,
        **kwargs: Optional[Any],
    ) -> AsyncIterator[Tuple[int, Output]]:
        ...
    @overload
    def abatch_as_completed(
        self,
        inputs: Sequence[Input],
        config: Optional[Union[RunnableConfig, Sequence[RunnableConfig]]] = None,
        *,
        return_exceptions: Literal[True],
        **kwargs: Optional[Any],
    ) -> AsyncIterator[Tuple[int, Union[Output, Exception]]]:
        ...
[docs]    async def abatch_as_completed(
        self,
        inputs: Sequence[Input],
        config: Optional[Union[RunnableConfig, Sequence[RunnableConfig]]] = None,
        *,
        return_exceptions: bool = False,
        **kwargs: Optional[Any],
    ) -> AsyncIterator[Tuple[int, Union[Output, Exception]]]:
        if isinstance(config, Sequence):
            configs = cast(
                List[RunnableConfig],
                [self._merge_configs(conf) for conf in config],
            )
        else:
            configs = [self._merge_configs(config) for _ in range(len(inputs))]
        if return_exceptions:
            async for item in self.bound.abatch_as_completed(
                inputs,
                configs,
                return_exceptions=return_exceptions,
                **{**self.kwargs, **kwargs},
            ):
                yield item
        else:
            async for item in self.bound.abatch_as_completed(
                inputs,
                configs,
                return_exceptions=return_exceptions,
                **{**self.kwargs, **kwargs},
            ):
                yield item
[docs]    def stream(
        self,
        input: Input,
        config: Optional[RunnableConfig] = None,
input: Input,
        config: Optional[RunnableConfig] = None,
        **kwargs: Optional[Any],
    ) -> Iterator[Output]:
        yield from self.bound.stream(
            input,
            self._merge_configs(config),
            **{**self.kwargs, **kwargs},
        )
[docs]    async def astream(
        self,
        input: Input,
        config: Optional[RunnableConfig] = None,
        **kwargs: Optional[Any],
    ) -> AsyncIterator[Output]:
        async for item in self.bound.astream(
            input,
            self._merge_configs(config),
            **{**self.kwargs, **kwargs},
        ):
            yield item
[docs]    async def astream_events(
        self,
        input: Input,
        config: Optional[RunnableConfig] = None,
        **kwargs: Optional[Any],
    ) -> AsyncIterator[StreamEvent]:
        async for item in self.bound.astream_events(
            input, self._merge_configs(config), **{**self.kwargs, **kwargs}
        ):
            yield item
[docs]    def transform(
        self,
        input: Iterator[Input],
        config: Optional[RunnableConfig] = None,
        **kwargs: Any,
    ) -> Iterator[Output]:
        yield from self.bound.transform(
            input,
            self._merge_configs(config),
            **{**self.kwargs, **kwargs},
        )
[docs]    async def atransform(
        self,
        input: AsyncIterator[Input],
        config: Optional[RunnableConfig] = None,
        **kwargs: Any,
    ) -> AsyncIterator[Output]:
        async for item in self.bound.atransform(
            input,
async for item in self.bound.atransform(
            input,
            self._merge_configs(config),
            **{**self.kwargs, **kwargs},
        ):
            yield item
RunnableBindingBase.update_forward_refs(RunnableConfig=RunnableConfig)
[docs]class RunnableBinding(RunnableBindingBase[Input, Output]):
    """Wrap a Runnable with additional functionality.
    A RunnableBinding can be thought of as a "runnable decorator" that
    preserves the essential features of Runnable; i.e., batching, streaming,
    and async support, while adding additional functionality.
    Any class that inherits from Runnable can be bound to a `RunnableBinding`.
    Runnables expose a standard set of methods for creating `RunnableBindings`
    or sub-classes of `RunnableBindings` (e.g., `RunnableRetry`,
    `RunnableWithFallbacks`) that add additional functionality.
    These methods include:
    - `bind`: Bind kwargs to pass to the underlying runnable when running it.
    - `with_config`: Bind config to pass to the underlying runnable when running it.
    - `with_listeners`:  Bind lifecycle listeners to the underlying runnable.
    - `with_types`: Override the input and output types of the underlying runnable.
    - `with_retry`: Bind a retry policy to the underlying runnable.
    - `with_fallbacks`: Bind a fallback policy to the underlying runnable.
    Example:
    `bind`: Bind kwargs to pass to the underlying runnable when running it.
        .. code-block:: python
            # Create a runnable binding that invokes the ChatModel with the
            # additional kwarg `stop=['-']` when running it.
            from langchain_community.chat_models import ChatOpenAI
            model = ChatOpenAI()
from langchain_community.chat_models import ChatOpenAI
            model = ChatOpenAI()
            model.invoke('Say "Parrot-MAGIC"', stop=['-']) # Should return `Parrot`
            # Using it the easy way via `bind` method which returns a new
            # RunnableBinding
            runnable_binding = model.bind(stop=['-'])
            runnable_binding.invoke('Say "Parrot-MAGIC"') # Should return `Parrot`
        Can also be done by instantiating a RunnableBinding directly (not recommended):
        .. code-block:: python
            from langchain_core.runnables import RunnableBinding
            runnable_binding = RunnableBinding(
                bound=model,
                kwargs={'stop': ['-']} # <-- Note the additional kwargs
            )
            runnable_binding.invoke('Say "Parrot-MAGIC"') # Should return `Parrot`
    """
[docs]    @classmethod
    def get_lc_namespace(cls) -> List[str]:
        """Get the namespace of the langchain object."""
        return ["langchain", "schema", "runnable"]
[docs]    def bind(self, **kwargs: Any) -> Runnable[Input, Output]:
        """Bind additional kwargs to a Runnable, returning a new Runnable.
        Args:
            **kwargs: The kwargs to bind to the Runnable.
        Returns:
            A new Runnable with the same type and config as the original,
            but with the additional kwargs bound.
        """
        return self.__class__(
            bound=self.bound,
            config=self.config,
            kwargs={**self.kwargs, **kwargs},
            custom_input_type=self.custom_input_type,
            custom_output_type=self.custom_output_type,
        )
[docs]    def with_config(
        self,
        config: Optional[RunnableConfig] = None,
self,
        config: Optional[RunnableConfig] = None,
        # Sadly Unpack is not well supported by mypy so this will have to be untyped
        **kwargs: Any,
    ) -> Runnable[Input, Output]:
        return self.__class__(
            bound=self.bound,
            kwargs=self.kwargs,
            config=cast(RunnableConfig, {**self.config, **(config or {}), **kwargs}),
            custom_input_type=self.custom_input_type,
            custom_output_type=self.custom_output_type,
        )
[docs]    def with_listeners(
        self,
        *,
        on_start: Optional[
            Union[Callable[[Run], None], Callable[[Run, RunnableConfig], None]]
        ] = None,
        on_end: Optional[
            Union[Callable[[Run], None], Callable[[Run, RunnableConfig], None]]
        ] = None,
        on_error: Optional[
            Union[Callable[[Run], None], Callable[[Run, RunnableConfig], None]]
        ] = None,
    ) -> Runnable[Input, Output]:
        """Bind lifecycle listeners to a Runnable, returning a new Runnable.
        Args:
            on_start: Called before the runnable starts running, with the Run object.
            on_end: Called after the runnable finishes running, with the Run object.
            on_error: Called if the runnable throws an error, with the Run object.
        Returns:
            The Run object contains information about the run, including its id,
            type, input, output, error, start_time, end_time, and any tags or metadata
            added to the run.
        """
        from langchain_core.tracers.root_listeners import RootListenersTracer
        return self.__class__(
            bound=self.bound,
            kwargs=self.kwargs,
return self.__class__(
            bound=self.bound,
            kwargs=self.kwargs,
            config=self.config,
            config_factories=[
                lambda config: {
                    "callbacks": [
                        RootListenersTracer(
                            config=config,
                            on_start=on_start,
                            on_end=on_end,
                            on_error=on_error,
                        )
                    ],
                }
            ],
            custom_input_type=self.custom_input_type,
            custom_output_type=self.custom_output_type,
        )
[docs]    def with_types(
        self,
        input_type: Optional[Union[Type[Input], BaseModel]] = None,
        output_type: Optional[Union[Type[Output], BaseModel]] = None,
    ) -> Runnable[Input, Output]:
        return self.__class__(
            bound=self.bound,
            kwargs=self.kwargs,
            config=self.config,
            custom_input_type=(
                input_type if input_type is not None else self.custom_input_type
            ),
            custom_output_type=(
                output_type if output_type is not None else self.custom_output_type
            ),
        )
[docs]    def with_retry(self, **kwargs: Any) -> Runnable[Input, Output]:
        return self.__class__(
            bound=self.bound.with_retry(**kwargs),
            kwargs=self.kwargs,
            config=self.config,
        )
    def __getattr__(self, name: str) -> Any:
        attr = getattr(self.bound, name)
        if callable(attr) and (
            config_param := inspect.signature(attr).parameters.get("config")
        ):
            if config_param.kind == inspect.Parameter.KEYWORD_ONLY:
                @wraps(attr)
                def wrapper(*args: Any, **kwargs: Any) -> Any:
                    return attr(