smartsheet-python-sdk 3.5.5__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.
- smartsheet/__init__.py +37 -0
- smartsheet/attachments.py +565 -0
- smartsheet/cells.py +164 -0
- smartsheet/contacts.py +78 -0
- smartsheet/discussions.py +411 -0
- smartsheet/events.py +79 -0
- smartsheet/exceptions.py +130 -0
- smartsheet/favorites.py +116 -0
- smartsheet/folders.py +438 -0
- smartsheet/groups.py +186 -0
- smartsheet/home.py +180 -0
- smartsheet/images.py +61 -0
- smartsheet/models/__init__.py +126 -0
- smartsheet/models/access_token.py +95 -0
- smartsheet/models/account.py +77 -0
- smartsheet/models/alternate_email.py +88 -0
- smartsheet/models/asset_share.py +165 -0
- smartsheet/models/asset_shares_paginated_result.py +84 -0
- smartsheet/models/attachment.py +181 -0
- smartsheet/models/auto_number_format.py +81 -0
- smartsheet/models/automation_action.py +162 -0
- smartsheet/models/automation_rule.py +164 -0
- smartsheet/models/boolean_object_value.py +38 -0
- smartsheet/models/bulk_item_failure.py +77 -0
- smartsheet/models/bulk_item_result.py +111 -0
- smartsheet/models/cell.py +193 -0
- smartsheet/models/cell_data_item.py +152 -0
- smartsheet/models/cell_history.py +67 -0
- smartsheet/models/cell_link.py +91 -0
- smartsheet/models/cell_link_widget_content.py +101 -0
- smartsheet/models/chart_widget_content.py +124 -0
- smartsheet/models/column.py +253 -0
- smartsheet/models/comment.py +126 -0
- smartsheet/models/contact.py +88 -0
- smartsheet/models/contact_object_value.py +59 -0
- smartsheet/models/container_destination.py +74 -0
- smartsheet/models/copy_or_move_row_destination.py +54 -0
- smartsheet/models/copy_or_move_row_directive.py +64 -0
- smartsheet/models/copy_or_move_row_result.py +67 -0
- smartsheet/models/criteria.py +82 -0
- smartsheet/models/cross_sheet_reference.py +134 -0
- smartsheet/models/currency.py +64 -0
- smartsheet/models/date_object_value.py +56 -0
- smartsheet/models/datetime_object_value.py +56 -0
- smartsheet/models/discussion.py +183 -0
- smartsheet/models/downloaded_file.py +106 -0
- smartsheet/models/duration.py +112 -0
- smartsheet/models/email.py +82 -0
- smartsheet/models/enums/__init__.py +56 -0
- smartsheet/models/enums/access_level.py +26 -0
- smartsheet/models/enums/asset_type.py +10 -0
- smartsheet/models/enums/attachment_parent_type.py +23 -0
- smartsheet/models/enums/attachment_sub_type.py +26 -0
- smartsheet/models/enums/attachment_type.py +29 -0
- smartsheet/models/enums/automation_action_frequency.py +24 -0
- smartsheet/models/enums/automation_action_type.py +23 -0
- smartsheet/models/enums/automation_rule_disabled_reason.py +27 -0
- smartsheet/models/enums/cell_link_status.py +28 -0
- smartsheet/models/enums/column_type.py +31 -0
- smartsheet/models/enums/criteria_target.py +21 -0
- smartsheet/models/enums/cross_sheet_reference_status.py +28 -0
- smartsheet/models/enums/currency_code.py +43 -0
- smartsheet/models/enums/day_descriptors.py +30 -0
- smartsheet/models/enums/day_ordinal.py +25 -0
- smartsheet/models/enums/event_action.py +76 -0
- smartsheet/models/enums/event_obejct_type.py +34 -0
- smartsheet/models/enums/event_source.py +27 -0
- smartsheet/models/enums/global_template.py +23 -0
- smartsheet/models/enums/operator.py +62 -0
- smartsheet/models/enums/paper_type.py +29 -0
- smartsheet/models/enums/predecessor_type.py +24 -0
- smartsheet/models/enums/publish_accessible_by.py +22 -0
- smartsheet/models/enums/schedule_type.py +25 -0
- smartsheet/models/enums/seat_type.py +17 -0
- smartsheet/models/enums/share_scope.py +22 -0
- smartsheet/models/enums/share_type.py +22 -0
- smartsheet/models/enums/sheet_email_format.py +23 -0
- smartsheet/models/enums/sheet_filter_operator.py +22 -0
- smartsheet/models/enums/sheet_filter_type.py +23 -0
- smartsheet/models/enums/sort_direction.py +22 -0
- smartsheet/models/enums/symbol.py +45 -0
- smartsheet/models/enums/system_column_type.py +25 -0
- smartsheet/models/enums/update_request_status.py +23 -0
- smartsheet/models/enums/user_status.py +23 -0
- smartsheet/models/enums/widget_type.py +32 -0
- smartsheet/models/error.py +74 -0
- smartsheet/models/error_result.py +117 -0
- smartsheet/models/event.py +153 -0
- smartsheet/models/event_result.py +86 -0
- smartsheet/models/explicit_null.py +24 -0
- smartsheet/models/favorite.py +81 -0
- smartsheet/models/folder.py +177 -0
- smartsheet/models/font_family.py +63 -0
- smartsheet/models/format_details.py +55 -0
- smartsheet/models/format_tables.py +191 -0
- smartsheet/models/group.py +134 -0
- smartsheet/models/group_member.py +104 -0
- smartsheet/models/home.py +110 -0
- smartsheet/models/hyperlink.py +81 -0
- smartsheet/models/image.py +101 -0
- smartsheet/models/image_url.py +91 -0
- smartsheet/models/image_url_map.py +68 -0
- smartsheet/models/image_widget_content.py +117 -0
- smartsheet/models/index_result.py +118 -0
- smartsheet/models/json_object.py +59 -0
- smartsheet/models/multi_contact_object_value.py +49 -0
- smartsheet/models/multi_picklist_object_value.py +48 -0
- smartsheet/models/multi_row_email.py +60 -0
- smartsheet/models/number_object_value.py +38 -0
- smartsheet/models/o_auth_error.py +86 -0
- smartsheet/models/object_value.py +130 -0
- smartsheet/models/paginated_children_result.py +80 -0
- smartsheet/models/predecessor.py +102 -0
- smartsheet/models/predecessor_list.py +49 -0
- smartsheet/models/primitive_object_value.py +59 -0
- smartsheet/models/profile_image.py +72 -0
- smartsheet/models/project_settings.py +89 -0
- smartsheet/models/recipient.py +63 -0
- smartsheet/models/report.py +90 -0
- smartsheet/models/report_cell.py +59 -0
- smartsheet/models/report_column.py +67 -0
- smartsheet/models/report_publish.py +95 -0
- smartsheet/models/report_row.py +68 -0
- smartsheet/models/report_widget_content.py +78 -0
- smartsheet/models/result.py +105 -0
- smartsheet/models/row.py +336 -0
- smartsheet/models/row_email.py +83 -0
- smartsheet/models/row_mapping.py +77 -0
- smartsheet/models/schedule.py +140 -0
- smartsheet/models/scope.py +70 -0
- smartsheet/models/search_result.py +67 -0
- smartsheet/models/search_result_item.py +150 -0
- smartsheet/models/selection_range.py +86 -0
- smartsheet/models/sent_update_request.py +172 -0
- smartsheet/models/server_info.py +67 -0
- smartsheet/models/share.py +183 -0
- smartsheet/models/sheet.py +462 -0
- smartsheet/models/sheet_email.py +81 -0
- smartsheet/models/sheet_filter.py +106 -0
- smartsheet/models/sheet_filter_details.py +76 -0
- smartsheet/models/sheet_publish.py +184 -0
- smartsheet/models/sheet_summary.py +59 -0
- smartsheet/models/sheet_user_permissions.py +58 -0
- smartsheet/models/sheet_user_settings.py +72 -0
- smartsheet/models/shortcut_data_item.py +102 -0
- smartsheet/models/shortcut_widget_content.py +61 -0
- smartsheet/models/sight.py +175 -0
- smartsheet/models/sight_publish.py +77 -0
- smartsheet/models/sort_criterion.py +64 -0
- smartsheet/models/sort_specifier.py +55 -0
- smartsheet/models/source.py +83 -0
- smartsheet/models/string_object_value.py +38 -0
- smartsheet/models/summary_field.py +256 -0
- smartsheet/models/template.py +171 -0
- smartsheet/models/title_rich_text_widget_content.py +68 -0
- smartsheet/models/token_paginated_result.py +79 -0
- smartsheet/models/update_request.py +110 -0
- smartsheet/models/user.py +58 -0
- smartsheet/models/user_model.py +280 -0
- smartsheet/models/user_plan.py +77 -0
- smartsheet/models/user_profile.py +89 -0
- smartsheet/models/version.py +57 -0
- smartsheet/models/web_content_widget_content.py +60 -0
- smartsheet/models/webhook.py +219 -0
- smartsheet/models/webhook_secret.py +58 -0
- smartsheet/models/webhook_stats.py +76 -0
- smartsheet/models/webhook_subscope.py +50 -0
- smartsheet/models/widget.py +211 -0
- smartsheet/models/widget_content.py +52 -0
- smartsheet/models/widget_hyperlink.py +74 -0
- smartsheet/models/workspace.py +185 -0
- smartsheet/object_value.py +72 -0
- smartsheet/passthrough.py +127 -0
- smartsheet/reports.py +382 -0
- smartsheet/search.py +100 -0
- smartsheet/server.py +48 -0
- smartsheet/session.py +70 -0
- smartsheet/sharing.py +163 -0
- smartsheet/sheets.py +2062 -0
- smartsheet/sights.py +370 -0
- smartsheet/smartsheet.py +684 -0
- smartsheet/templates.py +87 -0
- smartsheet/token.py +128 -0
- smartsheet/types.py +323 -0
- smartsheet/users.py +490 -0
- smartsheet/util.py +199 -0
- smartsheet/version.py +34 -0
- smartsheet/webhooks.py +161 -0
- smartsheet/workspaces.py +647 -0
- smartsheet_python_sdk-3.5.5.dist-info/METADATA +120 -0
- smartsheet_python_sdk-3.5.5.dist-info/RECORD +195 -0
- smartsheet_python_sdk-3.5.5.dist-info/WHEEL +5 -0
- smartsheet_python_sdk-3.5.5.dist-info/licenses/LICENSE.md +201 -0
- smartsheet_python_sdk-3.5.5.dist-info/licenses/NOTICE +10 -0
- smartsheet_python_sdk-3.5.5.dist-info/top_level.txt +1 -0
smartsheet/reports.py
ADDED
|
@@ -0,0 +1,382 @@
|
|
|
1
|
+
# pylint: disable=C0111,R0902,R0913
|
|
2
|
+
# Smartsheet Python SDK.
|
|
3
|
+
#
|
|
4
|
+
# Copyright 2016 Smartsheet.com, Inc.
|
|
5
|
+
#
|
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License"): you may
|
|
7
|
+
# not use this file except in compliance with the License. You may obtain
|
|
8
|
+
# a copy of the License at
|
|
9
|
+
#
|
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
+
#
|
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
14
|
+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
15
|
+
# License for the specific language governing permissions and limitations
|
|
16
|
+
# under the License.
|
|
17
|
+
|
|
18
|
+
from __future__ import absolute_import
|
|
19
|
+
|
|
20
|
+
import logging
|
|
21
|
+
import os.path
|
|
22
|
+
from datetime import datetime
|
|
23
|
+
|
|
24
|
+
from . import fresh_operation
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class Reports:
|
|
28
|
+
|
|
29
|
+
"""Class for handling Reports operations."""
|
|
30
|
+
|
|
31
|
+
def __init__(self, smartsheet_obj):
|
|
32
|
+
"""Init Reports with base Smartsheet object."""
|
|
33
|
+
self._base = smartsheet_obj
|
|
34
|
+
self._log = logging.getLogger(__name__)
|
|
35
|
+
|
|
36
|
+
def delete_share(self, report_id, share_id):
|
|
37
|
+
"""Deletes the specified Share
|
|
38
|
+
|
|
39
|
+
Args:
|
|
40
|
+
report_id (int): Report ID
|
|
41
|
+
share_id (str): Share ID
|
|
42
|
+
|
|
43
|
+
Returns:
|
|
44
|
+
Result
|
|
45
|
+
"""
|
|
46
|
+
_op = fresh_operation("delete_share")
|
|
47
|
+
_op["method"] = "DELETE"
|
|
48
|
+
_op["path"] = "/reports/" + str(report_id) + "/shares/" + str(share_id)
|
|
49
|
+
|
|
50
|
+
expected = ["Result", None]
|
|
51
|
+
prepped_request = self._base.prepare_request(_op)
|
|
52
|
+
response = self._base.request(prepped_request, expected, _op)
|
|
53
|
+
|
|
54
|
+
return response
|
|
55
|
+
|
|
56
|
+
def get_report(
|
|
57
|
+
self, report_id, page_size=None, page=None, include=None, level=None
|
|
58
|
+
):
|
|
59
|
+
"""Get the specified Report, including one page of Rows.
|
|
60
|
+
|
|
61
|
+
Get the specified Report, including one page of Rows, and
|
|
62
|
+
optionally populated with Discussions, Attachments, and
|
|
63
|
+
Source Sheets.
|
|
64
|
+
|
|
65
|
+
Args:
|
|
66
|
+
report_id (int): Report ID
|
|
67
|
+
page_size (int): The maximum number of items to return per page.
|
|
68
|
+
page (int): Which page to return.
|
|
69
|
+
include (list[str]): A comma-separated list of
|
|
70
|
+
optional elements to include in the response. Valid list values:
|
|
71
|
+
attachments, discussions, format, objectValue, scope, source, sourceSheets.
|
|
72
|
+
level (int): compatibility level
|
|
73
|
+
|
|
74
|
+
Returns:
|
|
75
|
+
Report
|
|
76
|
+
"""
|
|
77
|
+
_op = fresh_operation("get_report")
|
|
78
|
+
_op["method"] = "GET"
|
|
79
|
+
_op["path"] = "/reports/" + str(report_id)
|
|
80
|
+
_op["query_params"]["pageSize"] = page_size
|
|
81
|
+
_op["query_params"]["page"] = page
|
|
82
|
+
_op["query_params"]["include"] = include
|
|
83
|
+
_op["query_params"]["level"] = level
|
|
84
|
+
|
|
85
|
+
expected = "Report"
|
|
86
|
+
prepped_request = self._base.prepare_request(_op)
|
|
87
|
+
response = self._base.request(prepped_request, expected, _op)
|
|
88
|
+
|
|
89
|
+
return response
|
|
90
|
+
|
|
91
|
+
def get_report_as_csv(self, report_id, download_path, alternate_file_name=None):
|
|
92
|
+
"""Get the specified Report as a CSV file.
|
|
93
|
+
|
|
94
|
+
Args:
|
|
95
|
+
report_id (int): Report ID
|
|
96
|
+
download_path (str): Directory path on local
|
|
97
|
+
machine to save file.
|
|
98
|
+
alternate_file_name (str): Filename to use
|
|
99
|
+
instead of name suggested by Content-Disposition.
|
|
100
|
+
|
|
101
|
+
Returns:
|
|
102
|
+
DownloadedFile
|
|
103
|
+
"""
|
|
104
|
+
if not os.path.isdir(download_path):
|
|
105
|
+
raise ValueError("download_path must be a directory.")
|
|
106
|
+
|
|
107
|
+
_op = fresh_operation("get_report_as_csv")
|
|
108
|
+
_op["method"] = "GET"
|
|
109
|
+
_op["path"] = "/reports/" + str(report_id)
|
|
110
|
+
_op["header_params"]["Accept"] = "text/csv"
|
|
111
|
+
_op["dl_path"] = download_path
|
|
112
|
+
|
|
113
|
+
expected = "DownloadedFile"
|
|
114
|
+
prepped_request = self._base.prepare_request(_op)
|
|
115
|
+
response = self._base.request(prepped_request, expected, _op)
|
|
116
|
+
if alternate_file_name is not None:
|
|
117
|
+
response.filename = alternate_file_name
|
|
118
|
+
|
|
119
|
+
response.save_to_file()
|
|
120
|
+
return response
|
|
121
|
+
|
|
122
|
+
def get_report_as_excel(self, report_id, download_path, alternate_file_name=None):
|
|
123
|
+
"""Get the specified Report as an Excel .xls document.
|
|
124
|
+
|
|
125
|
+
Args:
|
|
126
|
+
report_id (int): Report ID
|
|
127
|
+
download_path (str): Directory path on local
|
|
128
|
+
machine to save file.
|
|
129
|
+
alternate_file_name (str): Filename to use
|
|
130
|
+
instead of name suggested by Content-Disposition.
|
|
131
|
+
|
|
132
|
+
Returns:
|
|
133
|
+
DownloadedFile
|
|
134
|
+
"""
|
|
135
|
+
if not os.path.isdir(download_path):
|
|
136
|
+
raise ValueError("download_path must be a directory.")
|
|
137
|
+
|
|
138
|
+
_op = fresh_operation("get_report_as_excel")
|
|
139
|
+
_op["method"] = "GET"
|
|
140
|
+
_op["path"] = "/reports/" + str(report_id)
|
|
141
|
+
_op["header_params"]["Accept"] = "application/vnd.ms-excel"
|
|
142
|
+
_op["dl_path"] = download_path
|
|
143
|
+
|
|
144
|
+
expected = "DownloadedFile"
|
|
145
|
+
prepped_request = self._base.prepare_request(_op)
|
|
146
|
+
response = self._base.request(prepped_request, expected, _op)
|
|
147
|
+
if alternate_file_name is not None:
|
|
148
|
+
response.filename = alternate_file_name
|
|
149
|
+
|
|
150
|
+
response.save_to_file()
|
|
151
|
+
return response
|
|
152
|
+
|
|
153
|
+
def get_share(self, report_id, share_id):
|
|
154
|
+
"""Get the specified Share.
|
|
155
|
+
|
|
156
|
+
Args:
|
|
157
|
+
report_id (int): Report ID
|
|
158
|
+
share_id (str): Share ID
|
|
159
|
+
|
|
160
|
+
Returns:
|
|
161
|
+
Share
|
|
162
|
+
"""
|
|
163
|
+
_op = fresh_operation("get_share")
|
|
164
|
+
_op["method"] = "GET"
|
|
165
|
+
_op["path"] = "/reports/" + str(report_id) + "/shares/" + str(share_id)
|
|
166
|
+
|
|
167
|
+
expected = "Share"
|
|
168
|
+
prepped_request = self._base.prepare_request(_op)
|
|
169
|
+
response = self._base.request(prepped_request, expected, _op)
|
|
170
|
+
|
|
171
|
+
return response
|
|
172
|
+
|
|
173
|
+
def list_reports(
|
|
174
|
+
self, page_size=None, page=None, include_all=None, modified_since=None
|
|
175
|
+
):
|
|
176
|
+
"""Get the list of all Reports accessible by the User.
|
|
177
|
+
|
|
178
|
+
Get the list of all Reports that the User has access to, in
|
|
179
|
+
alphabetical order by name.
|
|
180
|
+
|
|
181
|
+
Args:
|
|
182
|
+
page_size (int): The maximum number of items to
|
|
183
|
+
return per page.
|
|
184
|
+
page (int): Which page to return.
|
|
185
|
+
include_all (bool): If true, include all results
|
|
186
|
+
(i.e. do not paginate).
|
|
187
|
+
modified_since(datetime): return reports modified after the specified modified_since
|
|
188
|
+
|
|
189
|
+
Returns:
|
|
190
|
+
IndexResult
|
|
191
|
+
"""
|
|
192
|
+
_op = fresh_operation("list_reports")
|
|
193
|
+
_op["method"] = "GET"
|
|
194
|
+
_op["path"] = "/reports"
|
|
195
|
+
_op["query_params"]["pageSize"] = page_size
|
|
196
|
+
_op["query_params"]["page"] = page
|
|
197
|
+
_op["query_params"]["includeAll"] = include_all
|
|
198
|
+
if isinstance(modified_since, datetime):
|
|
199
|
+
_op["query_params"]["modifiedSince"] = modified_since.isoformat()
|
|
200
|
+
|
|
201
|
+
expected = ["IndexResult", "Report"]
|
|
202
|
+
|
|
203
|
+
prepped_request = self._base.prepare_request(_op)
|
|
204
|
+
response = self._base.request(prepped_request, expected, _op)
|
|
205
|
+
|
|
206
|
+
return response
|
|
207
|
+
|
|
208
|
+
def list_shares(
|
|
209
|
+
self,
|
|
210
|
+
report_id,
|
|
211
|
+
page_size=None,
|
|
212
|
+
page=None,
|
|
213
|
+
include_all=None,
|
|
214
|
+
include_workspace_shares=False,
|
|
215
|
+
):
|
|
216
|
+
"""Get a list of all Users and Groups to whom the specified Report is
|
|
217
|
+
shared, and their access level.
|
|
218
|
+
|
|
219
|
+
Args:
|
|
220
|
+
report_id (int): Report ID
|
|
221
|
+
page_size (int): The maximum number of items to
|
|
222
|
+
return per page.
|
|
223
|
+
page (int): Which page to return.
|
|
224
|
+
include_all (bool): If true, include all results
|
|
225
|
+
(i.e. do not paginate).
|
|
226
|
+
include_workspace_shares(bool): include Workspace shares
|
|
227
|
+
|
|
228
|
+
Returns:
|
|
229
|
+
IndexResult
|
|
230
|
+
"""
|
|
231
|
+
_op = fresh_operation("list_shares")
|
|
232
|
+
_op["method"] = "GET"
|
|
233
|
+
_op["path"] = "/reports/" + str(report_id) + "/shares"
|
|
234
|
+
_op["query_params"]["pageSize"] = page_size
|
|
235
|
+
_op["query_params"]["page"] = page
|
|
236
|
+
_op["query_params"]["includeAll"] = include_all
|
|
237
|
+
if include_workspace_shares:
|
|
238
|
+
_op["query_params"]["include"] = "workspaceShares"
|
|
239
|
+
|
|
240
|
+
expected = ["IndexResult", "Share"]
|
|
241
|
+
|
|
242
|
+
prepped_request = self._base.prepare_request(_op)
|
|
243
|
+
response = self._base.request(prepped_request, expected, _op)
|
|
244
|
+
|
|
245
|
+
return response
|
|
246
|
+
|
|
247
|
+
def send_report(self, report_id, sheet_email_obj):
|
|
248
|
+
"""Send the specified Report as a PDF attachment via email to the
|
|
249
|
+
designated recipients.
|
|
250
|
+
|
|
251
|
+
Args:
|
|
252
|
+
report_id (int): Report ID
|
|
253
|
+
sheet_email_obj (SheetEmail): SheetEmail object.
|
|
254
|
+
|
|
255
|
+
Returns:
|
|
256
|
+
Result
|
|
257
|
+
"""
|
|
258
|
+
_op = fresh_operation("send_report")
|
|
259
|
+
_op["method"] = "POST"
|
|
260
|
+
_op["path"] = "/reports/" + str(report_id) + "/emails"
|
|
261
|
+
_op["json"] = sheet_email_obj
|
|
262
|
+
|
|
263
|
+
expected = ["Result", None]
|
|
264
|
+
prepped_request = self._base.prepare_request(_op)
|
|
265
|
+
response = self._base.request(prepped_request, expected, _op)
|
|
266
|
+
|
|
267
|
+
return response
|
|
268
|
+
|
|
269
|
+
def share_report(self, report_id, share_obj, send_email=False):
|
|
270
|
+
"""Shares a Report with the specified Users and Groups.
|
|
271
|
+
|
|
272
|
+
Args:
|
|
273
|
+
report_id (int): Report ID
|
|
274
|
+
share_obj (Share): Share object.
|
|
275
|
+
send_email (bool): Either true or false to
|
|
276
|
+
indicate whether or not to notify the user by email. Default
|
|
277
|
+
is false.
|
|
278
|
+
|
|
279
|
+
Returns:
|
|
280
|
+
Result
|
|
281
|
+
"""
|
|
282
|
+
_op = fresh_operation("share_report")
|
|
283
|
+
_op["method"] = "POST"
|
|
284
|
+
_op["path"] = "/reports/" + str(report_id) + "/shares"
|
|
285
|
+
_op["query_params"]["sendEmail"] = send_email
|
|
286
|
+
_op["json"] = share_obj
|
|
287
|
+
|
|
288
|
+
expected = ["Result", "Share"]
|
|
289
|
+
|
|
290
|
+
prepped_request = self._base.prepare_request(_op)
|
|
291
|
+
response = self._base.request(prepped_request, expected, _op)
|
|
292
|
+
|
|
293
|
+
return response
|
|
294
|
+
|
|
295
|
+
def update_share(self, report_id, share_id, share_obj):
|
|
296
|
+
"""Update the access level of a User or Group for the specified Report
|
|
297
|
+
|
|
298
|
+
Args:
|
|
299
|
+
report_id (int): Report ID
|
|
300
|
+
share_id (str): Share ID
|
|
301
|
+
share_obj (Share): Share object.
|
|
302
|
+
|
|
303
|
+
Returns:
|
|
304
|
+
Result
|
|
305
|
+
"""
|
|
306
|
+
if not all(val is not None for val in ["report_id", "share_id", "share_obj"]):
|
|
307
|
+
raise ValueError(
|
|
308
|
+
("One or more required values are missing from call to " + __name__)
|
|
309
|
+
)
|
|
310
|
+
|
|
311
|
+
_op = fresh_operation("update_share")
|
|
312
|
+
_op["method"] = "PUT"
|
|
313
|
+
_op["path"] = "/reports/" + str(report_id) + "/shares/" + str(share_id)
|
|
314
|
+
_op["json"] = share_obj
|
|
315
|
+
|
|
316
|
+
expected = ["Result", "Share"]
|
|
317
|
+
|
|
318
|
+
prepped_request = self._base.prepare_request(_op)
|
|
319
|
+
response = self._base.request(prepped_request, expected, _op)
|
|
320
|
+
|
|
321
|
+
return response
|
|
322
|
+
|
|
323
|
+
def get_publish_status(self, report_id):
|
|
324
|
+
"""Get the Publish status of the Report.
|
|
325
|
+
|
|
326
|
+
Get the status of the Publish settings of the Report,
|
|
327
|
+
including URLs of any enabled publishings.
|
|
328
|
+
|
|
329
|
+
Args:
|
|
330
|
+
report_id (int): Report ID
|
|
331
|
+
|
|
332
|
+
Returns:
|
|
333
|
+
ReportPublish
|
|
334
|
+
"""
|
|
335
|
+
_op = fresh_operation("get_publish_status")
|
|
336
|
+
_op["method"] = "GET"
|
|
337
|
+
_op["path"] = "/reports/" + str(report_id) + "/publish"
|
|
338
|
+
|
|
339
|
+
expected = "ReportPublish"
|
|
340
|
+
prepped_request = self._base.prepare_request(_op)
|
|
341
|
+
response = self._base.request(prepped_request, expected, _op)
|
|
342
|
+
|
|
343
|
+
return response
|
|
344
|
+
|
|
345
|
+
def set_publish_status(self, report_id, report_publish_obj):
|
|
346
|
+
"""Set the publish status of the Report and returns the new status,
|
|
347
|
+
including the URLs of any enabled publishings.
|
|
348
|
+
|
|
349
|
+
Args:
|
|
350
|
+
report_id (int): Report ID
|
|
351
|
+
report_publish_obj (ReportPublish): ReportPublish
|
|
352
|
+
object.
|
|
353
|
+
|
|
354
|
+
Returns:
|
|
355
|
+
Result
|
|
356
|
+
"""
|
|
357
|
+
attributes = ["read_only_full_enabled", "read_only_full_accessible_by"]
|
|
358
|
+
|
|
359
|
+
fetch_first = False
|
|
360
|
+
# check for incompleteness, fill in from current status if necessary
|
|
361
|
+
for attribute in attributes:
|
|
362
|
+
val = getattr(report_publish_obj, attribute, None)
|
|
363
|
+
if val is None:
|
|
364
|
+
fetch_first = True
|
|
365
|
+
break
|
|
366
|
+
|
|
367
|
+
if fetch_first:
|
|
368
|
+
current_status = self.get_publish_status(report_id).to_dict()
|
|
369
|
+
current_status.update(report_publish_obj.to_dict())
|
|
370
|
+
report_publish_obj = self._base.models.ReportPublish(current_status)
|
|
371
|
+
|
|
372
|
+
_op = fresh_operation("set_publish_status")
|
|
373
|
+
_op["method"] = "PUT"
|
|
374
|
+
_op["path"] = "/reports/" + str(report_id) + "/publish"
|
|
375
|
+
_op["json"] = report_publish_obj
|
|
376
|
+
|
|
377
|
+
expected = ["Result", "ReportPublish"]
|
|
378
|
+
|
|
379
|
+
prepped_request = self._base.prepare_request(_op)
|
|
380
|
+
response = self._base.request(prepped_request, expected, _op)
|
|
381
|
+
|
|
382
|
+
return response
|
smartsheet/search.py
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# pylint: disable=C0111,R0902,R0913
|
|
2
|
+
# Smartsheet Python SDK.
|
|
3
|
+
#
|
|
4
|
+
# Copyright 2016 Smartsheet.com, Inc.
|
|
5
|
+
#
|
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License"): you may
|
|
7
|
+
# not use this file except in compliance with the License. You may obtain
|
|
8
|
+
# a copy of the License at
|
|
9
|
+
#
|
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
+
#
|
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
14
|
+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
15
|
+
# License for the specific language governing permissions and limitations
|
|
16
|
+
# under the License.
|
|
17
|
+
|
|
18
|
+
from __future__ import absolute_import
|
|
19
|
+
|
|
20
|
+
import logging
|
|
21
|
+
from datetime import datetime
|
|
22
|
+
|
|
23
|
+
from . import fresh_operation
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class Search:
|
|
27
|
+
|
|
28
|
+
"""Class for handling Search operations."""
|
|
29
|
+
|
|
30
|
+
def __init__(self, smartsheet_obj):
|
|
31
|
+
"""Init Search with base Smartsheet object."""
|
|
32
|
+
self._base = smartsheet_obj
|
|
33
|
+
self._log = logging.getLogger(__name__)
|
|
34
|
+
|
|
35
|
+
def search(
|
|
36
|
+
self, query, include=None, location=None, modified_since=None, scopes=None
|
|
37
|
+
):
|
|
38
|
+
"""Search all Sheets the User can access for the specified text.
|
|
39
|
+
|
|
40
|
+
Args:
|
|
41
|
+
query (str): Text with which to perform the search.
|
|
42
|
+
include (str): when specified with a value of 'favoriteFlag',
|
|
43
|
+
response indicates which returned items are favorites
|
|
44
|
+
location (str): when specified with a value of 'personalWorkspace',
|
|
45
|
+
limits the response to only those items in the user's Workspaces
|
|
46
|
+
modified_since (str): includes items that are modified on or after the
|
|
47
|
+
date and time specified
|
|
48
|
+
scopes (str): comma-separated list of search filters:
|
|
49
|
+
attachments
|
|
50
|
+
cellData
|
|
51
|
+
comments
|
|
52
|
+
folderNames
|
|
53
|
+
profileFields
|
|
54
|
+
reportNames
|
|
55
|
+
sheetNames
|
|
56
|
+
sightNames
|
|
57
|
+
summaryFields
|
|
58
|
+
templateNames
|
|
59
|
+
workspaceNames
|
|
60
|
+
|
|
61
|
+
Returns:
|
|
62
|
+
SearchResult
|
|
63
|
+
"""
|
|
64
|
+
_op = fresh_operation("search")
|
|
65
|
+
_op["method"] = "GET"
|
|
66
|
+
_op["path"] = "/search"
|
|
67
|
+
_op["query_params"]["query"] = query
|
|
68
|
+
_op["query_params"]["include"] = include
|
|
69
|
+
_op["query_params"]["location"] = location
|
|
70
|
+
_op["query_params"]["scopes"] = scopes
|
|
71
|
+
if isinstance(modified_since, datetime):
|
|
72
|
+
_op["query_params"]["modifiedSince"] = modified_since.isoformat()
|
|
73
|
+
|
|
74
|
+
expected = "SearchResult"
|
|
75
|
+
prepped_request = self._base.prepare_request(_op)
|
|
76
|
+
response = self._base.request(prepped_request, expected, _op)
|
|
77
|
+
|
|
78
|
+
return response
|
|
79
|
+
|
|
80
|
+
def search_sheet(self, sheet_id, query):
|
|
81
|
+
"""Search the specified Sheet for the specified text.
|
|
82
|
+
|
|
83
|
+
Args:
|
|
84
|
+
sheet_id (int): Sheet ID
|
|
85
|
+
query (str): Text with which to perform the
|
|
86
|
+
search.
|
|
87
|
+
|
|
88
|
+
Returns:
|
|
89
|
+
SearchResult
|
|
90
|
+
"""
|
|
91
|
+
_op = fresh_operation("search_sheet")
|
|
92
|
+
_op["method"] = "GET"
|
|
93
|
+
_op["path"] = "/search/sheets/" + str(sheet_id)
|
|
94
|
+
_op["query_params"]["query"] = query
|
|
95
|
+
|
|
96
|
+
expected = "SearchResult"
|
|
97
|
+
prepped_request = self._base.prepare_request(_op)
|
|
98
|
+
response = self._base.request(prepped_request, expected, _op)
|
|
99
|
+
|
|
100
|
+
return response
|
smartsheet/server.py
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# pylint: disable=C0111,R0902,R0913
|
|
2
|
+
# Smartsheet Python SDK.
|
|
3
|
+
#
|
|
4
|
+
# Copyright 2016 Smartsheet.com, Inc.
|
|
5
|
+
#
|
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License"): you may
|
|
7
|
+
# not use this file except in compliance with the License. You may obtain
|
|
8
|
+
# a copy of the License at
|
|
9
|
+
#
|
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
+
#
|
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
14
|
+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
15
|
+
# License for the specific language governing permissions and limitations
|
|
16
|
+
# under the License.
|
|
17
|
+
|
|
18
|
+
from __future__ import absolute_import
|
|
19
|
+
|
|
20
|
+
import logging
|
|
21
|
+
|
|
22
|
+
from . import fresh_operation
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class Server:
|
|
26
|
+
|
|
27
|
+
"""Class for handling Server operations."""
|
|
28
|
+
|
|
29
|
+
def __init__(self, smartsheet_obj):
|
|
30
|
+
"""Init Server with base Smartsheet object."""
|
|
31
|
+
self._base = smartsheet_obj
|
|
32
|
+
self._log = logging.getLogger(__name__)
|
|
33
|
+
|
|
34
|
+
def server_info(self):
|
|
35
|
+
"""Get application constants.
|
|
36
|
+
Returns:
|
|
37
|
+
ServerInfo
|
|
38
|
+
"""
|
|
39
|
+
_op = fresh_operation("server_info")
|
|
40
|
+
_op["method"] = "GET"
|
|
41
|
+
_op["path"] = "/serverinfo"
|
|
42
|
+
_op["auth_settings"] = None
|
|
43
|
+
|
|
44
|
+
expected = "ServerInfo"
|
|
45
|
+
prepped_request = self._base.prepare_request(_op)
|
|
46
|
+
response = self._base.request(prepped_request, expected, _op)
|
|
47
|
+
|
|
48
|
+
return response
|
smartsheet/session.py
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# pylint: disable=E0401,W0221,W0613
|
|
2
|
+
# Smartsheet Python SDK.
|
|
3
|
+
#
|
|
4
|
+
# Copyright 2016 Smartsheet.com, Inc.
|
|
5
|
+
#
|
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License"): you may
|
|
7
|
+
# not use this file except in compliance with the License. You may obtain
|
|
8
|
+
# a copy of the License at
|
|
9
|
+
#
|
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
+
#
|
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
14
|
+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
15
|
+
# License for the specific language governing permissions and limitations
|
|
16
|
+
# under the License.
|
|
17
|
+
|
|
18
|
+
# pylint: disable=no-member
|
|
19
|
+
# known issue regarding ssl module and pylint.
|
|
20
|
+
|
|
21
|
+
import ssl
|
|
22
|
+
|
|
23
|
+
import certifi
|
|
24
|
+
import requests
|
|
25
|
+
from requests.adapters import HTTPAdapter
|
|
26
|
+
from requests.packages.urllib3.poolmanager import PoolManager
|
|
27
|
+
from requests.packages.urllib3.util import Retry
|
|
28
|
+
|
|
29
|
+
_TRUSTED_CERT_FILE = certifi.where()
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class _SSLAdapter(HTTPAdapter):
|
|
33
|
+
def create_ssl_context(self):
|
|
34
|
+
ctx = ssl.create_default_context()
|
|
35
|
+
ctx.options |= ssl.OP_NO_SSLv2
|
|
36
|
+
ctx.options |= ssl.OP_NO_SSLv3
|
|
37
|
+
ctx.options |= ssl.OP_NO_TLSv1
|
|
38
|
+
return ctx
|
|
39
|
+
|
|
40
|
+
def init_poolmanager(self, connections, maxsize, block=False):
|
|
41
|
+
self.poolmanager = PoolManager(
|
|
42
|
+
num_pools=connections,
|
|
43
|
+
maxsize=maxsize,
|
|
44
|
+
block=block,
|
|
45
|
+
cert_reqs=ssl.CERT_REQUIRED,
|
|
46
|
+
ca_certs=_TRUSTED_CERT_FILE,
|
|
47
|
+
ssl_context=self.create_ssl_context(),
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def pinned_session(pool_maxsize=8):
|
|
52
|
+
http_adapter = _SSLAdapter(
|
|
53
|
+
pool_connections=4,
|
|
54
|
+
pool_maxsize=pool_maxsize,
|
|
55
|
+
max_retries=Retry(
|
|
56
|
+
total=1, allowed_methods=Retry.DEFAULT_ALLOWED_METHODS.union(["POST"])
|
|
57
|
+
),
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
_session = requests.session()
|
|
61
|
+
_session.hooks = {"response": redact_token}
|
|
62
|
+
_session.mount("https://", http_adapter)
|
|
63
|
+
|
|
64
|
+
return _session
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def redact_token(res, *args, **kwargs):
|
|
68
|
+
if "Authorization" in res.request.headers:
|
|
69
|
+
res.request.headers.update({"Authorization": "[redacted]"})
|
|
70
|
+
return res
|