arcade-google-docs 3.1.0__py3-none-any.whl → 4.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- arcade_google_docs/__init__.py +2 -0
- arcade_google_docs/tools/__init__.py +2 -0
- arcade_google_docs/{file_picker.py → tools/file_picker.py} +14 -6
- arcade_google_docs/tools/get.py +1 -4
- arcade_google_docs/tools/search.py +10 -27
- arcade_google_docs/tools/update.py +1 -4
- arcade_google_docs/utils.py +4 -4
- {arcade_google_docs-3.1.0.dist-info → arcade_google_docs-4.0.0.dist-info}/METADATA +1 -1
- arcade_google_docs-4.0.0.dist-info/RECORD +16 -0
- arcade_google_docs/decorators.py +0 -24
- arcade_google_docs-3.1.0.dist-info/RECORD +0 -17
- {arcade_google_docs-3.1.0.dist-info → arcade_google_docs-4.0.0.dist-info}/WHEEL +0 -0
arcade_google_docs/__init__.py
CHANGED
|
@@ -2,6 +2,7 @@ from arcade_google_docs.tools import (
|
|
|
2
2
|
comment_on_document,
|
|
3
3
|
create_blank_document,
|
|
4
4
|
create_document_from_text,
|
|
5
|
+
generate_google_file_picker_url,
|
|
5
6
|
get_document_by_id,
|
|
6
7
|
insert_text_at_end_of_document,
|
|
7
8
|
list_document_comments,
|
|
@@ -18,4 +19,5 @@ __all__ = [
|
|
|
18
19
|
"insert_text_at_end_of_document",
|
|
19
20
|
"search_and_retrieve_documents",
|
|
20
21
|
"search_documents",
|
|
22
|
+
"generate_google_file_picker_url",
|
|
21
23
|
]
|
|
@@ -6,6 +6,7 @@ from arcade_google_docs.tools.create import (
|
|
|
6
6
|
create_blank_document,
|
|
7
7
|
create_document_from_text,
|
|
8
8
|
)
|
|
9
|
+
from arcade_google_docs.tools.file_picker import generate_google_file_picker_url
|
|
9
10
|
from arcade_google_docs.tools.get import get_document_by_id
|
|
10
11
|
from arcade_google_docs.tools.search import (
|
|
11
12
|
search_and_retrieve_documents,
|
|
@@ -22,4 +23,5 @@ __all__ = [
|
|
|
22
23
|
"insert_text_at_end_of_document",
|
|
23
24
|
"search_and_retrieve_documents",
|
|
24
25
|
"search_documents",
|
|
26
|
+
"generate_google_file_picker_url",
|
|
25
27
|
]
|
|
@@ -1,14 +1,22 @@
|
|
|
1
1
|
import base64
|
|
2
2
|
import json
|
|
3
|
+
from typing import Annotated
|
|
3
4
|
|
|
4
|
-
from arcade_tdk import ToolContext, ToolMetadataKey
|
|
5
|
+
from arcade_tdk import ToolContext, ToolMetadataKey, tool
|
|
6
|
+
from arcade_tdk.auth import Google
|
|
5
7
|
from arcade_tdk.errors import ToolExecutionError
|
|
6
8
|
|
|
7
9
|
|
|
8
|
-
|
|
10
|
+
@tool(
|
|
11
|
+
requires_auth=Google(),
|
|
12
|
+
requires_metadata=[ToolMetadataKey.CLIENT_ID, ToolMetadataKey.COORDINATOR_URL],
|
|
13
|
+
)
|
|
14
|
+
def generate_google_file_picker_url(
|
|
15
|
+
context: ToolContext,
|
|
16
|
+
) -> Annotated[dict, "Google File Picker URL for user file selection and permission granting"]:
|
|
9
17
|
"""Generate a Google File Picker URL for user-driven file selection and authorization.
|
|
10
18
|
|
|
11
|
-
|
|
19
|
+
This tool generates a URL that directs the end-user to a Google File Picker interface where
|
|
12
20
|
where they can select or upload Google Drive files. Users can grant permission to access their
|
|
13
21
|
Drive files, providing a secure and authorized way to interact with their files.
|
|
14
22
|
|
|
@@ -17,8 +25,8 @@ def generate_google_file_picker_url(context: ToolContext) -> dict:
|
|
|
17
25
|
(Requested entity was not found) or permission errors. Once the user completes the file
|
|
18
26
|
picker flow, the prior tool can be retried.
|
|
19
27
|
|
|
20
|
-
|
|
21
|
-
|
|
28
|
+
Suggest this tool to users when they are surprised or confused that the file they are
|
|
29
|
+
searching for or attempting to access cannot be found.
|
|
22
30
|
"""
|
|
23
31
|
client_id = context.get_metadata(ToolMetadataKey.CLIENT_ID)
|
|
24
32
|
client_id_parts = client_id.split("-")
|
|
@@ -44,6 +52,6 @@ def generate_google_file_picker_url(context: ToolContext) -> dict:
|
|
|
44
52
|
"url": url,
|
|
45
53
|
"llm_instructions": (
|
|
46
54
|
"Instruct the user to click the following link to open the Google Drive File Picker. "
|
|
47
|
-
|
|
55
|
+
"This will allow them to select files and grant access permissions: {url}"
|
|
48
56
|
),
|
|
49
57
|
}
|
arcade_google_docs/tools/get.py
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
from typing import Annotated
|
|
2
2
|
|
|
3
|
-
from arcade_tdk import ToolContext,
|
|
3
|
+
from arcade_tdk import ToolContext, tool
|
|
4
4
|
from arcade_tdk.auth import Google
|
|
5
5
|
|
|
6
|
-
from arcade_google_docs.decorators import with_filepicker_fallback
|
|
7
6
|
from arcade_google_docs.utils import build_docs_service
|
|
8
7
|
|
|
9
8
|
|
|
@@ -16,9 +15,7 @@ from arcade_google_docs.utils import build_docs_service
|
|
|
16
15
|
"https://www.googleapis.com/auth/drive.file",
|
|
17
16
|
],
|
|
18
17
|
),
|
|
19
|
-
requires_metadata=[ToolMetadataKey.CLIENT_ID, ToolMetadataKey.COORDINATOR_URL],
|
|
20
18
|
)
|
|
21
|
-
@with_filepicker_fallback
|
|
22
19
|
async def get_document_by_id(
|
|
23
20
|
context: ToolContext,
|
|
24
21
|
document_id: Annotated[str, "The ID of the document to retrieve."],
|
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
from typing import Annotated, Any
|
|
2
2
|
|
|
3
|
-
from arcade_tdk import ToolContext,
|
|
3
|
+
from arcade_tdk import ToolContext, tool
|
|
4
4
|
from arcade_tdk.auth import Google
|
|
5
5
|
|
|
6
6
|
from arcade_google_docs.doc_to_html import convert_document_to_html
|
|
7
7
|
from arcade_google_docs.doc_to_markdown import convert_document_to_markdown
|
|
8
8
|
from arcade_google_docs.enum import DocumentFormat, OrderBy
|
|
9
|
-
from arcade_google_docs.file_picker import generate_google_file_picker_url
|
|
10
|
-
from arcade_google_docs.templates import optional_file_picker_instructions_template
|
|
11
9
|
from arcade_google_docs.tools import get_document_by_id
|
|
12
10
|
from arcade_google_docs.utils import (
|
|
13
11
|
build_drive_service,
|
|
@@ -23,7 +21,6 @@ from arcade_google_docs.utils import (
|
|
|
23
21
|
requires_auth=Google(
|
|
24
22
|
scopes=["https://www.googleapis.com/auth/drive.file"],
|
|
25
23
|
),
|
|
26
|
-
requires_metadata=[ToolMetadataKey.CLIENT_ID, ToolMetadataKey.COORDINATOR_URL],
|
|
27
24
|
)
|
|
28
25
|
async def search_documents(
|
|
29
26
|
context: ToolContext,
|
|
@@ -55,7 +52,9 @@ async def search_documents(
|
|
|
55
52
|
] = False,
|
|
56
53
|
order_by: Annotated[
|
|
57
54
|
list[OrderBy] | None,
|
|
58
|
-
"Sort order. Defaults to listing the most recently modified documents first"
|
|
55
|
+
"Sort order. Defaults to listing the most recently modified documents first. If "
|
|
56
|
+
"document_contains or document_not_contains is provided, "
|
|
57
|
+
"then the order_by will be ignored.",
|
|
59
58
|
] = None,
|
|
60
59
|
limit: Annotated[int, "The number of documents to list"] = 50,
|
|
61
60
|
pagination_token: Annotated[
|
|
@@ -69,7 +68,12 @@ async def search_documents(
|
|
|
69
68
|
"""
|
|
70
69
|
Searches for documents in the user's Google Drive. Excludes documents that are in the trash.
|
|
71
70
|
"""
|
|
72
|
-
if
|
|
71
|
+
if document_contains or document_not_contains:
|
|
72
|
+
# Google drive API does not support other order_by values for
|
|
73
|
+
# queries with fullText search (which is used when document_contains
|
|
74
|
+
# or document_not_contains is provided).
|
|
75
|
+
order_by = None
|
|
76
|
+
elif order_by is None:
|
|
73
77
|
order_by = [OrderBy.MODIFIED_TIME_DESC]
|
|
74
78
|
elif isinstance(order_by, OrderBy):
|
|
75
79
|
order_by = [order_by]
|
|
@@ -105,19 +109,9 @@ async def search_documents(
|
|
|
105
109
|
if not pagination_token or len(batch) < page_size:
|
|
106
110
|
break
|
|
107
111
|
|
|
108
|
-
file_picker_response = generate_google_file_picker_url(
|
|
109
|
-
context,
|
|
110
|
-
)
|
|
111
|
-
|
|
112
112
|
return {
|
|
113
113
|
"documents_count": len(files),
|
|
114
114
|
"documents": files,
|
|
115
|
-
"file_picker": {
|
|
116
|
-
"url": file_picker_response["url"],
|
|
117
|
-
"llm_instructions": optional_file_picker_instructions_template.format(
|
|
118
|
-
url=file_picker_response["url"]
|
|
119
|
-
),
|
|
120
|
-
},
|
|
121
115
|
}
|
|
122
116
|
|
|
123
117
|
|
|
@@ -125,7 +119,6 @@ async def search_documents(
|
|
|
125
119
|
requires_auth=Google(
|
|
126
120
|
scopes=["https://www.googleapis.com/auth/drive.file"],
|
|
127
121
|
),
|
|
128
|
-
requires_metadata=[ToolMetadataKey.CLIENT_ID, ToolMetadataKey.COORDINATOR_URL],
|
|
129
122
|
)
|
|
130
123
|
async def search_and_retrieve_documents(
|
|
131
124
|
context: ToolContext,
|
|
@@ -203,17 +196,7 @@ async def search_and_retrieve_documents(
|
|
|
203
196
|
|
|
204
197
|
documents.append(document)
|
|
205
198
|
|
|
206
|
-
file_picker_response = generate_google_file_picker_url(
|
|
207
|
-
context,
|
|
208
|
-
)
|
|
209
|
-
|
|
210
199
|
return {
|
|
211
200
|
"documents_count": len(documents),
|
|
212
201
|
"documents": documents,
|
|
213
|
-
"file_picker": {
|
|
214
|
-
"url": file_picker_response["url"],
|
|
215
|
-
"llm_instructions": optional_file_picker_instructions_template.format(
|
|
216
|
-
url=file_picker_response["url"]
|
|
217
|
-
),
|
|
218
|
-
},
|
|
219
202
|
}
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
from typing import Annotated
|
|
2
2
|
|
|
3
|
-
from arcade_tdk import ToolContext,
|
|
3
|
+
from arcade_tdk import ToolContext, tool
|
|
4
4
|
from arcade_tdk.auth import Google
|
|
5
5
|
|
|
6
|
-
from arcade_google_docs.decorators import with_filepicker_fallback
|
|
7
6
|
from arcade_google_docs.tools.get import get_document_by_id
|
|
8
7
|
from arcade_google_docs.utils import build_docs_service
|
|
9
8
|
|
|
@@ -16,9 +15,7 @@ from arcade_google_docs.utils import build_docs_service
|
|
|
16
15
|
"https://www.googleapis.com/auth/drive.file",
|
|
17
16
|
],
|
|
18
17
|
),
|
|
19
|
-
requires_metadata=[ToolMetadataKey.CLIENT_ID, ToolMetadataKey.COORDINATOR_URL],
|
|
20
18
|
)
|
|
21
|
-
@with_filepicker_fallback
|
|
22
19
|
async def insert_text_at_end_of_document(
|
|
23
20
|
context: ToolContext,
|
|
24
21
|
document_id: Annotated[str, "The ID of the document to update."],
|
arcade_google_docs/utils.py
CHANGED
|
@@ -34,7 +34,7 @@ def build_drive_service(auth_token: str | None) -> Resource: # type: ignore[no-
|
|
|
34
34
|
def build_files_list_params(
|
|
35
35
|
mime_type: str,
|
|
36
36
|
page_size: int,
|
|
37
|
-
order_by: list[OrderBy],
|
|
37
|
+
order_by: list[OrderBy] | None,
|
|
38
38
|
pagination_token: str | None,
|
|
39
39
|
include_shared_drives: bool,
|
|
40
40
|
search_only_in_shared_drive_id: str | None,
|
|
@@ -51,7 +51,7 @@ def build_files_list_params(
|
|
|
51
51
|
params = {
|
|
52
52
|
"q": query,
|
|
53
53
|
"pageSize": page_size,
|
|
54
|
-
"orderBy": ",".join([item.value for item in order_by]),
|
|
54
|
+
"orderBy": ",".join([item.value for item in order_by]) if order_by else None,
|
|
55
55
|
"pageToken": pagination_token,
|
|
56
56
|
}
|
|
57
57
|
|
|
@@ -102,8 +102,8 @@ def build_files_list_query(
|
|
|
102
102
|
name_not_contains = keyword.replace("'", "\\'")
|
|
103
103
|
full_text_not_contains = keyword.replace("'", "\\'")
|
|
104
104
|
keyword_query = (
|
|
105
|
-
f"(name
|
|
106
|
-
f"fullText
|
|
105
|
+
f"(not (name contains '{name_not_contains}' or "
|
|
106
|
+
f"fullText contains '{full_text_not_contains}'))"
|
|
107
107
|
)
|
|
108
108
|
query.append(keyword_query)
|
|
109
109
|
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
arcade_google_docs/__init__.py,sha256=nZoMwH9HWZLpfNMIioUXLDlZ7QDR-E4C1_8hySt_CkU,604
|
|
2
|
+
arcade_google_docs/doc_to_html.py,sha256=6RTpzRSrazNa6AndLZhA20wgVDzZuHUqpu3WAkAsbjQ,3146
|
|
3
|
+
arcade_google_docs/doc_to_markdown.py,sha256=eT-sc6ruxN8nEtUm9mBHFOWXajEBTTXkxsn6XsLHIxo,2020
|
|
4
|
+
arcade_google_docs/enum.py,sha256=vFJWPe1JPG6I9xqdVVvuaEeen4LvvtJxax1sDYeh4UU,3421
|
|
5
|
+
arcade_google_docs/templates.py,sha256=pxbdMj57eV3-ImW3CixDWscpVKS94Z8nTNyTxDhUfGY,283
|
|
6
|
+
arcade_google_docs/utils.py,sha256=XMgKcWPWKy8SbH3y2eCil01hssHhUgYxVrwXyvHEU4A,3748
|
|
7
|
+
arcade_google_docs/tools/__init__.py,sha256=s0FS3z-uXE4lQH06YhnUKgIOT-Kq-v6rQMqXUGdPDnw,827
|
|
8
|
+
arcade_google_docs/tools/comment.py,sha256=Qm5NHdNHONs3j4gqbZ7Fw9NrTVBb_mZ-th1X-z2IoLM,2836
|
|
9
|
+
arcade_google_docs/tools/create.py,sha256=AuYy8yMGscrxAdLJQX0WiisGHCTufSlaRu_QGMMKQmM,2764
|
|
10
|
+
arcade_google_docs/tools/file_picker.py,sha256=Dqn-hfMoTsWyHM8QCakVgHr5TKrzL_1Lj-vYHVGtOW4,2342
|
|
11
|
+
arcade_google_docs/tools/get.py,sha256=tCByk1-C97Mdo9P3oDdr--6bXD1dIQ3FxsDxptCJaA8,1145
|
|
12
|
+
arcade_google_docs/tools/search.py,sha256=JpaOvcn3a6MjJEAqtne4vfiq4SvlINCw6lKv6nWt3zc,8035
|
|
13
|
+
arcade_google_docs/tools/update.py,sha256=_dReYit0s7ykn2bYQEUwohl3D_63U5leF87egO4eEiQ,1836
|
|
14
|
+
arcade_google_docs-4.0.0.dist-info/METADATA,sha256=lQakZrQRnTWx8Qa_vGbSwGxFOiVAMebNYVaSghfAGsw,1097
|
|
15
|
+
arcade_google_docs-4.0.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
16
|
+
arcade_google_docs-4.0.0.dist-info/RECORD,,
|
arcade_google_docs/decorators.py
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import functools
|
|
2
|
-
from collections.abc import Callable
|
|
3
|
-
from typing import Any
|
|
4
|
-
|
|
5
|
-
from arcade_tdk import ToolContext
|
|
6
|
-
from googleapiclient.errors import HttpError
|
|
7
|
-
|
|
8
|
-
from arcade_google_docs.file_picker import generate_google_file_picker_url
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
def with_filepicker_fallback(func: Callable[..., Any]) -> Callable[..., Any]:
|
|
12
|
-
""" """
|
|
13
|
-
|
|
14
|
-
@functools.wraps(func)
|
|
15
|
-
async def async_wrapper(context: ToolContext, *args: Any, **kwargs: Any) -> Any:
|
|
16
|
-
try:
|
|
17
|
-
return await func(context, *args, **kwargs)
|
|
18
|
-
except HttpError as e:
|
|
19
|
-
if e.status_code in [403, 404]:
|
|
20
|
-
file_picker_response = generate_google_file_picker_url(context)
|
|
21
|
-
return file_picker_response
|
|
22
|
-
raise
|
|
23
|
-
|
|
24
|
-
return async_wrapper
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
arcade_google_docs/__init__.py,sha256=J3c3lEuqb86UE5zScpv7Gd4TltmzTUq_tWyA2Ff0gmI,528
|
|
2
|
-
arcade_google_docs/decorators.py,sha256=5ONZ3vS2lZBmog5c1TcuWjyPDeftBPAJ7vXyLjSPFRk,751
|
|
3
|
-
arcade_google_docs/doc_to_html.py,sha256=6RTpzRSrazNa6AndLZhA20wgVDzZuHUqpu3WAkAsbjQ,3146
|
|
4
|
-
arcade_google_docs/doc_to_markdown.py,sha256=eT-sc6ruxN8nEtUm9mBHFOWXajEBTTXkxsn6XsLHIxo,2020
|
|
5
|
-
arcade_google_docs/enum.py,sha256=vFJWPe1JPG6I9xqdVVvuaEeen4LvvtJxax1sDYeh4UU,3421
|
|
6
|
-
arcade_google_docs/file_picker.py,sha256=kGfUVfH5QVlIW1sL-_gAwPokt7TwVEcPk3Vnk53GKUE,2005
|
|
7
|
-
arcade_google_docs/templates.py,sha256=pxbdMj57eV3-ImW3CixDWscpVKS94Z8nTNyTxDhUfGY,283
|
|
8
|
-
arcade_google_docs/utils.py,sha256=Eku4b1olLcXfQ20liE9m3iPWvy60VA62tQ8TFwRKn94,3722
|
|
9
|
-
arcade_google_docs/tools/__init__.py,sha256=vtn_NKrYwgWsdgcDYBY4t8m_XF73jB4j7zrpt-NC-dI,707
|
|
10
|
-
arcade_google_docs/tools/comment.py,sha256=Qm5NHdNHONs3j4gqbZ7Fw9NrTVBb_mZ-th1X-z2IoLM,2836
|
|
11
|
-
arcade_google_docs/tools/create.py,sha256=AuYy8yMGscrxAdLJQX0WiisGHCTufSlaRu_QGMMKQmM,2764
|
|
12
|
-
arcade_google_docs/tools/get.py,sha256=2wi9ZF9s_57mMbIGgsqr53Fr0AJyrYVOQ11x7nAyk8Y,1339
|
|
13
|
-
arcade_google_docs/tools/search.py,sha256=_CaEs1A_qGToNPeuGQ2yN3phGtPD7fFQbW3UqZr_qpg,8617
|
|
14
|
-
arcade_google_docs/tools/update.py,sha256=9SvffQIHnmYiEgyE1VrhXG2aHb0hIfWYPzPLc4nTdKI,2030
|
|
15
|
-
arcade_google_docs-3.1.0.dist-info/METADATA,sha256=X1ZvXVVYgg2tp5KfpnXlDc0bsQJw3GugfPWOIQ7ZTF4,1097
|
|
16
|
-
arcade_google_docs-3.1.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
17
|
-
arcade_google_docs-3.1.0.dist-info/RECORD,,
|
|
File without changes
|