arcade-google-slides 0.1.0__py3-none-any.whl → 1.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.
@@ -2,6 +2,7 @@ from arcade_google_slides.tools import (
2
2
  comment_on_presentation,
3
3
  create_presentation,
4
4
  create_slide,
5
+ generate_google_file_picker_url,
5
6
  get_presentation_as_markdown,
6
7
  list_presentation_comments,
7
8
  search_presentations,
@@ -14,4 +15,5 @@ __all__ = [
14
15
  "search_presentations",
15
16
  "comment_on_presentation",
16
17
  "list_presentation_comments",
18
+ "generate_google_file_picker_url",
17
19
  ]
@@ -3,6 +3,7 @@ from arcade_google_slides.tools.comment import (
3
3
  list_presentation_comments,
4
4
  )
5
5
  from arcade_google_slides.tools.create import create_presentation, create_slide
6
+ from arcade_google_slides.tools.file_picker import generate_google_file_picker_url
6
7
  from arcade_google_slides.tools.get import get_presentation_as_markdown
7
8
  from arcade_google_slides.tools.search import (
8
9
  search_presentations,
@@ -15,4 +16,5 @@ __all__ = [
15
16
  "search_presentations",
16
17
  "comment_on_presentation",
17
18
  "list_presentation_comments",
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
- def generate_google_file_picker_url(context: ToolContext) -> dict:
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
- Generates a URL that directs the end-user to a Google File Picker interface where
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
- Returns:
21
- A dictionary containing the URL and instructions for the llm to instruct the user.
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
- f"This will allow them to select files and grant access permissions: {url}"
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, cast
2
2
 
3
- from arcade_tdk import ToolContext, ToolMetadataKey, tool
3
+ from arcade_tdk import ToolContext, tool
4
4
  from arcade_tdk.auth import Google
5
5
 
6
- from arcade_google_slides.decorators import with_filepicker_fallback
7
6
  from arcade_google_slides.types import Presentation
8
7
  from arcade_google_slides.utils import build_slides_service, convert_presentation_to_markdown
9
8
 
@@ -14,9 +13,7 @@ from arcade_google_slides.utils import build_slides_service, convert_presentatio
14
13
  "https://www.googleapis.com/auth/drive.file",
15
14
  ],
16
15
  ),
17
- requires_metadata=[ToolMetadataKey.CLIENT_ID, ToolMetadataKey.COORDINATOR_URL],
18
16
  )
19
- @with_filepicker_fallback
20
17
  async def get_presentation_as_markdown(
21
18
  context: ToolContext,
22
19
  presentation_id: Annotated[str, "The ID of the presentation to retrieve."],
@@ -1,11 +1,9 @@
1
1
  from typing import Annotated, Any
2
2
 
3
- from arcade_tdk import ToolContext, ToolMetadataKey, tool
3
+ from arcade_tdk import ToolContext, tool
4
4
  from arcade_tdk.auth import Google
5
5
 
6
6
  from arcade_google_slides.enum import OrderBy
7
- from arcade_google_slides.file_picker import generate_google_file_picker_url
8
- from arcade_google_slides.templates import optional_file_picker_instructions_template
9
7
  from arcade_google_slides.utils import (
10
8
  build_drive_service,
11
9
  build_files_list_params,
@@ -20,7 +18,6 @@ from arcade_google_slides.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_presentations(
26
23
  context: ToolContext,
@@ -53,7 +50,9 @@ async def search_presentations(
53
50
  ] = False,
54
51
  order_by: Annotated[
55
52
  list[OrderBy] | None,
56
- "Sort order. Defaults to listing the most recently modified presentations first",
53
+ "Sort order. Defaults to listing the most recently modified presentations first. "
54
+ "If presentation_contains or presentation_not_contains is provided, "
55
+ "then the order_by will be ignored.",
57
56
  ] = None,
58
57
  limit: Annotated[int, "The number of presentations to list"] = 50,
59
58
  pagination_token: Annotated[
@@ -69,7 +68,12 @@ async def search_presentations(
69
68
  Searches for presentations in the user's Google Drive.
70
69
  Excludes presentations that are in the trash.
71
70
  """
72
- if order_by is None:
71
+ if presentation_contains or presentation_not_contains:
72
+ # Google drive API does not support other order_by values for
73
+ # queries with fullText search (which is used when presentation_contains
74
+ # or presentation_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_presentations(
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
  "presentations_count": len(files),
114
114
  "presentations": 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
  "llm_instructions": (
122
116
  "If the results were not satisfactory, then inform the user that "
123
117
  "you can also search across all of their shared drives."
@@ -81,7 +81,7 @@ def convert_presentation_to_markdown(presentation: Presentation) -> str:
81
81
  def build_files_list_params(
82
82
  mime_type: str,
83
83
  page_size: int,
84
- order_by: list[OrderBy],
84
+ order_by: list[OrderBy] | None,
85
85
  pagination_token: str | None,
86
86
  include_shared_drives: bool,
87
87
  search_only_in_shared_drive_id: str | None,
@@ -98,7 +98,7 @@ def build_files_list_params(
98
98
  params = {
99
99
  "q": query,
100
100
  "pageSize": page_size,
101
- "orderBy": ",".join([item.value for item in order_by]),
101
+ "orderBy": ",".join([item.value for item in order_by]) if order_by else None,
102
102
  "pageToken": pagination_token,
103
103
  }
104
104
 
@@ -149,8 +149,8 @@ def build_files_list_query(
149
149
  name_not_contains = keyword.replace("'", "\\'")
150
150
  full_text_not_contains = keyword.replace("'", "\\'")
151
151
  keyword_query = (
152
- f"(name not contains '{name_not_contains}' and "
153
- f"fullText not contains '{full_text_not_contains}')"
152
+ f"(not (name contains '{name_not_contains}' or "
153
+ f"fullText contains '{full_text_not_contains}'))"
154
154
  )
155
155
  query.append(keyword_query)
156
156
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: arcade_google_slides
3
- Version: 0.1.0
3
+ Version: 1.0.0
4
4
  Summary: Arcade.dev LLM tools for Google Slides
5
5
  Author-email: Arcade <dev@arcade.dev>
6
6
  License: Proprietary - Arcade Software License Agreement v1.0
@@ -0,0 +1,15 @@
1
+ arcade_google_slides/__init__.py,sha256=lDbDi5794U-ao476aHyqlymoVBwJAyG938e3TXV4A0c,474
2
+ arcade_google_slides/converters.py,sha256=kKxTeuQX_Q4-QpZWCCKteAMAZ0o2McpaWimxg-6IxHI,9870
3
+ arcade_google_slides/enum.py,sha256=uRBfvSfDpbZaunuA6upPP3GvXArOW8r7k6YYPsa9X9M,5289
4
+ arcade_google_slides/types.py,sha256=osCGae3PXl9U_eA7zqVEA6kcju6W-npXLUlsbJZIuqc,6664
5
+ arcade_google_slides/utils.py,sha256=OA0B7jsD6zn3B6Mpil1uSnv9t0XBqtuOXSBbn9SQ034,5125
6
+ arcade_google_slides/tools/__init__.py,sha256=h35BQ0jxKERBbo-BpNCPJnAksiLO3o9hvpV2NAtBjw8,653
7
+ arcade_google_slides/tools/comment.py,sha256=SCLONR43ZXBHjLFkaNnIbWvxO3qV0tG-li8HkHi1Npk,2960
8
+ arcade_google_slides/tools/create.py,sha256=JbKhvZH5jbj7dFXLdUhm9mHDWYChXQZ66BSilersYMA,3955
9
+ arcade_google_slides/tools/file_picker.py,sha256=Dqn-hfMoTsWyHM8QCakVgHr5TKrzL_1Lj-vYHVGtOW4,2342
10
+ arcade_google_slides/tools/get.py,sha256=i3KKR-0ZouwLRapV87_Y4OmTL2cyXA8ACwaj3FM3ALw,1013
11
+ arcade_google_slides/tools/search.py,sha256=6tnLT5xRQfibrcbqdGQcowhjBxhLjaojKHVjN_274uA,4768
12
+ arcade_google_slides-1.0.0.dist-info/METADATA,sha256=_IzTbF8W7_KIH75KBT1BLASpkDSDVYGjn6n9q477Nok,1190
13
+ arcade_google_slides-1.0.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
14
+ arcade_google_slides-1.0.0.dist-info/licenses/LICENSE,sha256=ixeE7aL9b2B-_ZYHTY1vQcJB4NufKeo-LWwKNObGDN0,1960
15
+ arcade_google_slides-1.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_slides.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,5 +0,0 @@
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 documents via the Google Drive File Picker. "
4
- "The user can pick additional documents via the following link: {url}"
5
- )
@@ -1,17 +0,0 @@
1
- arcade_google_slides/__init__.py,sha256=NJk6XPdTtpKDTdDYxzP_rOVqTxjdfSF0yQVde1KliV0,398
2
- arcade_google_slides/converters.py,sha256=kKxTeuQX_Q4-QpZWCCKteAMAZ0o2McpaWimxg-6IxHI,9870
3
- arcade_google_slides/decorators.py,sha256=SQeS2_fa3UOgUgGiYuY5eugguIyRPvHVc85TSracSZY,753
4
- arcade_google_slides/enum.py,sha256=uRBfvSfDpbZaunuA6upPP3GvXArOW8r7k6YYPsa9X9M,5289
5
- arcade_google_slides/file_picker.py,sha256=kGfUVfH5QVlIW1sL-_gAwPokt7TwVEcPk3Vnk53GKUE,2005
6
- arcade_google_slides/templates.py,sha256=pxbdMj57eV3-ImW3CixDWscpVKS94Z8nTNyTxDhUfGY,283
7
- arcade_google_slides/types.py,sha256=osCGae3PXl9U_eA7zqVEA6kcju6W-npXLUlsbJZIuqc,6664
8
- arcade_google_slides/utils.py,sha256=OBBFKEfGse6ohWSvhF85Cgtzlz3svn8BOMi-RfBigVo,5099
9
- arcade_google_slides/tools/__init__.py,sha256=JMWqB_57Nul0mF6vwSJsqzHp91cimmy9cvqcgM-tacw,531
10
- arcade_google_slides/tools/comment.py,sha256=SCLONR43ZXBHjLFkaNnIbWvxO3qV0tG-li8HkHi1Npk,2960
11
- arcade_google_slides/tools/create.py,sha256=JbKhvZH5jbj7dFXLdUhm9mHDWYChXQZ66BSilersYMA,3955
12
- arcade_google_slides/tools/get.py,sha256=ZqV8gtDJR0I7wMugholR59zCtHfT5CjiaG3kwl9XCZk,1209
13
- arcade_google_slides/tools/search.py,sha256=8S0MhqrgDCuF1kVM48S_GiB8rZWCutCAsdiofAb0b9A,4932
14
- arcade_google_slides-0.1.0.dist-info/METADATA,sha256=S0CxSh8uvoiYFFJPw2fE8BT7lNKf_EOjuqc04oBEAEM,1190
15
- arcade_google_slides-0.1.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
16
- arcade_google_slides-0.1.0.dist-info/licenses/LICENSE,sha256=ixeE7aL9b2B-_ZYHTY1vQcJB4NufKeo-LWwKNObGDN0,1960
17
- arcade_google_slides-0.1.0.dist-info/RECORD,,