arcade-google-sheets 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_sheets/__init__.py +15 -1
- arcade_google_sheets/templates.py +0 -6
- arcade_google_sheets/tools/__init__.py +2 -0
- arcade_google_sheets/{file_picker.py → tools/file_picker.py} +14 -6
- arcade_google_sheets/tools/read.py +1 -6
- arcade_google_sheets/tools/search.py +9 -15
- arcade_google_sheets/utils.py +4 -4
- {arcade_google_sheets-3.1.0.dist-info → arcade_google_sheets-4.0.0.dist-info}/METADATA +1 -1
- arcade_google_sheets-4.0.0.dist-info/RECORD +17 -0
- arcade_google_sheets/decorators.py +0 -24
- arcade_google_sheets-3.1.0.dist-info/RECORD +0 -18
- {arcade_google_sheets-3.1.0.dist-info → arcade_google_sheets-4.0.0.dist-info}/WHEEL +0 -0
- {arcade_google_sheets-3.1.0.dist-info → arcade_google_sheets-4.0.0.dist-info}/licenses/LICENSE +0 -0
arcade_google_sheets/__init__.py
CHANGED
|
@@ -1,7 +1,21 @@
|
|
|
1
1
|
from arcade_google_sheets.tools import (
|
|
2
|
+
add_note_to_cell,
|
|
2
3
|
create_spreadsheet,
|
|
4
|
+
generate_google_file_picker_url,
|
|
3
5
|
get_spreadsheet,
|
|
6
|
+
get_spreadsheet_metadata,
|
|
7
|
+
search_spreadsheets,
|
|
8
|
+
update_cells,
|
|
4
9
|
write_to_cell,
|
|
5
10
|
)
|
|
6
11
|
|
|
7
|
-
__all__ = [
|
|
12
|
+
__all__ = [
|
|
13
|
+
"create_spreadsheet",
|
|
14
|
+
"get_spreadsheet",
|
|
15
|
+
"write_to_cell",
|
|
16
|
+
"generate_google_file_picker_url",
|
|
17
|
+
"get_spreadsheet_metadata",
|
|
18
|
+
"search_spreadsheets",
|
|
19
|
+
"update_cells",
|
|
20
|
+
"add_note_to_cell",
|
|
21
|
+
]
|
|
@@ -1,8 +1,2 @@
|
|
|
1
|
-
optional_file_picker_instructions_template = (
|
|
2
|
-
"Ensure the user knows that they have the option to select and grant access permissions to "
|
|
3
|
-
"additional files and folders via the Google Drive File Picker. "
|
|
4
|
-
"The user can pick additional files and folders via the following link: {url}"
|
|
5
|
-
)
|
|
6
|
-
|
|
7
1
|
spreadsheet_url_template = "https://docs.google.com/spreadsheets/d/{spreadsheet_id}/edit"
|
|
8
2
|
sheet_url_template = "https://docs.google.com/spreadsheets/d/{spreadsheet_id}/edit#gid={sheet_id}"
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
from arcade_google_sheets.tools.file_picker import generate_google_file_picker_url
|
|
1
2
|
from arcade_google_sheets.tools.read import get_spreadsheet, get_spreadsheet_metadata
|
|
2
3
|
from arcade_google_sheets.tools.search import search_spreadsheets
|
|
3
4
|
from arcade_google_sheets.tools.write import (
|
|
@@ -15,4 +16,5 @@ __all__ = [
|
|
|
15
16
|
"update_cells",
|
|
16
17
|
"add_note_to_cell",
|
|
17
18
|
"write_to_cell",
|
|
19
|
+
"generate_google_file_picker_url",
|
|
18
20
|
]
|
|
@@ -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
|
}
|
|
@@ -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_sheets.decorators import with_filepicker_fallback
|
|
7
6
|
from arcade_google_sheets.templates import sheet_url_template
|
|
8
7
|
from arcade_google_sheets.utils import (
|
|
9
8
|
build_sheets_service,
|
|
@@ -18,9 +17,7 @@ from arcade_google_sheets.utils import (
|
|
|
18
17
|
requires_auth=Google(
|
|
19
18
|
scopes=["https://www.googleapis.com/auth/drive.file"],
|
|
20
19
|
),
|
|
21
|
-
requires_metadata=[ToolMetadataKey.CLIENT_ID, ToolMetadataKey.COORDINATOR_URL],
|
|
22
20
|
)
|
|
23
|
-
@with_filepicker_fallback
|
|
24
21
|
async def get_spreadsheet(
|
|
25
22
|
context: ToolContext,
|
|
26
23
|
spreadsheet_id: Annotated[str, "The id of the spreadsheet to get"],
|
|
@@ -90,9 +87,7 @@ async def get_spreadsheet(
|
|
|
90
87
|
requires_auth=Google(
|
|
91
88
|
scopes=["https://www.googleapis.com/auth/drive.file"],
|
|
92
89
|
),
|
|
93
|
-
requires_metadata=[ToolMetadataKey.CLIENT_ID, ToolMetadataKey.COORDINATOR_URL],
|
|
94
90
|
)
|
|
95
|
-
@with_filepicker_fallback
|
|
96
91
|
async def get_spreadsheet_metadata(
|
|
97
92
|
context: ToolContext,
|
|
98
93
|
spreadsheet_id: Annotated[str, "The id of the spreadsheet to get metadata for"],
|
|
@@ -1,12 +1,10 @@
|
|
|
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_sheets.enums import OrderBy
|
|
7
|
-
from arcade_google_sheets.file_picker import generate_google_file_picker_url
|
|
8
7
|
from arcade_google_sheets.templates import (
|
|
9
|
-
optional_file_picker_instructions_template,
|
|
10
8
|
spreadsheet_url_template,
|
|
11
9
|
)
|
|
12
10
|
from arcade_google_sheets.utils import (
|
|
@@ -20,7 +18,6 @@ from arcade_google_sheets.utils import (
|
|
|
20
18
|
requires_auth=Google(
|
|
21
19
|
scopes=["https://www.googleapis.com/auth/drive.file"],
|
|
22
20
|
),
|
|
23
|
-
requires_metadata=[ToolMetadataKey.CLIENT_ID, ToolMetadataKey.COORDINATOR_URL],
|
|
24
21
|
)
|
|
25
22
|
async def search_spreadsheets(
|
|
26
23
|
context: ToolContext,
|
|
@@ -53,7 +50,9 @@ async def search_spreadsheets(
|
|
|
53
50
|
] = False,
|
|
54
51
|
order_by: Annotated[
|
|
55
52
|
list[OrderBy] | None,
|
|
56
|
-
"Sort order. Defaults to listing the most recently modified spreadsheets first"
|
|
53
|
+
"Sort order. Defaults to listing the most recently modified spreadsheets first. "
|
|
54
|
+
"If spreadsheet_contains or spreadsheet_not_contains is provided, "
|
|
55
|
+
"then the order_by will be ignored.",
|
|
57
56
|
] = None,
|
|
58
57
|
limit: Annotated[
|
|
59
58
|
int, "The maximum number of spreadsheets to list. Defaults to 10. Max is 50"
|
|
@@ -73,6 +72,11 @@ async def search_spreadsheets(
|
|
|
73
72
|
Does not return the content/data of the sheets in the spreadsheets - only the metadata.
|
|
74
73
|
Excludes spreadsheets that are in the trash.
|
|
75
74
|
"""
|
|
75
|
+
if spreadsheet_contains or spreadsheet_not_contains:
|
|
76
|
+
# Google drive API does not support other order_by values for
|
|
77
|
+
# queries with fullText search (which is used when spreadsheet_contains
|
|
78
|
+
# or spreadsheet_not_contains is provided).
|
|
79
|
+
order_by = None
|
|
76
80
|
if order_by is None:
|
|
77
81
|
order_by = [OrderBy.MODIFIED_TIME_DESC]
|
|
78
82
|
elif isinstance(order_by, OrderBy):
|
|
@@ -114,20 +118,10 @@ async def search_spreadsheets(
|
|
|
114
118
|
for spreadsheet in spreadsheets:
|
|
115
119
|
spreadsheet["url"] = spreadsheet_url_template.format(spreadsheet_id=spreadsheet["id"])
|
|
116
120
|
|
|
117
|
-
file_picker_response = generate_google_file_picker_url(
|
|
118
|
-
context,
|
|
119
|
-
)
|
|
120
|
-
|
|
121
121
|
tool_response = {
|
|
122
122
|
"pagination_token": pagination_token,
|
|
123
123
|
"spreadsheets_count": len(spreadsheets),
|
|
124
124
|
"spreadsheets": spreadsheets,
|
|
125
|
-
"file_picker": {
|
|
126
|
-
"url": file_picker_response["url"],
|
|
127
|
-
"llm_instructions": optional_file_picker_instructions_template.format(
|
|
128
|
-
url=file_picker_response["url"]
|
|
129
|
-
),
|
|
130
|
-
},
|
|
131
125
|
}
|
|
132
126
|
tool_response = remove_none_values(tool_response)
|
|
133
127
|
|
arcade_google_sheets/utils.py
CHANGED
|
@@ -971,8 +971,8 @@ def build_files_list_query(
|
|
|
971
971
|
name_not_contains = keyword.replace("'", "\\'")
|
|
972
972
|
full_text_not_contains = keyword.replace("'", "\\'")
|
|
973
973
|
keyword_query = (
|
|
974
|
-
f"(name
|
|
975
|
-
f"fullText
|
|
974
|
+
f"(not (name contains '{name_not_contains}' or "
|
|
975
|
+
f"fullText contains '{full_text_not_contains}'))"
|
|
976
976
|
)
|
|
977
977
|
query.append(keyword_query)
|
|
978
978
|
|
|
@@ -982,7 +982,7 @@ def build_files_list_query(
|
|
|
982
982
|
def build_files_list_params(
|
|
983
983
|
mime_type: str,
|
|
984
984
|
page_size: int,
|
|
985
|
-
order_by: list[OrderBy],
|
|
985
|
+
order_by: list[OrderBy] | None,
|
|
986
986
|
pagination_token: str | None,
|
|
987
987
|
include_shared_drives: bool,
|
|
988
988
|
search_only_in_shared_drive_id: str | None,
|
|
@@ -999,7 +999,7 @@ def build_files_list_params(
|
|
|
999
999
|
params = {
|
|
1000
1000
|
"q": query,
|
|
1001
1001
|
"pageSize": page_size,
|
|
1002
|
-
"orderBy": ",".join([item.value for item in order_by]),
|
|
1002
|
+
"orderBy": ",".join([item.value for item in order_by]) if order_by else None,
|
|
1003
1003
|
"pageToken": pagination_token,
|
|
1004
1004
|
}
|
|
1005
1005
|
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
arcade_google_sheets/__init__.py,sha256=asCX32sPK-bi2HRpWZSlLd7dRKy7Uztqxwu-eoXTY1g,466
|
|
2
|
+
arcade_google_sheets/constants.py,sha256=4tQOrQ1YagSklJSSw5Eq21XCcFCJdO7lso5SqWIdrPI,63
|
|
3
|
+
arcade_google_sheets/converters.py,sha256=1muE_28Jk0eyFUzoVo_lN0_qy3z-uv7f5XoZLH9mitQ,3924
|
|
4
|
+
arcade_google_sheets/enums.py,sha256=30OMPu2l_aUjz8kQzC1mR5w0lLbs0fZn8T6PDtoXpL4,4608
|
|
5
|
+
arcade_google_sheets/models.py,sha256=xwPdwUis0OHTDbSLy85qWl7zIh2lDTi5HZMNKwdZjzo,8627
|
|
6
|
+
arcade_google_sheets/templates.py,sha256=hSvjiErERLPe6RqWY6QNmivOy7Ofdg_zABcLWCI-ByU,189
|
|
7
|
+
arcade_google_sheets/types.py,sha256=R-rCRcyFqDZx3jgl_kWeCliqC8fHuZ8ub_LQ2KoU2AE,37
|
|
8
|
+
arcade_google_sheets/utils.py,sha256=VmDZOzAOEtfSPOra-ieVl_U16RLonQUOnZ4RW4Gf-oA,34895
|
|
9
|
+
arcade_google_sheets/tools/__init__.py,sha256=ZUhznD9qcK0cdaFM05I2eA2SCpY2nD4ou2_zUR8rHek,594
|
|
10
|
+
arcade_google_sheets/tools/file_picker.py,sha256=Dqn-hfMoTsWyHM8QCakVgHr5TKrzL_1Lj-vYHVGtOW4,2342
|
|
11
|
+
arcade_google_sheets/tools/read.py,sha256=qQX_TdcbPbkuaHPuhx7CzWsWJ_a97FSCDJqOlGHF_TM,4003
|
|
12
|
+
arcade_google_sheets/tools/search.py,sha256=olCaUwDqW26yaYqMT5lPmQDFL6M9g7qON7JG3mcgYJM,4841
|
|
13
|
+
arcade_google_sheets/tools/write.py,sha256=4kNx941PQt6VUGTogbepnbfUdcsVze6u5c8QvlNnWCI,7782
|
|
14
|
+
arcade_google_sheets-4.0.0.dist-info/METADATA,sha256=qDIQQqgbsYxUsqvmpNS7Om8xx9yC3HO_LfLA4uAbcYs,1123
|
|
15
|
+
arcade_google_sheets-4.0.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
16
|
+
arcade_google_sheets-4.0.0.dist-info/licenses/LICENSE,sha256=ixeE7aL9b2B-_ZYHTY1vQcJB4NufKeo-LWwKNObGDN0,1960
|
|
17
|
+
arcade_google_sheets-4.0.0.dist-info/RECORD,,
|
|
@@ -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_sheets.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,18 +0,0 @@
|
|
|
1
|
-
arcade_google_sheets/__init__.py,sha256=FB9h_cws_gu3UJp32GWlqvBQyAOb77JfAJNSSBqz-Jk,177
|
|
2
|
-
arcade_google_sheets/constants.py,sha256=4tQOrQ1YagSklJSSw5Eq21XCcFCJdO7lso5SqWIdrPI,63
|
|
3
|
-
arcade_google_sheets/converters.py,sha256=1muE_28Jk0eyFUzoVo_lN0_qy3z-uv7f5XoZLH9mitQ,3924
|
|
4
|
-
arcade_google_sheets/decorators.py,sha256=QMqfvSXaFBoxYJrz69EGeMdAxF0V7JPReVXfp73Nf3Y,753
|
|
5
|
-
arcade_google_sheets/enums.py,sha256=30OMPu2l_aUjz8kQzC1mR5w0lLbs0fZn8T6PDtoXpL4,4608
|
|
6
|
-
arcade_google_sheets/file_picker.py,sha256=kGfUVfH5QVlIW1sL-_gAwPokt7TwVEcPk3Vnk53GKUE,2005
|
|
7
|
-
arcade_google_sheets/models.py,sha256=xwPdwUis0OHTDbSLy85qWl7zIh2lDTi5HZMNKwdZjzo,8627
|
|
8
|
-
arcade_google_sheets/templates.py,sha256=p3ty6Kwo7l73EEsZTaRfdG4jzQ9XvlqqeXMLKB1ydEw,489
|
|
9
|
-
arcade_google_sheets/types.py,sha256=R-rCRcyFqDZx3jgl_kWeCliqC8fHuZ8ub_LQ2KoU2AE,37
|
|
10
|
-
arcade_google_sheets/utils.py,sha256=GHCGQYA8W8eR-78KcVgflz_D98OKMgjulYFuoR9iJAo,34869
|
|
11
|
-
arcade_google_sheets/tools/__init__.py,sha256=IiSd-0Q4_uxeKI8nVMT3JVRoF5G5GB8e5Z9SkGpSnt8,472
|
|
12
|
-
arcade_google_sheets/tools/read.py,sha256=g7uGhyhFNlDPHKT3xhg7NdMaSYuvzzefSzrb1XqiI80,4309
|
|
13
|
-
arcade_google_sheets/tools/search.py,sha256=q6sI4qUcg0dGiLrTQa6AbpRvsljW9LbL8gCa96ZD-aQ,4975
|
|
14
|
-
arcade_google_sheets/tools/write.py,sha256=4kNx941PQt6VUGTogbepnbfUdcsVze6u5c8QvlNnWCI,7782
|
|
15
|
-
arcade_google_sheets-3.1.0.dist-info/METADATA,sha256=FcyWZ3Wvr2wuFU4L7w8zlrTWl9iPvGN0AkkkqS6HGqQ,1123
|
|
16
|
-
arcade_google_sheets-3.1.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
17
|
-
arcade_google_sheets-3.1.0.dist-info/licenses/LICENSE,sha256=ixeE7aL9b2B-_ZYHTY1vQcJB4NufKeo-LWwKNObGDN0,1960
|
|
18
|
-
arcade_google_sheets-3.1.0.dist-info/RECORD,,
|
|
File without changes
|
{arcade_google_sheets-3.1.0.dist-info → arcade_google_sheets-4.0.0.dist-info}/licenses/LICENSE
RENAMED
|
File without changes
|