fastapi-jsonrpc icon indicating copy to clipboard operation
fastapi-jsonrpc copied to clipboard

Exposing a Langchain tool as JSON-RPC method

Open nethi opened this issue 1 year ago • 0 comments
trafficstars

Hi,

I started using this library and works great. Langchain library provides several out of the box tools (aka functions) for use with LLMs. I am trying to reuse these tools and expose them as JSON-RPC methods.

Langchain tool code

Here is a what I am trying

from langchain_community.tools import WikipediaQueryRun
from langchain_community.utilities import WikipediaAPIWrapper
import fastapi_jsonrpc as jsonrpc


app = jsonrpc.API()

#Create a JSON-RPC entrypoint
entrypoint = jsonrpc.Entrypoint("/api/v1/jsonrpc")

wikipedia = WikipediaQueryRun(api_wrapper=WikipediaAPIWrapper())

entrypoint.add_method_route(wikipedia, name="wikipedia")
#entrypoint.add_method_route(wikipedia.invoke, name="wikipedia")

This runs into some long stack trace. Need some help on what is the right way to do.

  File "/app/functions/langchain_wikipedia.py", line 8, in <module>
    entrypoint.add_method_route(wikipedia.invoke, name="wikipedia")
  File "/lib/python3.10/site-packages/fastapi_jsonrpc/__init__.py", line 1317, in add_method_route
    route = self.method_route_class(
  File "/lib/python3.10/site-packages/fastapi_jsonrpc/__init__.py", line 713, in __init__
    _Request = make_request_model(name, func.__module__, flat_dependant.body_params)
  File "/lib/python3.10/site-packages/fastapi_jsonrpc/__init__.py", line 508, in make_request_model
    _JsonRpcRequestParams = create_model(
  File "/lib/python3.10/site-packages/pydantic/main.py", line 1570, in create_model
    return meta(
  File "/lib/python3.10/site-packages/pydantic/_internal/_model_construction.py", line 205, in __new__
    complete_model_class(
  File "/lib/python3.10/site-packages/pydantic/_internal/_model_construction.py", line 534, in complete_model_class
    schema = cls.__get_pydantic_core_schema__(cls, handler)
  File "/lib/python3.10/site-packages/pydantic/main.py", line 643, in __get_pydantic_core_schema__
    return handler(source)
  File "/lib/python3.10/site-packages/pydantic/_internal/_schema_generation_shared.py", line 83, in __call__
    schema = self._handler(source_type)
  File "/lib/python3.10/site-packages/pydantic/_internal/_generate_schema.py", line 512, in generate_schema
    schema = self._generate_schema_inner(obj)
  File "/lib/python3.10/site-packages/pydantic/_internal/_generate_schema.py", line 784, in _generate_schema_inner
    return self._model_schema(obj)
  File "/lib/python3.10/site-packages/pydantic/_internal/_generate_schema.py", line 591, in _model_schema
    {k: self._generate_md_field_schema(k, v, decorators) for k, v in fields.items()},
  File "/lib/python3.10/site-packages/pydantic/_internal/_generate_schema.py", line 591, in <dictcomp>
    {k: self._generate_md_field_schema(k, v, decorators) for k, v in fields.items()},
  File "/lib/python3.10/site-packages/pydantic/_internal/_generate_schema.py", line 947, in _generate_md_field_schema
    common_field = self._common_field_schema(name, field_info, decorators)
  File "/lib/python3.10/site-packages/pydantic/_internal/_generate_schema.py", line 1134, in _common_field_schema
    schema = self._apply_annotations(
  File "/lib/python3.10/site-packages/pydantic/_internal/_generate_schema.py", line 1890, in _apply_annotations
    schema = get_inner_schema(source_type)
  File "/lib/python3.10/site-packages/pydantic/_internal/_schema_generation_shared.py", line 83, in __call__
    schema = self._handler(source_type)
  File "/lib/python3.10/site-packages/pydantic/_internal/_generate_schema.py", line 1871, in inner_handler
    schema = self._generate_schema_inner(obj)
  File "/lib/python3.10/site-packages/pydantic/_internal/_generate_schema.py", line 789, in _generate_schema_inner
    return self.match_type(obj)
  File "/lib/python3.10/site-packages/pydantic/_internal/_generate_schema.py", line 871, in match_type
    return self._match_generic_type(obj, origin)
  File "/lib/python3.10/site-packages/pydantic/_internal/_generate_schema.py", line 895, in _match_generic_type
    return self._union_schema(obj)
  File "/lib/python3.10/site-packages/pydantic/_internal/_generate_schema.py", line 1207, in _union_schema
    choices.append(self.generate_schema(arg))
  File "/lib/python3.10/site-packages/pydantic/_internal/_generate_schema.py", line 512, in generate_schema
    schema = self._generate_schema_inner(obj)
  File "/lib/python3.10/site-packages/pydantic/_internal/_generate_schema.py", line 789, in _generate_schema_inner
    return self.match_type(obj)
  File "/lib/python3.10/site-packages/pydantic/_internal/_generate_schema.py", line 837, in match_type
    return self._typed_dict_schema(obj, None)
  File "/lib/python3.10/site-packages/pydantic/_internal/_generate_schema.py", line 1336, in _typed_dict_schema
    fields[field_name] = self._generate_td_field_schema(
  File "/lib/python3.10/site-packages/pydantic/_internal/_generate_schema.py", line 930, in _generate_td_field_schema
    common_field = self._common_field_schema(name, field_info, decorators)
  File "/lib/python3.10/site-packages/pydantic/_internal/_generate_schema.py", line 1134, in _common_field_schema
    schema = self._apply_annotations(
  File "/lib/python3.10/site-packages/pydantic/_internal/_generate_schema.py", line 1890, in _apply_annotations
    schema = get_inner_schema(source_type)
  File "/lib/python3.10/site-packages/pydantic/_internal/_schema_generation_shared.py", line 83, in __call__
    schema = self._handler(source_type)
  File "/lib/python3.10/site-packages/pydantic/_internal/_generate_schema.py", line 1871, in inner_handler
    schema = self._generate_schema_inner(obj)
  File "/lib/python3.10/site-packages/pydantic/_internal/_generate_schema.py", line 789, in _generate_schema_inner
    return self.match_type(obj)
  File "/lib/python3.10/site-packages/pydantic/_internal/_generate_schema.py", line 871, in match_type
    return self._match_generic_type(obj, origin)
  File "/lib/python3.10/site-packages/pydantic/_internal/_generate_schema.py", line 895, in _match_generic_type
    return self._union_schema(obj)
  File "/lib/python3.10/site-packages/pydantic/_internal/_generate_schema.py", line 1207, in _union_schema
    choices.append(self.generate_schema(arg))
  File "/lib/python3.10/site-packages/pydantic/_internal/_generate_schema.py", line 512, in generate_schema
    schema = self._generate_schema_inner(obj)
  File "/lib/python3.10/site-packages/pydantic/_internal/_generate_schema.py", line 789, in _generate_schema_inner
    return self.match_type(obj)
  File "/lib/python3.10/site-packages/pydantic/_internal/_generate_schema.py", line 867, in match_type
    return self._apply_annotations(source_type, annotations)
  File "/lib/python3.10/site-packages/pydantic/_internal/_generate_schema.py", line 1890, in _apply_annotations
    schema = get_inner_schema(source_type)
  File "/lib/python3.10/site-packages/pydantic/_internal/_schema_generation_shared.py", line 83, in __call__
    schema = self._handler(source_type)
  File "/lib/python3.10/site-packages/pydantic/_internal/_generate_schema.py", line 1972, in new_handler
    schema = metadata_get_schema(source, get_inner_schema)
  File "/lib/python3.10/site-packages/pydantic/_internal/_std_types_schema.py", line 316, in __get_pydantic_core_schema__
    items_schema = handler.generate_schema(self.item_source_type)
  File "/lib/python3.10/site-packages/pydantic/_internal/_schema_generation_shared.py", line 97, in generate_schema
    return self._generate_schema.generate_schema(source_type)
  File "/lib/python3.10/site-packages/pydantic/_internal/_generate_schema.py", line 512, in generate_schema
    schema = self._generate_schema_inner(obj)
  File "/lib/python3.10/site-packages/pydantic/_internal/_generate_schema.py", line 789, in _generate_schema_inner
    return self.match_type(obj)
  File "/lib/python3.10/site-packages/pydantic/_internal/_generate_schema.py", line 875, in match_type
    return self._unknown_type_schema(obj)
  File "/lib/python3.10/site-packages/pydantic/_internal/_generate_schema.py", line 415, in _unknown_type_schema
    raise PydanticSchemaGenerationError(
pydantic.errors.PydanticSchemaGenerationError: Unable to generate pydantic-core schema for <class 'langchain_core.callbacks.base.BaseCallbackHandler'>. Set `arbitrary_types_allowed=True` in the model_config to ignore this error or implement `__get_pydantic_core_schema__` on your type to fully support it.

If you got this error by calling handler(<some type>) within `__get_pydantic_core_schema__` then you likely need to call `handler.generate_schema(<some type>)` since we do not call `__get_pydantic_core_schema__` on `<some type>` otherwise to avoid infinite recursion.

For further information visit https://errors.pydantic.dev/2.8/u/schema-for-unknown-type

nethi avatar Jul 27 '24 12:07 nethi