viruPVS/langchain-docs huggingface dataset:
These methods will work on any Runnable, including Runnable chains constructed
    by composing other Runnables. See the individual methods for details.
    For example,
    .. code-block:: python
        from langchain_core.runnables import RunnableLambda
        import random
        def add_one(x: int) -> int:
            return x + 1
        def buggy_double(y: int) -> int:
            '''Buggy code that will fail 70% of the time'''
            if random.random() > 0.3:
                print('This code failed, and will probably be retried!')
                raise ValueError('Triggered buggy code')
            return y * 2
        sequence = (
            RunnableLambda(add_one) |
            RunnableLambda(buggy_double).with_retry( # Retry on failure
                stop_after_attempt=10,
                wait_exponential_jitter=False
            )
        )
        print(sequence.input_schema.schema()) # Show inferred input schema
        print(sequence.output_schema.schema()) # Show inferred output schema
        print(sequence.invoke(2)) # invoke the sequence (note the retry above!!)
    Debugging and tracing
    =====================
    As the chains get longer, it can be useful to be able to see intermediate results
    to debug and trace the chain.
    You can set the global debug flag to True to enable debug output for all chains:
        .. code-block:: python
            from langchain_core.globals import set_debug
            set_debug(True)
    Alternatively, you can pass existing or custom callbacks to any given chain:
        .. code-block:: python
            from langchain_core.tracers import ConsoleCallbackHandler
            chain.invoke(
                ...,
                config={'callbacks': [ConsoleCallbackHandler()]}
            )
...,
                config={'callbacks': [ConsoleCallbackHandler()]}
            )
    For a UI (and much more) checkout LangSmith: https://docs.smith.langchain.com/
    """
    @property
    def InputType(self) -> Type[Input]:
        """The type of input this runnable accepts specified as a type annotation."""
        for cls in self.__class__.__orig_bases__:  # type: ignore[attr-defined]
            type_args = get_args(cls)
            if type_args and len(type_args) == 2:
                return type_args[0]
        raise TypeError(
            f"Runnable {self.__class__.__name__} doesn't have an inferable InputType. "
            "Override the InputType property to specify the input type."
        )
    @property
    def OutputType(self) -> Type[Output]:
        """The type of output this runnable produces specified as a type annotation."""
        for cls in self.__class__.__orig_bases__:  # type: ignore[attr-defined]
            type_args = get_args(cls)
            if type_args and len(type_args) == 2:
                return type_args[1]
        raise TypeError(
            f"Runnable {self.__class__.__name__} doesn't have an inferable OutputType. "
            "Override the OutputType property to specify the output type."
        )
    @property
    def input_schema(self) -> Type[BaseModel]:
        """The type of input this runnable accepts specified as a pydantic model."""
        return self.get_input_schema()
[docs]    def get_input_schema(
        self, config: Optional[RunnableConfig] = None
    ) -> Type[BaseModel]:
        """Get a pydantic model that can be used to validate input to the runnable.
"""Get a pydantic model that can be used to validate input to the runnable.
        Runnables that leverage the configurable_fields and configurable_alternatives
        methods will have a dynamic input schema that depends on which
        configuration the runnable is invoked with.
        This method allows to get an input schema for a specific configuration.
        Args:
            config: A config to use when generating the schema.
        Returns:
            A pydantic model that can be used to validate input.
        """
        root_type = self.InputType
        if inspect.isclass(root_type) and issubclass(root_type, BaseModel):
            return root_type
        return create_model(
            self.__class__.__name__ + "Input", __root__=(root_type, None)
        )
    @property
    def output_schema(self) -> Type[BaseModel]:
        """The type of output this runnable produces specified as a pydantic model."""
        return self.get_output_schema()
[docs]    def get_output_schema(
        self, config: Optional[RunnableConfig] = None
    ) -> Type[BaseModel]:
        """Get a pydantic model that can be used to validate output to the runnable.
        Runnables that leverage the configurable_fields and configurable_alternatives
        methods will have a dynamic output schema that depends on which
        configuration the runnable is invoked with.
        This method allows to get an output schema for a specific configuration.
        Args:
            config: A config to use when generating the schema.
        Returns:
            A pydantic model that can be used to validate output.
        """
        root_type = self.OutputType
        if inspect.isclass(root_type) and issubclass(root_type, BaseModel):
            return root_type
        return create_model(
return root_type
        return create_model(
            self.__class__.__name__ + "Output", __root__=(root_type, None)
        )
    @property
    def config_specs(self) -> List[ConfigurableFieldSpec]:
        """List configurable fields for this runnable."""
        return []
[docs]    def config_schema(
        self, *, include: Optional[Sequence[str]] = None
    ) -> Type[BaseModel]:
        """The type of config this runnable accepts specified as a pydantic model.
        To mark a field as configurable, see the `configurable_fields`
        and `configurable_alternatives` methods.
        Args:
            include: A list of fields to include in the config schema.
        Returns:
            A pydantic model that can be used to validate config.
        """
        class _Config:
            arbitrary_types_allowed = True
        include = include or []
        config_specs = self.config_specs
        configurable = (
            create_model(  # type: ignore[call-overload]
                "Configurable",
                **{
                    spec.id: (
                        spec.annotation,
                        Field(
                            spec.default, title=spec.name, description=spec.description
                        ),
                    )
                    for spec in config_specs
                },
            )
            if config_specs
            else None
        )
        return create_model(  # type: ignore[call-overload]
            self.__class__.__name__ + "Config",
            __config__=_Config,
            **({"configurable": (configurable, None)} if configurable else {}),
            **{
                field_name: (field_type, None)
                for field_name, field_type in RunnableConfig.__annotations__.items()
for field_name, field_type in RunnableConfig.__annotations__.items()
                if field_name in [i for i in include if i != "configurable"]
            },
        )
    def __or__(
        self,
        other: Union[
            Runnable[Any, Other],
            Callable[[Any], Other],
            Callable[[Iterator[Any]], Iterator[Other]],
            Mapping[str, Union[Runnable[Any, Other], Callable[[Any], Other], Any]],
        ],
    ) -> RunnableSerializable[Input, Other]:
        """Compose this runnable with another object to create a RunnableSequence."""
        return RunnableSequence(first=self, last=coerce_to_runnable(other))
    def __ror__(
        self,
        other: Union[
            Runnable[Other, Any],
            Callable[[Other], Any],
            Callable[[Iterator[Other]], Iterator[Any]],
            Mapping[str, Union[Runnable[Other, Any], Callable[[Other], Any], Any]],
        ],
    ) -> RunnableSerializable[Other, Output]:
        """Compose this runnable with another object to create a RunnableSequence."""
        return RunnableSequence(first=coerce_to_runnable(other), last=self)
    """ --- Public API --- """
[docs]    @abstractmethod
    def invoke(self, input: Input, config: Optional[RunnableConfig] = None) -> Output:
        """Transform a single input into an output. Override to implement.
        Args:
            input: The input to the runnable.
            config: A config to use when invoking the runnable.
               The config supports standard keys like 'tags', 'metadata' for tracing
               purposes, 'max_concurrency' for controlling how much work to do
               in parallel, and other keys. Please refer to the RunnableConfig
               for more details.
        Returns:
for more details.
        Returns:
            The output of the runnable.
        """
[docs]    async def ainvoke(
        self, input: Input, config: Optional[RunnableConfig] = None, **kwargs: Any
    ) -> Output:
        """Default implementation of ainvoke, calls invoke from a thread.
        The default implementation allows usage of async code even if
        the runnable did not implement a native async version of invoke.
        Subclasses should override this method if they can run asynchronously.
        """
        return await asyncio.get_running_loop().run_in_executor(
            None, partial(self.invoke, **kwargs), input, config
        )
[docs]    def batch(
        self,
        inputs: List[Input],
        config: Optional[Union[RunnableConfig, List[RunnableConfig]]] = None,
        *,
        return_exceptions: bool = False,
        **kwargs: Optional[Any],
    ) -> List[Output]:
        """Default implementation runs invoke in parallel using a thread pool executor.
        The default implementation of batch works well for IO bound runnables.
        Subclasses should override this method if they can batch more efficiently;
        e.g., if the underlying runnable uses an API which supports a batch mode.
        """
        if not inputs:
            return []
        configs = get_config_list(config, len(inputs))
        def invoke(input: Input, config: RunnableConfig) -> Union[Output, Exception]:
            if return_exceptions:
                try:
                    return self.invoke(input, config, **kwargs)
                except Exception as e:
                    return e
            else:
                return self.invoke(input, config, **kwargs)
        # If there's only one input, don't bother with the executor
        if len(inputs) == 1:
if len(inputs) == 1:
            return cast(List[Output], [invoke(inputs[0], configs[0])])
        with get_executor_for_config(configs[0]) as executor:
            return cast(List[Output], list(executor.map(invoke, inputs, configs)))
[docs]    async def abatch(
        self,
        inputs: List[Input],
        config: Optional[Union[RunnableConfig, List[RunnableConfig]]] = None,
        *,
        return_exceptions: bool = False,
        **kwargs: Optional[Any],
    ) -> List[Output]:
        """Default implementation runs ainvoke in parallel using asyncio.gather.
        The default implementation of batch works well for IO bound runnables.
        Subclasses should override this method if they can batch more efficiently;
        e.g., if the underlying runnable uses an API which supports a batch mode.
        """
        if not inputs:
            return []
        configs = get_config_list(config, len(inputs))
        async def ainvoke(
            input: Input, config: RunnableConfig
        ) -> Union[Output, Exception]:
            if return_exceptions:
                try:
                    return await self.ainvoke(input, config, **kwargs)
                except Exception as e:
                    return e
            else:
                return await self.ainvoke(input, config, **kwargs)
        coros = map(ainvoke, inputs, configs)
        return await gather_with_concurrency(configs[0].get("max_concurrency"), *coros)
[docs]    def stream(
        self,
        input: Input,
        config: Optional[RunnableConfig] = None,
        **kwargs: Optional[Any],
    ) -> Iterator[Output]:
        """
**kwargs: Optional[Any],
    ) -> Iterator[Output]:
        """
        Default implementation of stream, which calls invoke.
        Subclasses should override this method if they support streaming output.
        """
        yield self.invoke(input, config, **kwargs)
[docs]    async def astream(
        self,
        input: Input,
        config: Optional[RunnableConfig] = None,
        **kwargs: Optional[Any],
    ) -> AsyncIterator[Output]:
        """
        Default implementation of astream, which calls ainvoke.
        Subclasses should override this method if they support streaming output.
        """
        yield await self.ainvoke(input, config, **kwargs)
    @overload
    def astream_log(
        self,
        input: Any,
        config: Optional[RunnableConfig] = None,
        *,
        diff: Literal[True] = True,
        with_streamed_output_list: bool = True,
        include_names: Optional[Sequence[str]] = None,
        include_types: Optional[Sequence[str]] = None,
        include_tags: Optional[Sequence[str]] = None,
        exclude_names: Optional[Sequence[str]] = None,
        exclude_types: Optional[Sequence[str]] = None,
        exclude_tags: Optional[Sequence[str]] = None,
        **kwargs: Optional[Any],
    ) -> AsyncIterator[RunLogPatch]:
        ...
    @overload
    def astream_log(
        self,
        input: Any,
        config: Optional[RunnableConfig] = None,
        *,
        diff: Literal[False],
        with_streamed_output_list: bool = True,
        include_names: Optional[Sequence[str]] = None,
        include_types: Optional[Sequence[str]] = None,
include_types: Optional[Sequence[str]] = None,
        include_tags: Optional[Sequence[str]] = None,
        exclude_names: Optional[Sequence[str]] = None,
        exclude_types: Optional[Sequence[str]] = None,
        exclude_tags: Optional[Sequence[str]] = None,
        **kwargs: Optional[Any],
    ) -> AsyncIterator[RunLog]:
        ...
[docs]    async def astream_log(
        self,
        input: Any,
        config: Optional[RunnableConfig] = None,
        *,
        diff: bool = True,
        with_streamed_output_list: bool = True,
        include_names: Optional[Sequence[str]] = None,
        include_types: Optional[Sequence[str]] = None,
        include_tags: Optional[Sequence[str]] = None,
        exclude_names: Optional[Sequence[str]] = None,
        exclude_types: Optional[Sequence[str]] = None,
        exclude_tags: Optional[Sequence[str]] = None,
        **kwargs: Optional[Any],
    ) -> Union[AsyncIterator[RunLogPatch], AsyncIterator[RunLog]]:
        """
        Stream all output from a runnable, as reported to the callback system.
        This includes all inner runs of LLMs, Retrievers, Tools, etc.
        Output is streamed as Log objects, which include a list of
        jsonpatch ops that describe how the state of the run has changed in each
        step, and the final state of the run.
        The jsonpatch ops can be applied in order to construct state.
        Args:
            input: The input to the runnable.
            config: The config to use for the runnable.
            diff: Whether to yield diffs between each step, or the current state.
diff: Whether to yield diffs between each step, or the current state.
            with_streamed_output_list: Whether to yield the streamed_output list.
            include_names: Only include logs with these names.
            include_types: Only include logs with these types.
            include_tags: Only include logs with these tags.
            exclude_names: Exclude logs with these names.
            exclude_types: Exclude logs with these types.
            exclude_tags: Exclude logs with these tags.
        """
        import jsonpatch  # type: ignore[import]
        from langchain_core.callbacks.base import BaseCallbackManager
        from langchain_core.tracers.log_stream import (
            LogStreamCallbackHandler,
            RunLog,
            RunLogPatch,
        )
        # Create a stream handler that will emit Log objects
        stream = LogStreamCallbackHandler(
            auto_close=False,
            include_names=include_names,
            include_types=include_types,
            include_tags=include_tags,
            exclude_names=exclude_names,
            exclude_types=exclude_types,
            exclude_tags=exclude_tags,
        )
        # Assign the stream handler to the config
        config = config or {}
        callbacks = config.get("callbacks")
        if callbacks is None:
            config["callbacks"] = [stream]
        elif isinstance(callbacks, list):
            config["callbacks"] = callbacks + [stream]
        elif isinstance(callbacks, BaseCallbackManager):
            callbacks = callbacks.copy()
            callbacks.add_handler(stream, inherit=True)
            config["callbacks"] = callbacks
        else:
            raise ValueError(
                f"Unexpected type for callbacks: {callbacks}."
                "Expected None, list or AsyncCallbackManager."
            )
        # Call the runnable in streaming mode,
        # add each chunk to the output stream
# Call the runnable in streaming mode,
        # add each chunk to the output stream
        async def consume_astream() -> None:
            try:
                prev_final_output: Optional[Output] = None
                final_output: Optional[Output] = None
                async for chunk in self.astream(input, config, **kwargs):
                    prev_final_output = final_output
                    if final_output is None:
                        final_output = chunk
                    else:
                        try:
                            final_output = final_output + chunk  # type: ignore
                        except TypeError:
                            final_output = chunk
                    patches: List[Dict[str, Any]] = []
                    if with_streamed_output_list:
                        patches.append(
                            {
                                "op": "add",
                                "path": "/streamed_output/-",
                                # chunk cannot be shared between
                                # streamed_output and final_output
                                # otherwise jsonpatch.apply will
                                # modify both
                                "value": deepcopy(chunk),
                            }
                        )
                    for op in jsonpatch.JsonPatch.from_diff(
                        prev_final_output, final_output, dumps=dumps
                    ):
                        patches.append({**op, "path": f"/final_output{op['path']}"})
                    await stream.send_stream.send(RunLogPatch(*patches))
            finally:
                await stream.send_stream.aclose()
        # Start the runnable in a task, so we can start consuming output
        task = asyncio.create_task(consume_astream())
        try:
            # Yield each chunk from the output stream
            if diff:
                async for log in stream:
                    yield log
            else:
                state = RunLog(state=None)  # type: ignore[arg-type]
                async for log in stream:
                    state = state + log
                    yield state
        finally:
state = state + log
                    yield state
        finally:
            # Wait for the runnable to finish, if not cancelled (eg. by break)
            try:
                await task
            except asyncio.CancelledError:
                pass
[docs]    def transform(
        self,
        input: Iterator[Input],
        config: Optional[RunnableConfig] = None,
        **kwargs: Optional[Any],
    ) -> Iterator[Output]:
        """
        Default implementation of transform, which buffers input and then calls stream.
        Subclasses should override this method if they can start producing output while
        input is still being generated.
        """
        final: Input
        got_first_val = False
        for chunk in input:
            if not got_first_val:
                final = chunk
                got_first_val = True
            else:
                # Make a best effort to gather, for any type that supports `+`
                # This method should throw an error if gathering fails.
                final = final + chunk  # type: ignore[operator]
        if got_first_val:
            yield from self.stream(final, config, **kwargs)
[docs]    async def atransform(
        self,
        input: AsyncIterator[Input],
        config: Optional[RunnableConfig] = None,
        **kwargs: Optional[Any],
    ) -> AsyncIterator[Output]:
        """
        Default implementation of atransform, which buffers input and calls astream.
        Subclasses should override this method if they can start producing output while
        input is still being generated.
        """
        final: Input
        got_first_val = False
        async for chunk in input:
            if not got_first_val:
                final = chunk
                got_first_val = True
            else:
final = chunk
                got_first_val = True
            else:
                # Make a best effort to gather, for any type that supports `+`
                # This method should throw an error if gathering fails.
                final = final + chunk  # type: ignore[operator]
        if got_first_val:
            async for output in self.astream(final, config, **kwargs):
                yield output
[docs]    def bind(self, **kwargs: Any) -> Runnable[Input, Output]:
        """
        Bind arguments to a Runnable, returning a new Runnable.
        """
        return RunnableBinding(bound=self, kwargs=kwargs, config={})
[docs]    def with_config(
        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]:
        """
        Bind config to a Runnable, returning a new Runnable.
        """
        return RunnableBinding(
            bound=self,
            config=cast(
                RunnableConfig,
                {**(config or {}), **kwargs},
            ),  # type: ignore[misc]
            kwargs={},
        )
[docs]    def with_listeners(
        self,
        *,
        on_start: Optional[Listener] = None,
        on_end: Optional[Listener] = None,
        on_error: Optional[Listener] = None,
    ) -> Runnable[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.