llama-index
103 строки · 3.2 Кб
1"""Notion tool spec."""
2
3from typing import Any, Dict, List, Optional, Type
4
5import requests
6
7from llama_index.legacy.bridge.pydantic import BaseModel
8from llama_index.legacy.readers.notion import NotionPageReader
9from llama_index.legacy.tools.tool_spec.base import SPEC_FUNCTION_TYPE, BaseToolSpec
10
11SEARCH_URL = "https://api.notion.com/v1/search"
12
13
14class NotionLoadDataSchema(BaseModel):
15"""Notion load data schema."""
16
17page_ids: Optional[List[str]] = None
18database_id: Optional[str] = None
19
20
21class NotionSearchDataSchema(BaseModel):
22"""Notion search data schema."""
23
24query: str
25direction: Optional[str] = None
26timestamp: Optional[str] = None
27value: Optional[str] = None
28property: Optional[str] = None
29page_size: int = 100
30
31
32class NotionToolSpec(BaseToolSpec):
33"""Notion tool spec.
34
35Currently a simple wrapper around the data loader.
36TODO: add more methods to the Notion spec.
37
38"""
39
40spec_functions = ["load_data", "search_data"]
41
42def __init__(self, integration_token: Optional[str] = None) -> None:
43"""Initialize with parameters."""
44self.reader = NotionPageReader(integration_token=integration_token)
45
46def get_fn_schema_from_fn_name(
47self, fn_name: str, spec_functions: Optional[List[SPEC_FUNCTION_TYPE]] = None
48) -> Optional[Type[BaseModel]]:
49"""Return map from function name."""
50if fn_name == "load_data":
51return NotionLoadDataSchema
52elif fn_name == "search_data":
53return NotionSearchDataSchema
54else:
55raise ValueError(f"Invalid function name: {fn_name}")
56
57def load_data(
58self, page_ids: Optional[List[str]] = None, database_id: Optional[str] = None
59) -> str:
60"""Loads content from a set of page ids or a database id.
61
62Don't use this endpoint if you don't know the page ids or database id.
63
64"""
65page_ids = page_ids or []
66docs = self.reader.load_data(page_ids=page_ids, database_id=database_id)
67return "\n".join([doc.get_content() for doc in docs])
68
69def search_data(
70self,
71query: str,
72direction: Optional[str] = None,
73timestamp: Optional[str] = None,
74value: Optional[str] = None,
75property: Optional[str] = None,
76page_size: int = 100,
77) -> str:
78"""Search a list of relevant pages.
79
80Contains metadata for each page (but not the page content).
81
82"""
83payload: Dict[str, Any] = {
84"query": query,
85"page_size": page_size,
86}
87if direction is not None or timestamp is not None:
88payload["sort"] = {}
89if direction is not None:
90payload["sort"]["direction"] = direction
91if timestamp is not None:
92payload["sort"]["timestamp"] = timestamp
93
94if value is not None or property is not None:
95payload["filter"] = {}
96if value is not None:
97payload["filter"]["value"] = value
98if property is not None:
99payload["filter"]["property"] = property
100
101response = requests.post(SEARCH_URL, json=payload, headers=self.reader.headers)
102response_json = response.json()
103return response_json["results"]
104