workspace-mcp 1.0.0__py3-none-any.whl → 1.0.2__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.
gforms/forms_tools.py CHANGED
@@ -13,12 +13,14 @@ from googleapiclient.errors import HttpError
13
13
 
14
14
  from auth.service_decorator import require_google_service
15
15
  from core.server import server
16
+ from core.utils import handle_http_errors
16
17
 
17
18
  logger = logging.getLogger(__name__)
18
19
 
19
20
 
20
21
  @server.tool()
21
22
  @require_google_service("forms", "forms")
23
+ @handle_http_errors("create_form")
22
24
  async def create_form(
23
25
  service,
24
26
  user_google_email: str,
@@ -40,42 +42,34 @@ async def create_form(
40
42
  """
41
43
  logger.info(f"[create_form] Invoked. Email: '{user_google_email}', Title: {title}")
42
44
 
43
- try:
44
- form_body: Dict[str, Any] = {
45
- "info": {
46
- "title": title
47
- }
45
+ form_body: Dict[str, Any] = {
46
+ "info": {
47
+ "title": title
48
48
  }
49
+ }
50
+
51
+ if description:
52
+ form_body["info"]["description"] = description
49
53
 
50
- if description:
51
- form_body["info"]["description"] = description
52
-
53
- if document_title:
54
- form_body["info"]["document_title"] = document_title
55
-
56
- created_form = await asyncio.to_thread(
57
- service.forms().create(body=form_body).execute
58
- )
54
+ if document_title:
55
+ form_body["info"]["document_title"] = document_title
59
56
 
60
- form_id = created_form.get("formId")
61
- edit_url = f"https://docs.google.com/forms/d/{form_id}/edit"
62
- responder_url = created_form.get("responderUri", f"https://docs.google.com/forms/d/{form_id}/viewform")
63
-
64
- confirmation_message = f"Successfully created form '{created_form.get('info', {}).get('title', title)}' for {user_google_email}. Form ID: {form_id}. Edit URL: {edit_url}. Responder URL: {responder_url}"
65
- logger.info(f"Form created successfully for {user_google_email}. ID: {form_id}")
66
- return confirmation_message
67
- except HttpError as error:
68
- message = f"API error creating form: {error}. You might need to re-authenticate. LLM: Try 'start_google_auth' with the user's email ({user_google_email}) and service_name='Google Forms'."
69
- logger.error(message, exc_info=True)
70
- raise Exception(message)
71
- except Exception as e:
72
- message = f"Unexpected error creating form: {e}."
73
- logger.exception(message)
74
- raise Exception(message)
57
+ created_form = await asyncio.to_thread(
58
+ service.forms().create(body=form_body).execute
59
+ )
60
+
61
+ form_id = created_form.get("formId")
62
+ edit_url = f"https://docs.google.com/forms/d/{form_id}/edit"
63
+ responder_url = created_form.get("responderUri", f"https://docs.google.com/forms/d/{form_id}/viewform")
64
+
65
+ confirmation_message = f"Successfully created form '{created_form.get('info', {}).get('title', title)}' for {user_google_email}. Form ID: {form_id}. Edit URL: {edit_url}. Responder URL: {responder_url}"
66
+ logger.info(f"Form created successfully for {user_google_email}. ID: {form_id}")
67
+ return confirmation_message
75
68
 
76
69
 
77
70
  @server.tool()
78
71
  @require_google_service("forms", "forms")
72
+ @handle_http_errors("get_form")
79
73
  async def get_form(
80
74
  service,
81
75
  user_google_email: str,
@@ -93,30 +87,29 @@ async def get_form(
93
87
  """
94
88
  logger.info(f"[get_form] Invoked. Email: '{user_google_email}', Form ID: {form_id}")
95
89
 
96
- try:
97
- form = await asyncio.to_thread(
98
- service.forms().get(formId=form_id).execute
99
- )
100
-
101
- form_info = form.get("info", {})
102
- title = form_info.get("title", "No Title")
103
- description = form_info.get("description", "No Description")
104
- document_title = form_info.get("documentTitle", title)
105
-
106
- edit_url = f"https://docs.google.com/forms/d/{form_id}/edit"
107
- responder_url = form.get("responderUri", f"https://docs.google.com/forms/d/{form_id}/viewform")
108
-
109
- items = form.get("items", [])
110
- questions_summary = []
111
- for i, item in enumerate(items, 1):
112
- item_title = item.get("title", f"Question {i}")
113
- item_type = item.get("questionItem", {}).get("question", {}).get("required", False)
114
- required_text = " (Required)" if item_type else ""
115
- questions_summary.append(f" {i}. {item_title}{required_text}")
116
-
117
- questions_text = "\n".join(questions_summary) if questions_summary else " No questions found"
118
-
119
- result = f"""Form Details for {user_google_email}:
90
+ form = await asyncio.to_thread(
91
+ service.forms().get(formId=form_id).execute
92
+ )
93
+
94
+ form_info = form.get("info", {})
95
+ title = form_info.get("title", "No Title")
96
+ description = form_info.get("description", "No Description")
97
+ document_title = form_info.get("documentTitle", title)
98
+
99
+ edit_url = f"https://docs.google.com/forms/d/{form_id}/edit"
100
+ responder_url = form.get("responderUri", f"https://docs.google.com/forms/d/{form_id}/viewform")
101
+
102
+ items = form.get("items", [])
103
+ questions_summary = []
104
+ for i, item in enumerate(items, 1):
105
+ item_title = item.get("title", f"Question {i}")
106
+ item_type = item.get("questionItem", {}).get("question", {}).get("required", False)
107
+ required_text = " (Required)" if item_type else ""
108
+ questions_summary.append(f" {i}. {item_title}{required_text}")
109
+
110
+ questions_text = "\n".join(questions_summary) if questions_summary else " No questions found"
111
+
112
+ result = f"""Form Details for {user_google_email}:
120
113
  - Title: "{title}"
121
114
  - Description: "{description}"
122
115
  - Document Title: "{document_title}"
@@ -125,21 +118,14 @@ async def get_form(
125
118
  - Responder URL: {responder_url}
126
119
  - Questions ({len(items)} total):
127
120
  {questions_text}"""
128
-
129
- logger.info(f"Successfully retrieved form for {user_google_email}. ID: {form_id}")
130
- return result
131
- except HttpError as error:
132
- message = f"API error getting form: {error}. You might need to re-authenticate. LLM: Try 'start_google_auth' with the user's email ({user_google_email}) and service_name='Google Forms'."
133
- logger.error(message, exc_info=True)
134
- raise Exception(message)
135
- except Exception as e:
136
- message = f"Unexpected error getting form: {e}."
137
- logger.exception(message)
138
- raise Exception(message)
121
+
122
+ logger.info(f"Successfully retrieved form for {user_google_email}. ID: {form_id}")
123
+ return result
139
124
 
140
125
 
141
126
  @server.tool()
142
127
  @require_google_service("forms", "forms")
128
+ @handle_http_errors("set_publish_settings")
143
129
  async def set_publish_settings(
144
130
  service,
145
131
  user_google_email: str,
@@ -161,31 +147,23 @@ async def set_publish_settings(
161
147
  """
162
148
  logger.info(f"[set_publish_settings] Invoked. Email: '{user_google_email}', Form ID: {form_id}")
163
149
 
164
- try:
165
- settings_body = {
166
- "publishAsTemplate": publish_as_template,
167
- "requireAuthentication": require_authentication
168
- }
150
+ settings_body = {
151
+ "publishAsTemplate": publish_as_template,
152
+ "requireAuthentication": require_authentication
153
+ }
169
154
 
170
- await asyncio.to_thread(
171
- service.forms().setPublishSettings(formId=form_id, body=settings_body).execute
172
- )
155
+ await asyncio.to_thread(
156
+ service.forms().setPublishSettings(formId=form_id, body=settings_body).execute
157
+ )
173
158
 
174
- confirmation_message = f"Successfully updated publish settings for form {form_id} for {user_google_email}. Publish as template: {publish_as_template}, Require authentication: {require_authentication}"
175
- logger.info(f"Publish settings updated successfully for {user_google_email}. Form ID: {form_id}")
176
- return confirmation_message
177
- except HttpError as error:
178
- message = f"API error updating publish settings: {error}. You might need to re-authenticate. LLM: Try 'start_google_auth' with the user's email ({user_google_email}) and service_name='Google Forms'."
179
- logger.error(message, exc_info=True)
180
- raise Exception(message)
181
- except Exception as e:
182
- message = f"Unexpected error updating publish settings: {e}."
183
- logger.exception(message)
184
- raise Exception(message)
159
+ confirmation_message = f"Successfully updated publish settings for form {form_id} for {user_google_email}. Publish as template: {publish_as_template}, Require authentication: {require_authentication}"
160
+ logger.info(f"Publish settings updated successfully for {user_google_email}. Form ID: {form_id}")
161
+ return confirmation_message
185
162
 
186
163
 
187
164
  @server.tool()
188
165
  @require_google_service("forms", "forms")
166
+ @handle_http_errors("get_form_response")
189
167
  async def get_form_response(
190
168
  service,
191
169
  user_google_email: str,
@@ -205,49 +183,41 @@ async def get_form_response(
205
183
  """
206
184
  logger.info(f"[get_form_response] Invoked. Email: '{user_google_email}', Form ID: {form_id}, Response ID: {response_id}")
207
185
 
208
- try:
209
- response = await asyncio.to_thread(
210
- service.forms().responses().get(formId=form_id, responseId=response_id).execute
211
- )
212
-
213
- response_id = response.get("responseId", "Unknown")
214
- create_time = response.get("createTime", "Unknown")
215
- last_submitted_time = response.get("lastSubmittedTime", "Unknown")
216
-
217
- answers = response.get("answers", {})
218
- answer_details = []
219
- for question_id, answer_data in answers.items():
220
- question_response = answer_data.get("textAnswers", {}).get("answers", [])
221
- if question_response:
222
- answer_text = ", ".join([ans.get("value", "") for ans in question_response])
223
- answer_details.append(f" Question ID {question_id}: {answer_text}")
224
- else:
225
- answer_details.append(f" Question ID {question_id}: No answer provided")
226
-
227
- answers_text = "\n".join(answer_details) if answer_details else " No answers found"
228
-
229
- result = f"""Form Response Details for {user_google_email}:
186
+ response = await asyncio.to_thread(
187
+ service.forms().responses().get(formId=form_id, responseId=response_id).execute
188
+ )
189
+
190
+ response_id = response.get("responseId", "Unknown")
191
+ create_time = response.get("createTime", "Unknown")
192
+ last_submitted_time = response.get("lastSubmittedTime", "Unknown")
193
+
194
+ answers = response.get("answers", {})
195
+ answer_details = []
196
+ for question_id, answer_data in answers.items():
197
+ question_response = answer_data.get("textAnswers", {}).get("answers", [])
198
+ if question_response:
199
+ answer_text = ", ".join([ans.get("value", "") for ans in question_response])
200
+ answer_details.append(f" Question ID {question_id}: {answer_text}")
201
+ else:
202
+ answer_details.append(f" Question ID {question_id}: No answer provided")
203
+
204
+ answers_text = "\n".join(answer_details) if answer_details else " No answers found"
205
+
206
+ result = f"""Form Response Details for {user_google_email}:
230
207
  - Form ID: {form_id}
231
208
  - Response ID: {response_id}
232
209
  - Created: {create_time}
233
210
  - Last Submitted: {last_submitted_time}
234
211
  - Answers:
235
212
  {answers_text}"""
236
-
237
- logger.info(f"Successfully retrieved response for {user_google_email}. Response ID: {response_id}")
238
- return result
239
- except HttpError as error:
240
- message = f"API error getting form response: {error}. You might need to re-authenticate. LLM: Try 'start_google_auth' with the user's email ({user_google_email}) and service_name='Google Forms'."
241
- logger.error(message, exc_info=True)
242
- raise Exception(message)
243
- except Exception as e:
244
- message = f"Unexpected error getting form response: {e}."
245
- logger.exception(message)
246
- raise Exception(message)
213
+
214
+ logger.info(f"Successfully retrieved response for {user_google_email}. Response ID: {response_id}")
215
+ return result
247
216
 
248
217
 
249
218
  @server.tool()
250
219
  @require_google_service("forms", "forms")
220
+ @handle_http_errors("list_form_responses")
251
221
  async def list_form_responses(
252
222
  service,
253
223
  user_google_email: str,
@@ -269,50 +239,41 @@ async def list_form_responses(
269
239
  """
270
240
  logger.info(f"[list_form_responses] Invoked. Email: '{user_google_email}', Form ID: {form_id}")
271
241
 
272
- try:
273
- params = {
274
- "formId": form_id,
275
- "pageSize": page_size
276
- }
277
- if page_token:
278
- params["pageToken"] = page_token
279
-
280
- responses_result = await asyncio.to_thread(
281
- service.forms().responses().list(**params).execute
242
+ params = {
243
+ "formId": form_id,
244
+ "pageSize": page_size
245
+ }
246
+ if page_token:
247
+ params["pageToken"] = page_token
248
+
249
+ responses_result = await asyncio.to_thread(
250
+ service.forms().responses().list(**params).execute
251
+ )
252
+
253
+ responses = responses_result.get("responses", [])
254
+ next_page_token = responses_result.get("nextPageToken")
255
+
256
+ if not responses:
257
+ return f"No responses found for form {form_id} for {user_google_email}."
258
+
259
+ response_details = []
260
+ for i, response in enumerate(responses, 1):
261
+ response_id = response.get("responseId", "Unknown")
262
+ create_time = response.get("createTime", "Unknown")
263
+ last_submitted_time = response.get("lastSubmittedTime", "Unknown")
264
+
265
+ answers_count = len(response.get("answers", {}))
266
+ response_details.append(
267
+ f" {i}. Response ID: {response_id} | Created: {create_time} | Last Submitted: {last_submitted_time} | Answers: {answers_count}"
282
268
  )
283
269
 
284
- responses = responses_result.get("responses", [])
285
- next_page_token = responses_result.get("nextPageToken")
286
-
287
- if not responses:
288
- return f"No responses found for form {form_id} for {user_google_email}."
289
-
290
- response_details = []
291
- for i, response in enumerate(responses, 1):
292
- response_id = response.get("responseId", "Unknown")
293
- create_time = response.get("createTime", "Unknown")
294
- last_submitted_time = response.get("lastSubmittedTime", "Unknown")
295
-
296
- answers_count = len(response.get("answers", {}))
297
- response_details.append(
298
- f" {i}. Response ID: {response_id} | Created: {create_time} | Last Submitted: {last_submitted_time} | Answers: {answers_count}"
299
- )
300
-
301
- pagination_info = f"\nNext page token: {next_page_token}" if next_page_token else "\nNo more pages."
302
-
303
- result = f"""Form Responses for {user_google_email}:
270
+ pagination_info = f"\nNext page token: {next_page_token}" if next_page_token else "\nNo more pages."
271
+
272
+ result = f"""Form Responses for {user_google_email}:
304
273
  - Form ID: {form_id}
305
274
  - Total responses returned: {len(responses)}
306
275
  - Responses:
307
276
  {chr(10).join(response_details)}{pagination_info}"""
308
-
309
- logger.info(f"Successfully retrieved {len(responses)} responses for {user_google_email}. Form ID: {form_id}")
310
- return result
311
- except HttpError as error:
312
- message = f"API error listing form responses: {error}. You might need to re-authenticate. LLM: Try 'start_google_auth' with the user's email ({user_google_email}) and service_name='Google Forms'."
313
- logger.error(message, exc_info=True)
314
- raise Exception(message)
315
- except Exception as e:
316
- message = f"Unexpected error listing form responses: {e}."
317
- logger.exception(message)
318
- raise Exception(message)
277
+
278
+ logger.info(f"Successfully retrieved {len(responses)} responses for {user_google_email}. Form ID: {form_id}")
279
+ return result