mirror of
https://github.com/hwchase17/langchain.git
synced 2026-02-06 01:00:22 +00:00
Compare commits
3 Commits
cc/remove_
...
langchain-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b525226531 | ||
|
|
0fc50b82a0 | ||
|
|
21bfc95e14 |
@@ -115,7 +115,7 @@
|
||||
"\n",
|
||||
"PROMPT_TEMPLATE = \"\"\"Given an input question, create a syntactically correct Elasticsearch query to run. Unless the user specifies in their question a specific number of examples they wish to obtain, always limit your query to at most {top_k} results. You can order the results by a relevant column to return the most interesting examples in the database.\n",
|
||||
"\n",
|
||||
"Unless told to do not query for all the columns from a specific index, only ask for a the few relevant columns given the question.\n",
|
||||
"Unless told to do not query for all the columns from a specific index, only ask for a few relevant columns given the question.\n",
|
||||
"\n",
|
||||
"Pay attention to use only the column names that you can see in the mapping description. Be careful to not query for columns that do not exist. Also, pay attention to which column is in which index. Return the query as valid json.\n",
|
||||
"\n",
|
||||
|
||||
@@ -233,7 +233,7 @@ Question: {input}"""
|
||||
|
||||
_DEFAULT_TEMPLATE = """Given an input question, first create a syntactically correct {dialect} query to run, then look at the results of the query and return the answer. Unless the user specifies in his question a specific number of examples he wishes to obtain, always limit your query to at most {top_k} results. You can order the results by a relevant column to return the most interesting examples in the database.
|
||||
|
||||
Never query for all the columns from a specific table, only ask for a the few relevant columns given the question.
|
||||
Never query for all the columns from a specific table, only ask for a few relevant columns given the question.
|
||||
|
||||
Pay attention to use only the column names that you can see in the schema description. Be careful to not query for columns that do not exist. Also, pay attention to which column is in which table.
|
||||
|
||||
|
||||
@@ -551,7 +551,7 @@
|
||||
"\n",
|
||||
"While a parser encapsulates the logic needed to parse binary data into documents, *blob loaders* encapsulate the logic that's necessary to load blobs from a given storage location.\n",
|
||||
"\n",
|
||||
"A the moment, `LangChain` only supports `FileSystemBlobLoader`.\n",
|
||||
"At the moment, `LangChain` only supports `FileSystemBlobLoader`.\n",
|
||||
"\n",
|
||||
"You can use the `FileSystemBlobLoader` to load blobs and then use the parser to parse them."
|
||||
]
|
||||
|
||||
@@ -329,7 +329,7 @@
|
||||
"id": "fc6059fd-0df7-4b6f-a84c-b5874e983638",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"We can also pass in an arbitrary function or a runnable. This function/runnable should take in a the graph state and output a list of messages.\n",
|
||||
"We can also pass in an arbitrary function or a runnable. This function/runnable should take in a graph state and output a list of messages.\n",
|
||||
"We can do all types of arbitrary formatting of messages here. In this case, let's add a SystemMessage to the start of the list of messages and append another user message at the end."
|
||||
]
|
||||
},
|
||||
|
||||
@@ -221,7 +221,7 @@
|
||||
"source": [
|
||||
"## JSONFormer LLM Wrapper\n",
|
||||
"\n",
|
||||
"Let's try that again, now providing a the Action input's JSON Schema to the model."
|
||||
"Let's try that again, now providing the Action input's JSON Schema to the model."
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
"\n",
|
||||
"In many Q&A applications we want to allow the user to have a back-and-forth conversation, meaning the application needs some sort of \"memory\" of past questions and answers, and some logic for incorporating those into its current thinking.\n",
|
||||
"\n",
|
||||
"This is a the second part of a multi-part tutorial:\n",
|
||||
"This is the second part of a multi-part tutorial:\n",
|
||||
"\n",
|
||||
"- [Part 1](/docs/tutorials/rag) introduces RAG and walks through a minimal implementation.\n",
|
||||
"- [Part 2](/docs/tutorials/qa_chat_history) (this guide) extends the implementation to accommodate conversation-style interactions and multi-step retrieval processes.\n",
|
||||
|
||||
@@ -459,6 +459,12 @@ class ChildTool(BaseTool):
|
||||
@property
|
||||
def tool_call_schema(self) -> ArgsSchema:
|
||||
if isinstance(self.args_schema, dict):
|
||||
if self.description:
|
||||
return {
|
||||
**self.args_schema,
|
||||
"description": self.description,
|
||||
}
|
||||
|
||||
return self.args_schema
|
||||
|
||||
full_schema = self.get_input_schema()
|
||||
|
||||
@@ -5,7 +5,7 @@ from pydantic import BaseModel, Field, create_model
|
||||
|
||||
from langchain_core.callbacks import Callbacks
|
||||
from langchain_core.runnables import Runnable
|
||||
from langchain_core.tools.base import BaseTool
|
||||
from langchain_core.tools.base import ArgsSchema, BaseTool
|
||||
from langchain_core.tools.simple import Tool
|
||||
from langchain_core.tools.structured import StructuredTool
|
||||
|
||||
@@ -13,8 +13,9 @@ from langchain_core.tools.structured import StructuredTool
|
||||
@overload
|
||||
def tool(
|
||||
*,
|
||||
description: Optional[str] = None,
|
||||
return_direct: bool = False,
|
||||
args_schema: Optional[type] = None,
|
||||
args_schema: Optional[ArgsSchema] = None,
|
||||
infer_schema: bool = True,
|
||||
response_format: Literal["content", "content_and_artifact"] = "content",
|
||||
parse_docstring: bool = False,
|
||||
@@ -27,8 +28,9 @@ def tool(
|
||||
name_or_callable: str,
|
||||
runnable: Runnable,
|
||||
*,
|
||||
description: Optional[str] = None,
|
||||
return_direct: bool = False,
|
||||
args_schema: Optional[type] = None,
|
||||
args_schema: Optional[ArgsSchema] = None,
|
||||
infer_schema: bool = True,
|
||||
response_format: Literal["content", "content_and_artifact"] = "content",
|
||||
parse_docstring: bool = False,
|
||||
@@ -40,8 +42,9 @@ def tool(
|
||||
def tool(
|
||||
name_or_callable: Callable,
|
||||
*,
|
||||
description: Optional[str] = None,
|
||||
return_direct: bool = False,
|
||||
args_schema: Optional[type] = None,
|
||||
args_schema: Optional[ArgsSchema] = None,
|
||||
infer_schema: bool = True,
|
||||
response_format: Literal["content", "content_and_artifact"] = "content",
|
||||
parse_docstring: bool = False,
|
||||
@@ -53,8 +56,9 @@ def tool(
|
||||
def tool(
|
||||
name_or_callable: str,
|
||||
*,
|
||||
description: Optional[str] = None,
|
||||
return_direct: bool = False,
|
||||
args_schema: Optional[type] = None,
|
||||
args_schema: Optional[ArgsSchema] = None,
|
||||
infer_schema: bool = True,
|
||||
response_format: Literal["content", "content_and_artifact"] = "content",
|
||||
parse_docstring: bool = False,
|
||||
@@ -66,8 +70,9 @@ def tool(
|
||||
name_or_callable: Optional[Union[str, Callable]] = None,
|
||||
runnable: Optional[Runnable] = None,
|
||||
*args: Any,
|
||||
description: Optional[str] = None,
|
||||
return_direct: bool = False,
|
||||
args_schema: Optional[type] = None,
|
||||
args_schema: Optional[ArgsSchema] = None,
|
||||
infer_schema: bool = True,
|
||||
response_format: Literal["content", "content_and_artifact"] = "content",
|
||||
parse_docstring: bool = False,
|
||||
@@ -83,6 +88,14 @@ def tool(
|
||||
converted to a tool. Must be provided as a positional argument.
|
||||
runnable: Optional runnable to convert to a tool. Must be provided as a
|
||||
positional argument.
|
||||
description: Optional description for the tool.
|
||||
Precedence for the tool description value is as follows:
|
||||
- `description` argument
|
||||
(used even if docstring and/or `args_schema` are provided)
|
||||
- tool function docstring
|
||||
(used even if `args_schema` is provided)
|
||||
- `args_schema` description
|
||||
(used only if `description` / docstring are not provided)
|
||||
return_direct: Whether to return directly from the tool rather
|
||||
than continuing the agent loop. Defaults to False.
|
||||
args_schema: optional argument schema for user to specify.
|
||||
@@ -213,6 +226,7 @@ def tool(
|
||||
"""
|
||||
|
||||
def _tool_factory(dec_func: Union[Callable, Runnable]) -> BaseTool:
|
||||
tool_description = description
|
||||
if isinstance(dec_func, Runnable):
|
||||
runnable = dec_func
|
||||
|
||||
@@ -232,25 +246,23 @@ def tool(
|
||||
|
||||
coroutine = ainvoke_wrapper
|
||||
func = invoke_wrapper
|
||||
schema: Optional[type[BaseModel]] = runnable.input_schema
|
||||
description = repr(runnable)
|
||||
schema: Optional[ArgsSchema] = runnable.input_schema
|
||||
tool_description = description or repr(runnable)
|
||||
elif inspect.iscoroutinefunction(dec_func):
|
||||
coroutine = dec_func
|
||||
func = None
|
||||
schema = args_schema
|
||||
description = None
|
||||
else:
|
||||
coroutine = None
|
||||
func = dec_func
|
||||
schema = args_schema
|
||||
description = None
|
||||
|
||||
if infer_schema or args_schema is not None:
|
||||
return StructuredTool.from_function(
|
||||
func,
|
||||
coroutine,
|
||||
name=tool_name,
|
||||
description=description,
|
||||
description=tool_description,
|
||||
return_direct=return_direct,
|
||||
args_schema=schema,
|
||||
infer_schema=infer_schema,
|
||||
|
||||
@@ -27,6 +27,7 @@ from langchain_core.tools.base import (
|
||||
_get_runnable_config_param,
|
||||
create_schema_from_function,
|
||||
)
|
||||
from langchain_core.utils.pydantic import is_basemodel_subclass
|
||||
|
||||
|
||||
class StructuredTool(BaseTool):
|
||||
@@ -188,7 +189,16 @@ class StructuredTool(BaseTool):
|
||||
if description is None and not parse_docstring:
|
||||
description_ = source_function.__doc__ or None
|
||||
if description_ is None and args_schema:
|
||||
description_ = args_schema.__doc__ or None
|
||||
if isinstance(args_schema, type) and is_basemodel_subclass(args_schema):
|
||||
description_ = args_schema.__doc__ or None
|
||||
elif isinstance(args_schema, dict):
|
||||
description_ = args_schema.get("description")
|
||||
else:
|
||||
msg = (
|
||||
"Invalid args_schema: expected BaseModel or dict, "
|
||||
f"got {args_schema}"
|
||||
)
|
||||
raise TypeError(msg)
|
||||
if description_ is None:
|
||||
msg = "Function must have a docstring if description not provided."
|
||||
raise ValueError(msg)
|
||||
|
||||
@@ -17,7 +17,7 @@ dependencies = [
|
||||
"pydantic<3.0.0,>=2.7.4; python_full_version >= \"3.12.4\"",
|
||||
]
|
||||
name = "langchain-core"
|
||||
version = "0.3.39"
|
||||
version = "0.3.40"
|
||||
description = "Building applications with LLMs through composability"
|
||||
readme = "README.md"
|
||||
|
||||
|
||||
@@ -52,6 +52,7 @@ from langchain_core.tools import (
|
||||
tool,
|
||||
)
|
||||
from langchain_core.tools.base import (
|
||||
ArgsSchema,
|
||||
InjectedToolArg,
|
||||
InjectedToolCallId,
|
||||
SchemaAnnotationError,
|
||||
@@ -199,7 +200,7 @@ def test_decorator_with_specified_schema() -> None:
|
||||
assert isinstance(tool_func, BaseTool)
|
||||
assert tool_func.args_schema == _MockSchema
|
||||
|
||||
@tool(args_schema=_MockSchemaV1)
|
||||
@tool(args_schema=cast(ArgsSchema, _MockSchemaV1))
|
||||
def tool_func_v1(arg1: int, arg2: bool, arg3: Optional[dict] = None) -> str:
|
||||
return f"{arg1} {arg2} {arg3}"
|
||||
|
||||
@@ -2398,10 +2399,10 @@ def test_structured_tool_args_schema_dict() -> None:
|
||||
"required": ["a", "b"],
|
||||
"title": "add",
|
||||
"type": "object",
|
||||
"description": "add two numbers",
|
||||
}
|
||||
tool = StructuredTool(
|
||||
name="add",
|
||||
description="add two numbers",
|
||||
args_schema=args_schema,
|
||||
func=lambda a, b: a + b,
|
||||
)
|
||||
@@ -2433,6 +2434,7 @@ def test_simple_tool_args_schema_dict() -> None:
|
||||
"required": ["a"],
|
||||
"title": "square",
|
||||
"type": "object",
|
||||
"description": "square a number",
|
||||
}
|
||||
tool = Tool(
|
||||
name="square",
|
||||
@@ -2468,3 +2470,93 @@ def test_empty_string_tool_call_id() -> None:
|
||||
assert foo.invoke({"type": "tool_call", "args": {"x": 0}, "id": ""}) == ToolMessage(
|
||||
content="hi", name="foo", tool_call_id=""
|
||||
)
|
||||
|
||||
|
||||
def test_tool_decorator_description() -> None:
|
||||
# test basic tool
|
||||
@tool
|
||||
def foo(x: int) -> str:
|
||||
"""Foo."""
|
||||
return "hi"
|
||||
|
||||
assert foo.description == "Foo."
|
||||
assert (
|
||||
cast(BaseModel, foo.tool_call_schema).model_json_schema()["description"]
|
||||
== "Foo."
|
||||
)
|
||||
|
||||
# test basic tool with description
|
||||
@tool(description="description")
|
||||
def foo_description(x: int) -> str:
|
||||
"""Foo."""
|
||||
return "hi"
|
||||
|
||||
assert foo_description.description == "description"
|
||||
assert (
|
||||
cast(BaseModel, foo_description.tool_call_schema).model_json_schema()[
|
||||
"description"
|
||||
]
|
||||
== "description"
|
||||
)
|
||||
|
||||
# test tool with args schema
|
||||
class ArgsSchema(BaseModel):
|
||||
"""Bar."""
|
||||
|
||||
x: int
|
||||
|
||||
@tool(args_schema=ArgsSchema)
|
||||
def foo_args_schema(x: int) -> str:
|
||||
return "hi"
|
||||
|
||||
assert foo_args_schema.description == "Bar."
|
||||
assert (
|
||||
cast(BaseModel, foo_args_schema.tool_call_schema).model_json_schema()[
|
||||
"description"
|
||||
]
|
||||
== "Bar."
|
||||
)
|
||||
|
||||
@tool(description="description", args_schema=ArgsSchema)
|
||||
def foo_args_schema_description(x: int) -> str:
|
||||
return "hi"
|
||||
|
||||
assert foo_args_schema_description.description == "description"
|
||||
assert (
|
||||
cast(
|
||||
BaseModel, foo_args_schema_description.tool_call_schema
|
||||
).model_json_schema()["description"]
|
||||
== "description"
|
||||
)
|
||||
|
||||
args_json_schema = {
|
||||
"description": "JSON Schema.",
|
||||
"properties": {
|
||||
"x": {"description": "my field", "title": "X", "type": "string"}
|
||||
},
|
||||
"required": ["x"],
|
||||
"title": "my_tool",
|
||||
"type": "object",
|
||||
}
|
||||
|
||||
@tool(args_schema=args_json_schema)
|
||||
def foo_args_jsons_schema(x: int) -> str:
|
||||
return "hi"
|
||||
|
||||
@tool(description="description", args_schema=args_json_schema)
|
||||
def foo_args_jsons_schema_with_description(x: int) -> str:
|
||||
return "hi"
|
||||
|
||||
assert foo_args_jsons_schema.description == "JSON Schema."
|
||||
assert (
|
||||
cast(dict, foo_args_jsons_schema.tool_call_schema)["description"]
|
||||
== "JSON Schema."
|
||||
)
|
||||
|
||||
assert foo_args_jsons_schema_with_description.description == "description"
|
||||
assert (
|
||||
cast(dict, foo_args_jsons_schema_with_description.tool_call_schema)[
|
||||
"description"
|
||||
]
|
||||
== "description"
|
||||
)
|
||||
|
||||
@@ -9,7 +9,7 @@ ESQuery:"""
|
||||
|
||||
DEFAULT_DSL_TEMPLATE = """Given an input question, create a syntactically correct Elasticsearch query to run. Unless the user specifies in their question a specific number of examples they wish to obtain, always limit your query to at most {top_k} results. You can order the results by a relevant column to return the most interesting examples in the database.
|
||||
|
||||
Unless told to do not query for all the columns from a specific index, only ask for a the few relevant columns given the question.
|
||||
Unless told to do not query for all the columns from a specific index, only ask for a few relevant columns given the question.
|
||||
|
||||
Pay attention to use only the column names that you can see in the mapping description. Be careful to not query for columns that do not exist. Also, pay attention to which column is in which index. Return the query as valid json.
|
||||
|
||||
|
||||
@@ -5,12 +5,14 @@ import re
|
||||
from collections import defaultdict
|
||||
from typing import TYPE_CHECKING, Any, Callable, Dict, List, Optional, Tuple, Union
|
||||
|
||||
import requests
|
||||
from langchain_core._api import deprecated
|
||||
from langchain_core.callbacks import CallbackManagerForChainRun
|
||||
from langchain_core.language_models import BaseLanguageModel
|
||||
from langchain_core.output_parsers.openai_functions import JsonOutputFunctionsParser
|
||||
from langchain_core.prompts import BasePromptTemplate, ChatPromptTemplate
|
||||
from langchain_core.utils.input import get_colored_text
|
||||
from requests import Response
|
||||
|
||||
from langchain.chains.base import Chain
|
||||
from langchain.chains.llm import LLMChain
|
||||
@@ -19,7 +21,6 @@ from langchain.chains.sequential import SequentialChain
|
||||
if TYPE_CHECKING:
|
||||
from langchain_community.utilities.openapi import OpenAPISpec
|
||||
from openapi_pydantic import Parameter
|
||||
from requests import Response
|
||||
|
||||
|
||||
def _get_description(o: Any, prefer_short: bool) -> Optional[str]:
|
||||
@@ -174,12 +175,6 @@ def openapi_spec_to_openai_fn(
|
||||
params: Optional[dict] = None,
|
||||
**kwargs: Any,
|
||||
) -> Any:
|
||||
try:
|
||||
import requests
|
||||
except ImportError as e:
|
||||
raise ImportError(
|
||||
"Could not import requests, please install with `pip install requests`."
|
||||
) from e
|
||||
method = _name_to_call_map[name]["method"]
|
||||
url = _name_to_call_map[name]["url"]
|
||||
path_params = fn_args.pop("path_params", {})
|
||||
|
||||
@@ -10,7 +10,7 @@ Question: {input}"""
|
||||
|
||||
_DEFAULT_TEMPLATE = """Given an input question, first create a syntactically correct {dialect} query to run, then look at the results of the query and return the answer. Unless the user specifies in his question a specific number of examples he wishes to obtain, always limit your query to at most {top_k} results. You can order the results by a relevant column to return the most interesting examples in the database.
|
||||
|
||||
Never query for all the columns from a specific table, only ask for a the few relevant columns given the question.
|
||||
Never query for all the columns from a specific table, only ask for a few relevant columns given the question.
|
||||
|
||||
Pay attention to use only the column names that you can see in the schema description. Be careful to not query for columns that do not exist. Also, pay attention to which column is in which table.
|
||||
|
||||
|
||||
@@ -46,6 +46,7 @@ from langsmith.evaluation import (
|
||||
from langsmith.run_helpers import as_runnable, is_traceable_function
|
||||
from langsmith.schemas import Dataset, DataType, Example, Run, TracerSession
|
||||
from langsmith.utils import LangSmithError
|
||||
from requests import HTTPError
|
||||
from typing_extensions import TypedDict
|
||||
|
||||
from langchain.chains.base import Chain
|
||||
@@ -971,12 +972,6 @@ def _prepare_eval_run(
|
||||
tags: Optional[List[str]] = None,
|
||||
dataset_version: Optional[Union[str, datetime]] = None,
|
||||
) -> Tuple[MCF, TracerSession, Dataset, List[Example]]:
|
||||
try:
|
||||
from requests import HTTPError
|
||||
except ImportError as e:
|
||||
raise ImportError(
|
||||
"Could not import requests, please install with `pip install requests`."
|
||||
) from e
|
||||
wrapped_model = _wrap_in_chain_factory(llm_or_chain_factory, dataset_name)
|
||||
dataset = client.read_dataset(dataset_name=dataset_name)
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ dependencies = [
|
||||
"langsmith<0.4,>=0.1.17",
|
||||
"pydantic<3.0.0,>=2.7.4",
|
||||
"SQLAlchemy<3,>=1.4",
|
||||
"requests<3,>=2",
|
||||
"PyYAML>=5.3",
|
||||
"numpy<2,>=1.26.4; python_version < \"3.12\"",
|
||||
"numpy<3,>=1.26.2; python_version >= \"3.12\"",
|
||||
@@ -73,7 +74,6 @@ test = [
|
||||
"langchain-openai",
|
||||
"toml>=0.10.2",
|
||||
"packaging>=24.2",
|
||||
"requests<3,>=2",
|
||||
]
|
||||
codespell = ["codespell<3.0.0,>=2.2.0"]
|
||||
test_integration = [
|
||||
@@ -102,7 +102,6 @@ typing = [
|
||||
"mypy-protobuf<4.0.0,>=3.0.0",
|
||||
"langchain-core",
|
||||
"langchain-text-splitters",
|
||||
"requests<3,>=2",
|
||||
]
|
||||
dev = [
|
||||
"jupyter<2.0.0,>=1.0.0",
|
||||
|
||||
6
libs/langchain/uv.lock
generated
6
libs/langchain/uv.lock
generated
@@ -2251,6 +2251,7 @@ dependencies = [
|
||||
{ name = "numpy", version = "2.2.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" },
|
||||
{ name = "pydantic" },
|
||||
{ name = "pyyaml" },
|
||||
{ name = "requests" },
|
||||
{ name = "sqlalchemy" },
|
||||
]
|
||||
|
||||
@@ -2338,7 +2339,6 @@ test = [
|
||||
{ name = "pytest-socket" },
|
||||
{ name = "pytest-watcher" },
|
||||
{ name = "pytest-xdist" },
|
||||
{ name = "requests" },
|
||||
{ name = "requests-mock" },
|
||||
{ name = "responses" },
|
||||
{ name = "syrupy" },
|
||||
@@ -2359,7 +2359,6 @@ typing = [
|
||||
{ name = "langchain-text-splitters" },
|
||||
{ name = "mypy" },
|
||||
{ name = "mypy-protobuf" },
|
||||
{ name = "requests" },
|
||||
{ name = "types-chardet" },
|
||||
{ name = "types-pytz" },
|
||||
{ name = "types-pyyaml" },
|
||||
@@ -2394,6 +2393,7 @@ requires-dist = [
|
||||
{ name = "numpy", marker = "python_full_version >= '3.12'", specifier = ">=1.26.2,<3" },
|
||||
{ name = "pydantic", specifier = ">=2.7.4,<3.0.0" },
|
||||
{ name = "pyyaml", specifier = ">=5.3" },
|
||||
{ name = "requests", specifier = ">=2,<3" },
|
||||
{ name = "sqlalchemy", specifier = ">=1.4,<3" },
|
||||
]
|
||||
|
||||
@@ -2432,7 +2432,6 @@ test = [
|
||||
{ name = "pytest-socket", specifier = ">=0.6.0,<1.0.0" },
|
||||
{ name = "pytest-watcher", specifier = ">=0.2.6,<1.0.0" },
|
||||
{ name = "pytest-xdist", specifier = ">=3.6.1,<4.0.0" },
|
||||
{ name = "requests", specifier = ">=2,<3" },
|
||||
{ name = "requests-mock", specifier = ">=1.11.0,<2.0.0" },
|
||||
{ name = "responses", specifier = ">=0.22.0,<1.0.0" },
|
||||
{ name = "syrupy", specifier = ">=4.0.2,<5.0.0" },
|
||||
@@ -2453,7 +2452,6 @@ typing = [
|
||||
{ name = "langchain-text-splitters", editable = "../text-splitters" },
|
||||
{ name = "mypy", specifier = ">=1.10,<2.0" },
|
||||
{ name = "mypy-protobuf", specifier = ">=3.0.0,<4.0.0" },
|
||||
{ name = "requests", specifier = ">=2,<3" },
|
||||
{ name = "types-chardet", specifier = ">=5.0.4.6,<6.0.0.0" },
|
||||
{ name = "types-pytz", specifier = ">=2023.3.0.0,<2024.0.0.0" },
|
||||
{ name = "types-pyyaml", specifier = ">=6.0.12.2,<7.0.0.0" },
|
||||
|
||||
Reference in New Issue
Block a user