google-api-client-wrapper 2.1.1__tar.gz → 3.0.0__tar.gz

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.
Files changed (66) hide show
  1. {google_api_client_wrapper-2.1.1 → google_api_client_wrapper-3.0.0}/PKG-INFO +32 -6
  2. {google_api_client_wrapper-2.1.1 → google_api_client_wrapper-3.0.0}/README.md +31 -4
  3. {google_api_client_wrapper-2.1.1 → google_api_client_wrapper-3.0.0}/google_api_client_wrapper.egg-info/PKG-INFO +32 -6
  4. {google_api_client_wrapper-2.1.1 → google_api_client_wrapper-3.0.0}/google_api_client_wrapper.egg-info/SOURCES.txt +16 -0
  5. {google_api_client_wrapper-2.1.1 → google_api_client_wrapper-3.0.0}/google_api_client_wrapper.egg-info/requires.txt +0 -1
  6. {google_api_client_wrapper-2.1.1 → google_api_client_wrapper-3.0.0}/google_client/api_service.py +33 -2
  7. {google_api_client_wrapper-2.1.1 → google_api_client_wrapper-3.0.0}/google_client/auth.py +8 -0
  8. {google_api_client_wrapper-2.1.1 → google_api_client_wrapper-3.0.0}/google_client/services/__init__.py +3 -1
  9. {google_api_client_wrapper-2.1.1 → google_api_client_wrapper-3.0.0}/google_client/services/calendar/api_service.py +86 -12
  10. {google_api_client_wrapper-2.1.1 → google_api_client_wrapper-3.0.0}/google_client/services/calendar/async_api_service.py +88 -11
  11. google_api_client_wrapper-3.0.0/google_client/services/docs/__init__.py +7 -0
  12. google_api_client_wrapper-3.0.0/google_client/services/docs/api_service.py +277 -0
  13. google_api_client_wrapper-3.0.0/google_client/services/docs/async_api_service.py +307 -0
  14. google_api_client_wrapper-3.0.0/google_client/services/docs/async_batch_updater.py +31 -0
  15. google_api_client_wrapper-3.0.0/google_client/services/docs/base_batch_updater.py +201 -0
  16. google_api_client_wrapper-3.0.0/google_client/services/docs/batch_updater.py +27 -0
  17. google_api_client_wrapper-3.0.0/google_client/services/docs/types.py +10 -0
  18. google_api_client_wrapper-3.0.0/google_client/services/docs/utils.py +53 -0
  19. {google_api_client_wrapper-2.1.1 → google_api_client_wrapper-3.0.0}/google_client/services/drive/api_service.py +233 -0
  20. {google_api_client_wrapper-2.1.1 → google_api_client_wrapper-3.0.0}/google_client/services/drive/async_api_service.py +255 -0
  21. {google_api_client_wrapper-2.1.1 → google_api_client_wrapper-3.0.0}/google_client/services/drive/constants.py +1 -1
  22. {google_api_client_wrapper-2.1.1 → google_api_client_wrapper-3.0.0}/google_client/services/gmail/api_service.py +210 -22
  23. {google_api_client_wrapper-2.1.1 → google_api_client_wrapper-3.0.0}/google_client/services/gmail/async_api_service.py +197 -18
  24. google_api_client_wrapper-3.0.0/google_client/services/sheets/__init__.py +14 -0
  25. google_api_client_wrapper-3.0.0/google_client/services/sheets/api_service.py +433 -0
  26. google_api_client_wrapper-3.0.0/google_client/services/sheets/async_api_service.py +301 -0
  27. google_api_client_wrapper-3.0.0/google_client/services/sheets/async_batch_updater.py +58 -0
  28. google_api_client_wrapper-3.0.0/google_client/services/sheets/base_batch_updater.py +447 -0
  29. google_api_client_wrapper-3.0.0/google_client/services/sheets/batch_updater.py +47 -0
  30. google_api_client_wrapper-3.0.0/google_client/services/sheets/types.py +154 -0
  31. google_api_client_wrapper-3.0.0/google_client/services/sheets/utils.py +43 -0
  32. {google_api_client_wrapper-2.1.1 → google_api_client_wrapper-3.0.0}/google_client/services/tasks/api_service.py +147 -2
  33. {google_api_client_wrapper-2.1.1 → google_api_client_wrapper-3.0.0}/google_client/services/tasks/async_api_service.py +132 -10
  34. {google_api_client_wrapper-2.1.1 → google_api_client_wrapper-3.0.0}/pyproject.toml +1 -2
  35. {google_api_client_wrapper-2.1.1 → google_api_client_wrapper-3.0.0}/LICENSE +0 -0
  36. {google_api_client_wrapper-2.1.1 → google_api_client_wrapper-3.0.0}/google_api_client_wrapper.egg-info/dependency_links.txt +0 -0
  37. {google_api_client_wrapper-2.1.1 → google_api_client_wrapper-3.0.0}/google_api_client_wrapper.egg-info/top_level.txt +0 -0
  38. {google_api_client_wrapper-2.1.1 → google_api_client_wrapper-3.0.0}/google_client/__init__.py +0 -0
  39. {google_api_client_wrapper-2.1.1 → google_api_client_wrapper-3.0.0}/google_client/services/calendar/__init__.py +0 -0
  40. {google_api_client_wrapper-2.1.1 → google_api_client_wrapper-3.0.0}/google_client/services/calendar/async_query_builder.py +0 -0
  41. {google_api_client_wrapper-2.1.1 → google_api_client_wrapper-3.0.0}/google_client/services/calendar/constants.py +0 -0
  42. {google_api_client_wrapper-2.1.1 → google_api_client_wrapper-3.0.0}/google_client/services/calendar/query_builder.py +0 -0
  43. {google_api_client_wrapper-2.1.1 → google_api_client_wrapper-3.0.0}/google_client/services/calendar/types.py +0 -0
  44. {google_api_client_wrapper-2.1.1 → google_api_client_wrapper-3.0.0}/google_client/services/calendar/utils.py +0 -0
  45. {google_api_client_wrapper-2.1.1 → google_api_client_wrapper-3.0.0}/google_client/services/drive/__init__.py +0 -0
  46. {google_api_client_wrapper-2.1.1 → google_api_client_wrapper-3.0.0}/google_client/services/drive/async_query_builder.py +0 -0
  47. {google_api_client_wrapper-2.1.1 → google_api_client_wrapper-3.0.0}/google_client/services/drive/exceptions.py +0 -0
  48. {google_api_client_wrapper-2.1.1 → google_api_client_wrapper-3.0.0}/google_client/services/drive/query_builder.py +0 -0
  49. {google_api_client_wrapper-2.1.1 → google_api_client_wrapper-3.0.0}/google_client/services/drive/types.py +0 -0
  50. {google_api_client_wrapper-2.1.1 → google_api_client_wrapper-3.0.0}/google_client/services/drive/utils.py +0 -0
  51. {google_api_client_wrapper-2.1.1 → google_api_client_wrapper-3.0.0}/google_client/services/gmail/__init__.py +0 -0
  52. {google_api_client_wrapper-2.1.1 → google_api_client_wrapper-3.0.0}/google_client/services/gmail/async_query_builder.py +0 -0
  53. {google_api_client_wrapper-2.1.1 → google_api_client_wrapper-3.0.0}/google_client/services/gmail/constants.py +0 -0
  54. {google_api_client_wrapper-2.1.1 → google_api_client_wrapper-3.0.0}/google_client/services/gmail/query_builder.py +0 -0
  55. {google_api_client_wrapper-2.1.1 → google_api_client_wrapper-3.0.0}/google_client/services/gmail/types.py +0 -0
  56. {google_api_client_wrapper-2.1.1 → google_api_client_wrapper-3.0.0}/google_client/services/gmail/utils.py +0 -0
  57. {google_api_client_wrapper-2.1.1 → google_api_client_wrapper-3.0.0}/google_client/services/tasks/__init__.py +0 -0
  58. {google_api_client_wrapper-2.1.1 → google_api_client_wrapper-3.0.0}/google_client/services/tasks/async_query_builder.py +0 -0
  59. {google_api_client_wrapper-2.1.1 → google_api_client_wrapper-3.0.0}/google_client/services/tasks/constants.py +0 -0
  60. {google_api_client_wrapper-2.1.1 → google_api_client_wrapper-3.0.0}/google_client/services/tasks/query_builder.py +0 -0
  61. {google_api_client_wrapper-2.1.1 → google_api_client_wrapper-3.0.0}/google_client/services/tasks/types.py +0 -0
  62. {google_api_client_wrapper-2.1.1 → google_api_client_wrapper-3.0.0}/google_client/services/tasks/utils.py +0 -0
  63. {google_api_client_wrapper-2.1.1 → google_api_client_wrapper-3.0.0}/google_client/utils/__init__.py +0 -0
  64. {google_api_client_wrapper-2.1.1 → google_api_client_wrapper-3.0.0}/google_client/utils/datetime.py +0 -0
  65. {google_api_client_wrapper-2.1.1 → google_api_client_wrapper-3.0.0}/google_client/utils/validation.py +0 -0
  66. {google_api_client_wrapper-2.1.1 → google_api_client_wrapper-3.0.0}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: google-api-client-wrapper
3
- Version: 2.1.1
3
+ Version: 3.0.0
4
4
  Summary: A comprehensive Python wrapper for Google APIs with async support, providing clean and intuitive access to Gmail, Google Drive, Google Calendar, and Google Tasks services.
5
5
  Author-email: Dagmawi Molla <dagmawishewadeg@gmail.com>
6
6
  License: MIT License
@@ -46,12 +46,11 @@ Requires-Dist: html2text>=2025.4.15
46
46
  Requires-Dist: pydantic>=2.11.7
47
47
  Requires-Dist: aiohttp>=3.9.0
48
48
  Requires-Dist: aiofiles>=23.0.0
49
- Requires-Dist: aiogoogle>=5.15.0
50
49
  Dynamic: license-file
51
50
 
52
51
  # Google API Client Wrapper
53
52
 
54
- A comprehensive Python wrapper for Google APIs, providing clean and intuitive access to Gmail, Google Drive, Google Calendar, and Google Tasks services with both synchronous and asynchronous implementations.
53
+ A comprehensive Python wrapper for Google APIs, providing clean and intuitive access to Gmail, Google Drive, Google Calendar, Google Tasks, Google Docs, and Google Sheets services with both synchronous and asynchronous implementations.
55
54
 
56
55
  ## Installation
57
56
 
@@ -71,6 +70,8 @@ pip install git+https://github.com/dsmolla/google-api-client-wrapper.git
71
70
  - **Google Drive Service**: Upload, download, and manage files and folders
72
71
  - **Google Calendar Service**: Create, update, and manage calendar events
73
72
  - **Google Tasks Service**: Manage tasks and task lists
73
+ - **Google Sheets Service**: Read, write, format, and batch-mutate spreadsheets
74
+ - **Google Docs Service**: Create, read, and perform complex batch formatting and structural mutations on Google Documents
74
75
  - **Async Support**: Full async/await support for all services with concurrent batch operations
75
76
  - **OAuth2 Authentication**: Secure authentication flow with token management
76
77
  - **Query Builders**: Intuitive query building for each service
@@ -97,13 +98,13 @@ oauth_manager = GoogleOAuthManager(
97
98
 
98
99
  # Generate authorization URL
99
100
  auth_url, state = oauth_manager.generate_auth_url(
100
- scopes=[Scopes.GMAIL, Scopes.DRIVE, Scopes.CALENDAR, Scopes.TASKS]
101
+ scopes=[Scopes.GMAIL, Scopes.DRIVE, Scopes.CALENDAR, Scopes.TASKS, Scopes.SHEETS]
101
102
  )
102
103
 
103
104
  # After user authorizes, exchange code for tokens
104
105
  user_info = oauth_manager.complete_auth_flow(
105
106
  code='authorization_code_from_callback',
106
- scopes=[Scopes.GMAIL, Scopes.DRIVE, Scopes.CALENDAR, Scopes.TASKS]
107
+ scopes=[Scopes.GMAIL, Scopes.DRIVE, Scopes.CALENDAR, Scopes.TASKS, Scopes.SHEETS]
107
108
  )
108
109
 
109
110
  # Save user_info for future use
@@ -130,7 +131,7 @@ oauth_manager = GoogleOAuthManager(
130
131
 
131
132
  # Authenticate using local server - browser opens automatically!
132
133
  user_info = oauth_manager.authenticate_via_local_server(
133
- scopes=[Scopes.GMAIL, Scopes.DRIVE, Scopes.CALENDAR, Scopes.TASKS]
134
+ scopes=[Scopes.GMAIL, Scopes.DRIVE, Scopes.CALENDAR, Scopes.TASKS, Scopes.SHEETS]
134
135
  )
135
136
 
136
137
  # Save credentials
@@ -185,6 +186,16 @@ event = calendar.create_event(
185
186
  # Access Tasks service
186
187
  tasks = api_service.tasks
187
188
  task = tasks.create_task(title="Review documents")
189
+
190
+ # Access Sheets service
191
+ sheets = api_service.sheets
192
+ values = sheets.get_values(spreadsheet_id="your_spreadsheet_id", range_name="Sheet1!A1:B2")
193
+ sheets.append_values_from_dicts("your_spreadsheet_id", "Sheet1!A1", [{"Name": "Alice", "Role": "Admin"}])
194
+
195
+ # Access Docs service
196
+ docs = api_service.docs
197
+ new_doc = docs.create_document(title="Automated Report")
198
+ docs.insert_table_with_data(new_doc.document_id, index=1, data=[["Column 1", "Column 2"]])
188
199
  ```
189
200
 
190
201
  ### Using Services (Asynchronous)
@@ -227,6 +238,15 @@ async def main():
227
238
  tasks = api_service.async_tasks
228
239
  all_tasks = await tasks.list_tasks(show_completed=True)
229
240
 
241
+ # Access async Sheets service
242
+ sheets = api_service.async_sheets
243
+ values = await sheets.get_values(spreadsheet_id="your_spreadsheet_id", range_name="Sheet1!A1:B2")
244
+
245
+ # Access async Docs service
246
+ docs = api_service.async_docs
247
+ new_doc = await docs.create_document(title="Async Automated Report")
248
+ extracted_text = await docs.get_document_text(new_doc.document_id)
249
+
230
250
  # Run async code
231
251
  asyncio.run(main())
232
252
  ```
@@ -327,6 +347,8 @@ Each service has detailed documentation with examples and API reference:
327
347
  - **[Google Drive Service](google_client/services/drive/README.md)** - File and folder management
328
348
  - **[Google Calendar Service](google_client/services/calendar/README.md)** - Calendar and event management
329
349
  - **[Google Tasks Service](google_client/services/tasks/README.md)** - Task and task list management
350
+ - **[Google Sheets Service](google_client/services/sheets/README.md)** - Advanced spreadsheet reading, writing, and batch mutation
351
+ - **[Google Docs Service](google_client/services/docs/README.md)** - Precise document creation, abstract-syntax-tree parsing, and nested structural formatting
330
352
 
331
353
  ## Available Scopes
332
354
 
@@ -337,6 +359,8 @@ Scopes.GMAIL # Full Gmail access
337
359
  Scopes.DRIVE # Full Drive access
338
360
  Scopes.CALENDAR # Full Calendar access
339
361
  Scopes.TASKS # Full Tasks access
362
+ Scopes.SHEETS # Full Sheets access
363
+ Scopes.DOCS # Full Docs access
340
364
  ```
341
365
 
342
366
  ## Token Refresh
@@ -362,6 +386,8 @@ refreshed_token = api_service.refresh_token()
362
386
  - **[Drive API Reference](https://developers.google.com/drive/api)**
363
387
  - **[Calendar API Reference](https://developers.google.com/calendar/api)**
364
388
  - **[Tasks API Reference](https://developers.google.com/tasks/reference/rest)**
389
+ - **[Sheets API Reference](https://developers.google.com/sheets/api/reference/rest)**
390
+ - **[Docs API Reference](https://developers.google.com/docs/api/reference/rest)**
365
391
 
366
392
  ---
367
393
 
@@ -1,6 +1,6 @@
1
1
  # Google API Client Wrapper
2
2
 
3
- A comprehensive Python wrapper for Google APIs, providing clean and intuitive access to Gmail, Google Drive, Google Calendar, and Google Tasks services with both synchronous and asynchronous implementations.
3
+ A comprehensive Python wrapper for Google APIs, providing clean and intuitive access to Gmail, Google Drive, Google Calendar, Google Tasks, Google Docs, and Google Sheets services with both synchronous and asynchronous implementations.
4
4
 
5
5
  ## Installation
6
6
 
@@ -20,6 +20,8 @@ pip install git+https://github.com/dsmolla/google-api-client-wrapper.git
20
20
  - **Google Drive Service**: Upload, download, and manage files and folders
21
21
  - **Google Calendar Service**: Create, update, and manage calendar events
22
22
  - **Google Tasks Service**: Manage tasks and task lists
23
+ - **Google Sheets Service**: Read, write, format, and batch-mutate spreadsheets
24
+ - **Google Docs Service**: Create, read, and perform complex batch formatting and structural mutations on Google Documents
23
25
  - **Async Support**: Full async/await support for all services with concurrent batch operations
24
26
  - **OAuth2 Authentication**: Secure authentication flow with token management
25
27
  - **Query Builders**: Intuitive query building for each service
@@ -46,13 +48,13 @@ oauth_manager = GoogleOAuthManager(
46
48
 
47
49
  # Generate authorization URL
48
50
  auth_url, state = oauth_manager.generate_auth_url(
49
- scopes=[Scopes.GMAIL, Scopes.DRIVE, Scopes.CALENDAR, Scopes.TASKS]
51
+ scopes=[Scopes.GMAIL, Scopes.DRIVE, Scopes.CALENDAR, Scopes.TASKS, Scopes.SHEETS]
50
52
  )
51
53
 
52
54
  # After user authorizes, exchange code for tokens
53
55
  user_info = oauth_manager.complete_auth_flow(
54
56
  code='authorization_code_from_callback',
55
- scopes=[Scopes.GMAIL, Scopes.DRIVE, Scopes.CALENDAR, Scopes.TASKS]
57
+ scopes=[Scopes.GMAIL, Scopes.DRIVE, Scopes.CALENDAR, Scopes.TASKS, Scopes.SHEETS]
56
58
  )
57
59
 
58
60
  # Save user_info for future use
@@ -79,7 +81,7 @@ oauth_manager = GoogleOAuthManager(
79
81
 
80
82
  # Authenticate using local server - browser opens automatically!
81
83
  user_info = oauth_manager.authenticate_via_local_server(
82
- scopes=[Scopes.GMAIL, Scopes.DRIVE, Scopes.CALENDAR, Scopes.TASKS]
84
+ scopes=[Scopes.GMAIL, Scopes.DRIVE, Scopes.CALENDAR, Scopes.TASKS, Scopes.SHEETS]
83
85
  )
84
86
 
85
87
  # Save credentials
@@ -134,6 +136,16 @@ event = calendar.create_event(
134
136
  # Access Tasks service
135
137
  tasks = api_service.tasks
136
138
  task = tasks.create_task(title="Review documents")
139
+
140
+ # Access Sheets service
141
+ sheets = api_service.sheets
142
+ values = sheets.get_values(spreadsheet_id="your_spreadsheet_id", range_name="Sheet1!A1:B2")
143
+ sheets.append_values_from_dicts("your_spreadsheet_id", "Sheet1!A1", [{"Name": "Alice", "Role": "Admin"}])
144
+
145
+ # Access Docs service
146
+ docs = api_service.docs
147
+ new_doc = docs.create_document(title="Automated Report")
148
+ docs.insert_table_with_data(new_doc.document_id, index=1, data=[["Column 1", "Column 2"]])
137
149
  ```
138
150
 
139
151
  ### Using Services (Asynchronous)
@@ -176,6 +188,15 @@ async def main():
176
188
  tasks = api_service.async_tasks
177
189
  all_tasks = await tasks.list_tasks(show_completed=True)
178
190
 
191
+ # Access async Sheets service
192
+ sheets = api_service.async_sheets
193
+ values = await sheets.get_values(spreadsheet_id="your_spreadsheet_id", range_name="Sheet1!A1:B2")
194
+
195
+ # Access async Docs service
196
+ docs = api_service.async_docs
197
+ new_doc = await docs.create_document(title="Async Automated Report")
198
+ extracted_text = await docs.get_document_text(new_doc.document_id)
199
+
179
200
  # Run async code
180
201
  asyncio.run(main())
181
202
  ```
@@ -276,6 +297,8 @@ Each service has detailed documentation with examples and API reference:
276
297
  - **[Google Drive Service](google_client/services/drive/README.md)** - File and folder management
277
298
  - **[Google Calendar Service](google_client/services/calendar/README.md)** - Calendar and event management
278
299
  - **[Google Tasks Service](google_client/services/tasks/README.md)** - Task and task list management
300
+ - **[Google Sheets Service](google_client/services/sheets/README.md)** - Advanced spreadsheet reading, writing, and batch mutation
301
+ - **[Google Docs Service](google_client/services/docs/README.md)** - Precise document creation, abstract-syntax-tree parsing, and nested structural formatting
279
302
 
280
303
  ## Available Scopes
281
304
 
@@ -286,6 +309,8 @@ Scopes.GMAIL # Full Gmail access
286
309
  Scopes.DRIVE # Full Drive access
287
310
  Scopes.CALENDAR # Full Calendar access
288
311
  Scopes.TASKS # Full Tasks access
312
+ Scopes.SHEETS # Full Sheets access
313
+ Scopes.DOCS # Full Docs access
289
314
  ```
290
315
 
291
316
  ## Token Refresh
@@ -311,6 +336,8 @@ refreshed_token = api_service.refresh_token()
311
336
  - **[Drive API Reference](https://developers.google.com/drive/api)**
312
337
  - **[Calendar API Reference](https://developers.google.com/calendar/api)**
313
338
  - **[Tasks API Reference](https://developers.google.com/tasks/reference/rest)**
339
+ - **[Sheets API Reference](https://developers.google.com/sheets/api/reference/rest)**
340
+ - **[Docs API Reference](https://developers.google.com/docs/api/reference/rest)**
314
341
 
315
342
  ---
316
343
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: google-api-client-wrapper
3
- Version: 2.1.1
3
+ Version: 3.0.0
4
4
  Summary: A comprehensive Python wrapper for Google APIs with async support, providing clean and intuitive access to Gmail, Google Drive, Google Calendar, and Google Tasks services.
5
5
  Author-email: Dagmawi Molla <dagmawishewadeg@gmail.com>
6
6
  License: MIT License
@@ -46,12 +46,11 @@ Requires-Dist: html2text>=2025.4.15
46
46
  Requires-Dist: pydantic>=2.11.7
47
47
  Requires-Dist: aiohttp>=3.9.0
48
48
  Requires-Dist: aiofiles>=23.0.0
49
- Requires-Dist: aiogoogle>=5.15.0
50
49
  Dynamic: license-file
51
50
 
52
51
  # Google API Client Wrapper
53
52
 
54
- A comprehensive Python wrapper for Google APIs, providing clean and intuitive access to Gmail, Google Drive, Google Calendar, and Google Tasks services with both synchronous and asynchronous implementations.
53
+ A comprehensive Python wrapper for Google APIs, providing clean and intuitive access to Gmail, Google Drive, Google Calendar, Google Tasks, Google Docs, and Google Sheets services with both synchronous and asynchronous implementations.
55
54
 
56
55
  ## Installation
57
56
 
@@ -71,6 +70,8 @@ pip install git+https://github.com/dsmolla/google-api-client-wrapper.git
71
70
  - **Google Drive Service**: Upload, download, and manage files and folders
72
71
  - **Google Calendar Service**: Create, update, and manage calendar events
73
72
  - **Google Tasks Service**: Manage tasks and task lists
73
+ - **Google Sheets Service**: Read, write, format, and batch-mutate spreadsheets
74
+ - **Google Docs Service**: Create, read, and perform complex batch formatting and structural mutations on Google Documents
74
75
  - **Async Support**: Full async/await support for all services with concurrent batch operations
75
76
  - **OAuth2 Authentication**: Secure authentication flow with token management
76
77
  - **Query Builders**: Intuitive query building for each service
@@ -97,13 +98,13 @@ oauth_manager = GoogleOAuthManager(
97
98
 
98
99
  # Generate authorization URL
99
100
  auth_url, state = oauth_manager.generate_auth_url(
100
- scopes=[Scopes.GMAIL, Scopes.DRIVE, Scopes.CALENDAR, Scopes.TASKS]
101
+ scopes=[Scopes.GMAIL, Scopes.DRIVE, Scopes.CALENDAR, Scopes.TASKS, Scopes.SHEETS]
101
102
  )
102
103
 
103
104
  # After user authorizes, exchange code for tokens
104
105
  user_info = oauth_manager.complete_auth_flow(
105
106
  code='authorization_code_from_callback',
106
- scopes=[Scopes.GMAIL, Scopes.DRIVE, Scopes.CALENDAR, Scopes.TASKS]
107
+ scopes=[Scopes.GMAIL, Scopes.DRIVE, Scopes.CALENDAR, Scopes.TASKS, Scopes.SHEETS]
107
108
  )
108
109
 
109
110
  # Save user_info for future use
@@ -130,7 +131,7 @@ oauth_manager = GoogleOAuthManager(
130
131
 
131
132
  # Authenticate using local server - browser opens automatically!
132
133
  user_info = oauth_manager.authenticate_via_local_server(
133
- scopes=[Scopes.GMAIL, Scopes.DRIVE, Scopes.CALENDAR, Scopes.TASKS]
134
+ scopes=[Scopes.GMAIL, Scopes.DRIVE, Scopes.CALENDAR, Scopes.TASKS, Scopes.SHEETS]
134
135
  )
135
136
 
136
137
  # Save credentials
@@ -185,6 +186,16 @@ event = calendar.create_event(
185
186
  # Access Tasks service
186
187
  tasks = api_service.tasks
187
188
  task = tasks.create_task(title="Review documents")
189
+
190
+ # Access Sheets service
191
+ sheets = api_service.sheets
192
+ values = sheets.get_values(spreadsheet_id="your_spreadsheet_id", range_name="Sheet1!A1:B2")
193
+ sheets.append_values_from_dicts("your_spreadsheet_id", "Sheet1!A1", [{"Name": "Alice", "Role": "Admin"}])
194
+
195
+ # Access Docs service
196
+ docs = api_service.docs
197
+ new_doc = docs.create_document(title="Automated Report")
198
+ docs.insert_table_with_data(new_doc.document_id, index=1, data=[["Column 1", "Column 2"]])
188
199
  ```
189
200
 
190
201
  ### Using Services (Asynchronous)
@@ -227,6 +238,15 @@ async def main():
227
238
  tasks = api_service.async_tasks
228
239
  all_tasks = await tasks.list_tasks(show_completed=True)
229
240
 
241
+ # Access async Sheets service
242
+ sheets = api_service.async_sheets
243
+ values = await sheets.get_values(spreadsheet_id="your_spreadsheet_id", range_name="Sheet1!A1:B2")
244
+
245
+ # Access async Docs service
246
+ docs = api_service.async_docs
247
+ new_doc = await docs.create_document(title="Async Automated Report")
248
+ extracted_text = await docs.get_document_text(new_doc.document_id)
249
+
230
250
  # Run async code
231
251
  asyncio.run(main())
232
252
  ```
@@ -327,6 +347,8 @@ Each service has detailed documentation with examples and API reference:
327
347
  - **[Google Drive Service](google_client/services/drive/README.md)** - File and folder management
328
348
  - **[Google Calendar Service](google_client/services/calendar/README.md)** - Calendar and event management
329
349
  - **[Google Tasks Service](google_client/services/tasks/README.md)** - Task and task list management
350
+ - **[Google Sheets Service](google_client/services/sheets/README.md)** - Advanced spreadsheet reading, writing, and batch mutation
351
+ - **[Google Docs Service](google_client/services/docs/README.md)** - Precise document creation, abstract-syntax-tree parsing, and nested structural formatting
330
352
 
331
353
  ## Available Scopes
332
354
 
@@ -337,6 +359,8 @@ Scopes.GMAIL # Full Gmail access
337
359
  Scopes.DRIVE # Full Drive access
338
360
  Scopes.CALENDAR # Full Calendar access
339
361
  Scopes.TASKS # Full Tasks access
362
+ Scopes.SHEETS # Full Sheets access
363
+ Scopes.DOCS # Full Docs access
340
364
  ```
341
365
 
342
366
  ## Token Refresh
@@ -362,6 +386,8 @@ refreshed_token = api_service.refresh_token()
362
386
  - **[Drive API Reference](https://developers.google.com/drive/api)**
363
387
  - **[Calendar API Reference](https://developers.google.com/calendar/api)**
364
388
  - **[Tasks API Reference](https://developers.google.com/tasks/reference/rest)**
389
+ - **[Sheets API Reference](https://developers.google.com/sheets/api/reference/rest)**
390
+ - **[Docs API Reference](https://developers.google.com/docs/api/reference/rest)**
365
391
 
366
392
  ---
367
393
 
@@ -18,6 +18,14 @@ google_client/services/calendar/constants.py
18
18
  google_client/services/calendar/query_builder.py
19
19
  google_client/services/calendar/types.py
20
20
  google_client/services/calendar/utils.py
21
+ google_client/services/docs/__init__.py
22
+ google_client/services/docs/api_service.py
23
+ google_client/services/docs/async_api_service.py
24
+ google_client/services/docs/async_batch_updater.py
25
+ google_client/services/docs/base_batch_updater.py
26
+ google_client/services/docs/batch_updater.py
27
+ google_client/services/docs/types.py
28
+ google_client/services/docs/utils.py
21
29
  google_client/services/drive/__init__.py
22
30
  google_client/services/drive/api_service.py
23
31
  google_client/services/drive/async_api_service.py
@@ -35,6 +43,14 @@ google_client/services/gmail/constants.py
35
43
  google_client/services/gmail/query_builder.py
36
44
  google_client/services/gmail/types.py
37
45
  google_client/services/gmail/utils.py
46
+ google_client/services/sheets/__init__.py
47
+ google_client/services/sheets/api_service.py
48
+ google_client/services/sheets/async_api_service.py
49
+ google_client/services/sheets/async_batch_updater.py
50
+ google_client/services/sheets/base_batch_updater.py
51
+ google_client/services/sheets/batch_updater.py
52
+ google_client/services/sheets/types.py
53
+ google_client/services/sheets/utils.py
38
54
  google_client/services/tasks/__init__.py
39
55
  google_client/services/tasks/api_service.py
40
56
  google_client/services/tasks/async_api_service.py
@@ -7,4 +7,3 @@ html2text>=2025.4.15
7
7
  pydantic>=2.11.7
8
8
  aiohttp>=3.9.0
9
9
  aiofiles>=23.0.0
10
- aiogoogle>=5.15.0
@@ -8,11 +8,15 @@ from .services.gmail import GmailApiService
8
8
  from .services.calendar import CalendarApiService
9
9
  from .services.tasks import TasksApiService
10
10
  from .services.drive import DriveApiService
11
+ from .services.sheets import SheetsApiService
12
+ from .services.docs import DocsApiService
11
13
 
12
14
  from .services.gmail import AsyncGmailApiService
13
15
  from .services.calendar import AsyncCalendarApiService
14
16
  from .services.drive import AsyncDriveApiService
15
17
  from .services.tasks import AsyncTasksApiService
18
+ from .services.sheets import AsyncSheetsApiService
19
+ from .services.docs import AsyncDocsApiService
16
20
 
17
21
 
18
22
  class APIServiceLayer:
@@ -27,11 +31,15 @@ class APIServiceLayer:
27
31
  self._calendar = None
28
32
  self._tasks = None
29
33
  self._drive = None
34
+ self._docs = None
35
+ self._sheets = None
30
36
 
31
37
  self._async_gmail = None
32
38
  self._async_calendar = None
33
39
  self._async_tasks = None
34
40
  self._async_drive = None
41
+ self._async_sheets = None
42
+ self._async_docs = None
35
43
 
36
44
  self.timezone = timezone
37
45
 
@@ -50,8 +58,8 @@ class APIServiceLayer:
50
58
  def refresh_token(self) -> dict:
51
59
  self._credentials.refresh(Request())
52
60
 
53
- self._gmail, self._calendar, self._tasks, self._drive = None, None, None, None
54
- self._async_gmail, self._async_calendar, self._async_tasks, self._async_drive = None, None, None, None
61
+ self._gmail, self._calendar, self._tasks, self._drive, self._docs, self._sheets = None, None, None, None, None, None
62
+ self._async_gmail, self._async_calendar, self._async_tasks, self._async_drive, self._async_sheets, self._async_docs = None, None, None, None, None, None
55
63
 
56
64
  return json.loads(self._credentials.to_json())
57
65
 
@@ -83,6 +91,17 @@ class APIServiceLayer:
83
91
  if self._drive is None:
84
92
  self._drive = DriveApiService(self._credentials, timezone=self.timezone)
85
93
  return self._drive
94
+ @property
95
+ def sheets(self):
96
+ if self._sheets is None:
97
+ self._sheets = SheetsApiService(self._credentials, timezone=self.timezone)
98
+ return self._sheets
99
+
100
+ @property
101
+ def docs(self):
102
+ if self._docs is None:
103
+ self._docs = DocsApiService(self._credentials, timezone=self.timezone)
104
+ return self._docs
86
105
 
87
106
 
88
107
  @property
@@ -109,3 +128,15 @@ class APIServiceLayer:
109
128
  self._async_drive = AsyncDriveApiService(self._credentials, timezone=self.timezone)
110
129
  return self._async_drive
111
130
 
131
+ @property
132
+ def async_sheets(self):
133
+ if self._async_sheets is None:
134
+ self._async_sheets = AsyncSheetsApiService(self._credentials, timezone=self.timezone)
135
+ return self._async_sheets
136
+
137
+ @property
138
+ def async_docs(self):
139
+ if self._async_docs is None:
140
+ self._async_docs = AsyncDocsApiService(self._credentials, timezone=self.timezone)
141
+ return self._async_docs
142
+
@@ -177,6 +177,14 @@ class Scopes:
177
177
  DRIVE_PHOTOS_READONLY = 'https://www.googleapis.com/auth/drive.photos.readonly'
178
178
  DRIVE_SCRIPTS = 'https://www.googleapis.com/auth/drive.scripts'
179
179
 
180
+ # Docs scopes
181
+ DOCS = 'https://www.googleapis.com/auth/documents'
182
+ DOCS_READONLY = 'https://www.googleapis.com/auth/documents.readonly'
183
+
184
+ # Sheets scopes
185
+ SHEETS = 'https://www.googleapis.com/auth/spreadsheets'
186
+ SHEETS_READONLY = 'https://www.googleapis.com/auth/spreadsheets.readonly'
187
+
180
188
  # User info scopes
181
189
  USERINFO_EMAIL = 'https://www.googleapis.com/auth/userinfo.email'
182
190
  USERINFO_PROFILE = 'https://www.googleapis.com/auth/userinfo.profile'
@@ -4,10 +4,12 @@ from . import calendar
4
4
  from . import gmail
5
5
  from . import drive
6
6
  from . import tasks
7
+ from . import sheets
7
8
 
8
9
  __all__ = [
9
10
  "calendar",
10
11
  "gmail",
11
12
  "drive",
12
- "tasks"
13
+ "tasks",
14
+ "sheets"
13
15
  ]
@@ -1,3 +1,4 @@
1
+ import json
1
2
  import uuid
2
3
  from datetime import datetime, timedelta
3
4
  from typing import Optional, List, Any, Dict, Union
@@ -370,11 +371,18 @@ class CalendarApiService:
370
371
  """
371
372
 
372
373
  calendar_events = []
373
- for event_id in event_ids:
374
- try:
375
- calendar_events.append(self.get_event(event_id, calendar_id))
376
- except Exception as e:
377
- calendar_events.append(e)
374
+ for i in range(0, len(event_ids), 10):
375
+ batch = self._service.new_batch_http_request()
376
+ for event_id in event_ids[i: i + 10]:
377
+ batch.add(self._service.events().get(calendarId=calendar_id, eventId=event_id))
378
+ batch.execute()
379
+
380
+ for response in batch._responses.values():
381
+ event_json = json.loads(response[1].decode())
382
+ if "error" in event_json:
383
+ calendar_events.append(("ERROR", event_json["error"]))
384
+ continue
385
+ calendar_events.append(utils.from_google_event(event_json, calendar_id, self._timezone))
378
386
 
379
387
  return calendar_events
380
388
 
@@ -382,7 +390,7 @@ class CalendarApiService:
382
390
  self,
383
391
  events_data: List[Dict[str, Any]],
384
392
  calendar_id: str = DEFAULT_CALENDAR_ID
385
- ) -> List[CalendarEvent | Exception]:
393
+ ) -> List[CalendarEvent | tuple]:
386
394
  """
387
395
  Creates multiple events.
388
396
 
@@ -391,18 +399,84 @@ class CalendarApiService:
391
399
  calendar_id: Calendar ID to create events in (default: 'primary').
392
400
 
393
401
  Returns:
394
- List of created CalendarEvent objects.
402
+ List of created CalendarEvent objects or ("ERROR", error_dict) tuples on failure.
395
403
  """
396
404
 
397
405
  created_events = []
398
- for event_data in events_data:
399
- try:
400
- created_events.append(self.create_event(calendar_id=calendar_id, **event_data))
401
- except Exception as e:
402
- created_events.append(e)
406
+ for i in range(0, len(events_data), 10):
407
+ batch = self._service.new_batch_http_request()
408
+ for event_data in events_data[i: i + 10]:
409
+ event_body = {
410
+ 'summary': event_data.get('summary') or "New Event",
411
+ 'start': {'dateTime': datetime_to_iso(event_data['start'], self._timezone), 'timeZone': self._timezone},
412
+ 'end': {'dateTime': datetime_to_iso(event_data['end'], self._timezone), 'timeZone': self._timezone},
413
+ }
414
+ if event_data.get('description'):
415
+ event_body['description'] = event_data['description']
416
+ if event_data.get('location'):
417
+ event_body['location'] = event_data['location']
418
+ if event_data.get('attendees'):
419
+ event_body['attendees'] = [a.to_dict() for a in event_data['attendees']]
420
+ if event_data.get('recurrence'):
421
+ event_body['recurrence'] = event_data['recurrence']
422
+ if event_data.get('create_google_meet'):
423
+ event_body['conferenceData'] = {
424
+ "createRequest": {
425
+ "requestId": uuid.uuid4().hex,
426
+ "conferenceSolutionKey": {"type": "hangoutsMeet"}
427
+ }
428
+ }
429
+ batch.add(self._service.events().insert(
430
+ calendarId=calendar_id, body=event_body, conferenceDataVersion=1
431
+ ))
432
+ batch.execute()
433
+
434
+ for response in batch._responses.values():
435
+ event_json = json.loads(response[1].decode())
436
+ if "error" in event_json:
437
+ created_events.append(("ERROR", event_json["error"]))
438
+ continue
439
+ created_events.append(utils.from_google_event(event_json, calendar_id, self._timezone))
403
440
 
404
441
  return created_events
405
442
 
443
+ def batch_delete_events(
444
+ self,
445
+ events: List[Union[CalendarEvent, str]],
446
+ calendar_id: str = DEFAULT_CALENDAR_ID
447
+ ) -> List[bool | tuple]:
448
+ """
449
+ Deletes multiple calendar events.
450
+
451
+ Args:
452
+ events: List of CalendarEvent objects or event IDs to delete.
453
+ calendar_id: Calendar ID containing the events (default: 'primary').
454
+
455
+ Returns:
456
+ List of True for each success or ("ERROR", error_dict) for each failure.
457
+ """
458
+ results = []
459
+ event_ids = [e if isinstance(e, str) else e.event_id for e in events]
460
+
461
+ for i in range(0, len(event_ids), 10):
462
+ batch = self._service.new_batch_http_request()
463
+ for event_id in event_ids[i: i + 10]:
464
+ batch.add(self._service.events().delete(calendarId=calendar_id, eventId=event_id))
465
+ batch.execute()
466
+
467
+ for response in batch._responses.values():
468
+ body = response[1]
469
+ if not body:
470
+ results.append(True)
471
+ continue
472
+ response_json = json.loads(body.decode())
473
+ if "error" in response_json:
474
+ results.append(("ERROR", response_json["error"]))
475
+ continue
476
+ results.append(True)
477
+
478
+ return results
479
+
406
480
  def get_freebusy(
407
481
  self,
408
482
  start: datetime,