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/templates.py
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
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 Templates:
|
|
26
|
+
|
|
27
|
+
"""Class for handling Templates operations."""
|
|
28
|
+
|
|
29
|
+
def __init__(self, smartsheet_obj):
|
|
30
|
+
"""Init Templates with base Smartsheet object."""
|
|
31
|
+
self._base = smartsheet_obj
|
|
32
|
+
self._log = logging.getLogger(__name__)
|
|
33
|
+
|
|
34
|
+
def list_public_templates(self, page_size=None, page=None, include_all=None):
|
|
35
|
+
"""Get the list of public Templates to which the User has access.
|
|
36
|
+
|
|
37
|
+
Args:
|
|
38
|
+
page_size (int): The maximum number of items to
|
|
39
|
+
return per page.
|
|
40
|
+
page (int): Which page to return.
|
|
41
|
+
include_all (bool): If true, include all results
|
|
42
|
+
(i.e. do not paginate).
|
|
43
|
+
|
|
44
|
+
Returns:
|
|
45
|
+
IndexResult
|
|
46
|
+
"""
|
|
47
|
+
_op = fresh_operation("list_public_templates")
|
|
48
|
+
_op["method"] = "GET"
|
|
49
|
+
_op["path"] = "/templates/public"
|
|
50
|
+
_op["query_params"]["pageSize"] = page_size
|
|
51
|
+
_op["query_params"]["page"] = page
|
|
52
|
+
_op["query_params"]["includeAll"] = include_all
|
|
53
|
+
|
|
54
|
+
expected = ["IndexResult", "Template"]
|
|
55
|
+
|
|
56
|
+
prepped_request = self._base.prepare_request(_op)
|
|
57
|
+
response = self._base.request(prepped_request, expected, _op)
|
|
58
|
+
|
|
59
|
+
return response
|
|
60
|
+
|
|
61
|
+
def list_user_created_templates(self, page_size=None, page=None, include_all=None):
|
|
62
|
+
"""Get the list of user-created Templates to which the user has
|
|
63
|
+
access.
|
|
64
|
+
|
|
65
|
+
Args:
|
|
66
|
+
page_size (int): The maximum number of items to
|
|
67
|
+
return per page.
|
|
68
|
+
page (int): Which page to return.
|
|
69
|
+
include_all (bool): If true, include all results
|
|
70
|
+
(i.e. do not paginate).
|
|
71
|
+
|
|
72
|
+
Returns:
|
|
73
|
+
IndexResult
|
|
74
|
+
"""
|
|
75
|
+
_op = fresh_operation("list_user_created_templates")
|
|
76
|
+
_op["method"] = "GET"
|
|
77
|
+
_op["path"] = "/templates"
|
|
78
|
+
_op["query_params"]["pageSize"] = page_size
|
|
79
|
+
_op["query_params"]["page"] = page
|
|
80
|
+
_op["query_params"]["includeAll"] = include_all
|
|
81
|
+
|
|
82
|
+
expected = ["IndexResult", "Template"]
|
|
83
|
+
|
|
84
|
+
prepped_request = self._base.prepare_request(_op)
|
|
85
|
+
response = self._base.request(prepped_request, expected, _op)
|
|
86
|
+
|
|
87
|
+
return response
|
smartsheet/token.py
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
# pylint: disable=C0111,R0902,R0913,E1137
|
|
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 Token:
|
|
26
|
+
|
|
27
|
+
"""Class for handling Token operations."""
|
|
28
|
+
|
|
29
|
+
def __init__(self, smartsheet_obj):
|
|
30
|
+
"""Init Token with base Smartsheet object."""
|
|
31
|
+
self._base = smartsheet_obj
|
|
32
|
+
self._log = logging.getLogger(__name__)
|
|
33
|
+
|
|
34
|
+
def get_access_token(self, client_id, code, _hash, redirect_uri=None):
|
|
35
|
+
"""Get an access token, as part of the OAuth process. For more
|
|
36
|
+
information, see [OAuth
|
|
37
|
+
Flow](http://smartsheet-platform.github.io/api-docs/index.html#oauth-flow)
|
|
38
|
+
|
|
39
|
+
Args:
|
|
40
|
+
client_id (str)
|
|
41
|
+
code (str)
|
|
42
|
+
_hash (str): SHA-256 hash of your `app_secret`
|
|
43
|
+
concatenated with a pipe and the authorization `code`.
|
|
44
|
+
redirect_uri (str): Redirect URL registered for
|
|
45
|
+
your app, including protocol (e.g. \"http://\"); if not
|
|
46
|
+
provided, the redirect URL set during registration is used.
|
|
47
|
+
|
|
48
|
+
Returns:
|
|
49
|
+
AccessToken
|
|
50
|
+
"""
|
|
51
|
+
if not all(val is not None for val in ["client_id", "code", "_hash"]):
|
|
52
|
+
raise ValueError(
|
|
53
|
+
("One or more required values are missing from call to " + __name__)
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
_op = fresh_operation("get_access_token")
|
|
57
|
+
_op["method"] = "POST"
|
|
58
|
+
_op["path"] = "/token"
|
|
59
|
+
_op["form_data"] = {}
|
|
60
|
+
_op["form_data"]["grant_type"] = "authorization_code"
|
|
61
|
+
_op["form_data"]["client_id"] = client_id
|
|
62
|
+
_op["form_data"]["code"] = code
|
|
63
|
+
_op["form_data"]["redirect_uri"] = redirect_uri
|
|
64
|
+
_op["form_data"]["hash"] = _hash
|
|
65
|
+
_op["auth_settings"] = None
|
|
66
|
+
|
|
67
|
+
expected = "AccessToken"
|
|
68
|
+
prepped_request = self._base.prepare_request(_op)
|
|
69
|
+
response = self._base.request(prepped_request, expected, _op)
|
|
70
|
+
|
|
71
|
+
return response
|
|
72
|
+
|
|
73
|
+
def refresh_access_token(self, client_id, refresh_token, _hash, redirect_uri=None):
|
|
74
|
+
"""Refresh an access token, as part of the OAuth process. For more
|
|
75
|
+
information, see [OAuth
|
|
76
|
+
Flow](http://smartsheet-platform.github.io/api-docs/index.html#oauth-flow)
|
|
77
|
+
|
|
78
|
+
Args:
|
|
79
|
+
client_id (str)
|
|
80
|
+
refresh_token (str)
|
|
81
|
+
_hash (str): SHA-256 hash of your `app_secret`
|
|
82
|
+
concatenated with a pipe and the refresh token value.
|
|
83
|
+
redirect_uri (str): Redirect URL registered for
|
|
84
|
+
your app, including protocol (e.g. \"http://\"); if not
|
|
85
|
+
provided, the redirect URL set during registration is used.
|
|
86
|
+
|
|
87
|
+
Returns:
|
|
88
|
+
AccessToken
|
|
89
|
+
"""
|
|
90
|
+
if not all(val is not None for val in ["client_id", "refresh_token", "_hash"]):
|
|
91
|
+
raise ValueError(
|
|
92
|
+
("One or more required values are missing from call to " + __name__)
|
|
93
|
+
)
|
|
94
|
+
|
|
95
|
+
_op = fresh_operation("refresh_access_token")
|
|
96
|
+
_op["method"] = "POST"
|
|
97
|
+
_op["path"] = "/token"
|
|
98
|
+
_op["form_data"] = {}
|
|
99
|
+
_op["form_data"]["grant_type"] = "refresh_token"
|
|
100
|
+
_op["form_data"]["client_id"] = client_id
|
|
101
|
+
_op["form_data"]["refresh_token"] = refresh_token
|
|
102
|
+
_op["form_data"]["redirect_uri"] = redirect_uri
|
|
103
|
+
_op["form_data"]["hash"] = _hash
|
|
104
|
+
|
|
105
|
+
expected = "AccessToken"
|
|
106
|
+
prepped_request = self._base.prepare_request(_op)
|
|
107
|
+
response = self._base.request(prepped_request, expected, _op)
|
|
108
|
+
|
|
109
|
+
return response
|
|
110
|
+
|
|
111
|
+
def revoke_access_token(self):
|
|
112
|
+
"""Revoke the access token used to make the request.
|
|
113
|
+
|
|
114
|
+
Revoke the access token used to make the request. The
|
|
115
|
+
access token will no longer be valid, and subsequent API calls
|
|
116
|
+
using the token will fail.
|
|
117
|
+
Returns:
|
|
118
|
+
Result
|
|
119
|
+
"""
|
|
120
|
+
_op = fresh_operation("revoke_access_token")
|
|
121
|
+
_op["method"] = "DELETE"
|
|
122
|
+
_op["path"] = "/token"
|
|
123
|
+
|
|
124
|
+
expected = ["Result", None]
|
|
125
|
+
prepped_request = self._base.prepare_request(_op)
|
|
126
|
+
response = self._base.request(prepped_request, expected, _op)
|
|
127
|
+
|
|
128
|
+
return response
|
smartsheet/types.py
ADDED
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
# pylint: disable=C0111,R0902,R0913,W4904,W0706,W0237
|
|
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
|
+
try:
|
|
19
|
+
# For Python version >= 3.10 import from collections.abc
|
|
20
|
+
from collections.abc import MutableSequence
|
|
21
|
+
except ImportError:
|
|
22
|
+
# For Python versions 2.7 and 3.3 to 3.9, import from collections
|
|
23
|
+
from collections import MutableSequence
|
|
24
|
+
|
|
25
|
+
import importlib
|
|
26
|
+
import json
|
|
27
|
+
import logging
|
|
28
|
+
from datetime import datetime
|
|
29
|
+
from enum import Enum
|
|
30
|
+
|
|
31
|
+
import six
|
|
32
|
+
from dateutil.parser import parse
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class TypedList(MutableSequence):
|
|
36
|
+
def __init__(self, item_type):
|
|
37
|
+
self.item_type = item_type
|
|
38
|
+
self.__store = []
|
|
39
|
+
self._log = logging.getLogger(__name__)
|
|
40
|
+
if isinstance(self.item_type, six.string_types):
|
|
41
|
+
self.item_type = getattr(
|
|
42
|
+
importlib.import_module(
|
|
43
|
+
__package__ + ".models." + self.item_type.lower()
|
|
44
|
+
),
|
|
45
|
+
self.item_type,
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
def __len__(self):
|
|
49
|
+
return len(self.__store)
|
|
50
|
+
|
|
51
|
+
def __getitem__(self, idx):
|
|
52
|
+
return self.__store[idx]
|
|
53
|
+
|
|
54
|
+
def __setitem__(self, idx, value):
|
|
55
|
+
self._log.debug("__setitem__, %s, %s", idx, value)
|
|
56
|
+
self.__store[idx] = self.convert(value)
|
|
57
|
+
|
|
58
|
+
def __delitem__(self, idx):
|
|
59
|
+
del self.__store[idx]
|
|
60
|
+
|
|
61
|
+
def insert(self, idx, value):
|
|
62
|
+
self.__store.insert(idx, self.convert(value))
|
|
63
|
+
|
|
64
|
+
def convert(self, item):
|
|
65
|
+
"""Convert the input item to the desired object type."""
|
|
66
|
+
try:
|
|
67
|
+
if isinstance(item, self.item_type):
|
|
68
|
+
return item
|
|
69
|
+
# allow explicit null to be passed through to the list
|
|
70
|
+
elif hasattr(item, "is_explicit_null"):
|
|
71
|
+
return item
|
|
72
|
+
except TypeError:
|
|
73
|
+
raise
|
|
74
|
+
|
|
75
|
+
try:
|
|
76
|
+
retval = self.item_type(item)
|
|
77
|
+
self._log.debug(
|
|
78
|
+
"item converted to %s: %s -> %s", self.item_type, item, retval
|
|
79
|
+
)
|
|
80
|
+
return retval
|
|
81
|
+
except (ValueError, TypeError) as exc:
|
|
82
|
+
raise ValueError(
|
|
83
|
+
f"Can't convert {item} to {self.item_type} in TypedList"
|
|
84
|
+
) from exc
|
|
85
|
+
|
|
86
|
+
def purge(self):
|
|
87
|
+
"""Zero out the underlying list object."""
|
|
88
|
+
del self.__store[:]
|
|
89
|
+
|
|
90
|
+
def to_list(self):
|
|
91
|
+
return self.__store
|
|
92
|
+
|
|
93
|
+
def load(self, value):
|
|
94
|
+
if isinstance(value, list):
|
|
95
|
+
self.purge()
|
|
96
|
+
self.extend(
|
|
97
|
+
[
|
|
98
|
+
(item if isinstance(item, self.item_type) else self.item_type(item))
|
|
99
|
+
for item in value
|
|
100
|
+
]
|
|
101
|
+
)
|
|
102
|
+
elif isinstance(value, TypedList):
|
|
103
|
+
self.purge()
|
|
104
|
+
self.extend(value.to_list())
|
|
105
|
+
elif isinstance(value, self.item_type):
|
|
106
|
+
self.purge()
|
|
107
|
+
self.append(value)
|
|
108
|
+
elif hasattr(value, "is_explicit_null"):
|
|
109
|
+
self.purge()
|
|
110
|
+
self.append(value)
|
|
111
|
+
else:
|
|
112
|
+
raise ValueError(
|
|
113
|
+
f"Can't load to TypedList({self.item_type}) from '{value}'"
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
def __repr__(self):
|
|
117
|
+
tmp = json.dumps(self.__store)
|
|
118
|
+
return f"TypedList(item_type={self.item_type}, contents={tmp})"
|
|
119
|
+
|
|
120
|
+
def __str__(self):
|
|
121
|
+
return json.dumps(self.__store)
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
class TypedObject:
|
|
125
|
+
def __init__(self, object_type):
|
|
126
|
+
self.object_type = object_type
|
|
127
|
+
self._value = None
|
|
128
|
+
self._log = logging.getLogger(__name__)
|
|
129
|
+
if isinstance(self.object_type, six.string_types):
|
|
130
|
+
self.object_type = getattr(
|
|
131
|
+
importlib.import_module(
|
|
132
|
+
__package__ + ".models." + self.object_type.lower()
|
|
133
|
+
),
|
|
134
|
+
self.object_type,
|
|
135
|
+
)
|
|
136
|
+
|
|
137
|
+
@property
|
|
138
|
+
def value(self):
|
|
139
|
+
return self._value
|
|
140
|
+
|
|
141
|
+
@value.setter
|
|
142
|
+
def value(self, value):
|
|
143
|
+
if isinstance(value, self.object_type):
|
|
144
|
+
self._value = value
|
|
145
|
+
elif isinstance(value, dict):
|
|
146
|
+
self._value = self.object_type(value)
|
|
147
|
+
elif hasattr(value, "is_explicit_null"):
|
|
148
|
+
self._value = value
|
|
149
|
+
else:
|
|
150
|
+
raise ValueError(
|
|
151
|
+
f"`{value}` invalid type for {self.object_type} value"
|
|
152
|
+
)
|
|
153
|
+
|
|
154
|
+
def __str(self):
|
|
155
|
+
return json.dumps(self._value)
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
class Number:
|
|
159
|
+
def __init__(self, initial_value=None):
|
|
160
|
+
self._value = None
|
|
161
|
+
if initial_value:
|
|
162
|
+
self.value = initial_value
|
|
163
|
+
|
|
164
|
+
@property
|
|
165
|
+
def value(self):
|
|
166
|
+
return self._value
|
|
167
|
+
|
|
168
|
+
@value.setter
|
|
169
|
+
def value(self, value):
|
|
170
|
+
if value is None:
|
|
171
|
+
self._value = None
|
|
172
|
+
elif isinstance(value, (six.integer_types, float)):
|
|
173
|
+
self._value = value
|
|
174
|
+
else:
|
|
175
|
+
raise ValueError(f"`{value}` invalid type for Number value")
|
|
176
|
+
|
|
177
|
+
def __str__(self):
|
|
178
|
+
return str(self.value)
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
class String:
|
|
182
|
+
def __init__(self, initial_value=None, accept=None):
|
|
183
|
+
self._value = None
|
|
184
|
+
if initial_value:
|
|
185
|
+
self.value = initial_value
|
|
186
|
+
self._accept = None
|
|
187
|
+
if accept:
|
|
188
|
+
self.accept = accept
|
|
189
|
+
|
|
190
|
+
@property
|
|
191
|
+
def value(self):
|
|
192
|
+
return self._value
|
|
193
|
+
|
|
194
|
+
@value.setter
|
|
195
|
+
def value(self, value):
|
|
196
|
+
if value is None:
|
|
197
|
+
self._value = None
|
|
198
|
+
elif isinstance(value, six.string_types):
|
|
199
|
+
if self.accept and value not in self._accept:
|
|
200
|
+
raise ValueError(
|
|
201
|
+
f"`{value}` is not in accept list, must be one of {self.accept}"
|
|
202
|
+
)
|
|
203
|
+
self._value = value
|
|
204
|
+
else:
|
|
205
|
+
raise ValueError(f"`{value}` invalid type for String value")
|
|
206
|
+
|
|
207
|
+
@property
|
|
208
|
+
def accept(self):
|
|
209
|
+
return self._accept
|
|
210
|
+
|
|
211
|
+
@accept.setter
|
|
212
|
+
def accept(self, value):
|
|
213
|
+
if isinstance(value, list):
|
|
214
|
+
self._accept = value
|
|
215
|
+
elif isinstance(value, six.string_types):
|
|
216
|
+
self._accept = [value]
|
|
217
|
+
else:
|
|
218
|
+
raise ValueError(f"`{value}` invalid type for accept")
|
|
219
|
+
|
|
220
|
+
def __str__(self):
|
|
221
|
+
return self._value
|
|
222
|
+
|
|
223
|
+
|
|
224
|
+
class Boolean:
|
|
225
|
+
def __init__(self, initial_value=None):
|
|
226
|
+
self._value = None
|
|
227
|
+
if initial_value:
|
|
228
|
+
self.value = initial_value
|
|
229
|
+
|
|
230
|
+
@property
|
|
231
|
+
def value(self):
|
|
232
|
+
return self._value
|
|
233
|
+
|
|
234
|
+
@value.setter
|
|
235
|
+
def value(self, value):
|
|
236
|
+
if value is None:
|
|
237
|
+
self._value = None
|
|
238
|
+
elif isinstance(value, bool):
|
|
239
|
+
self._value = value
|
|
240
|
+
else:
|
|
241
|
+
raise ValueError(f"`{value}` invalid type for Boolean value")
|
|
242
|
+
|
|
243
|
+
def __str__(self):
|
|
244
|
+
return str(self._value)
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
class Timestamp:
|
|
248
|
+
def __init__(self, initial_value=None):
|
|
249
|
+
self._value = None
|
|
250
|
+
if initial_value:
|
|
251
|
+
self.value = initial_value
|
|
252
|
+
|
|
253
|
+
@property
|
|
254
|
+
def value(self):
|
|
255
|
+
return self._value
|
|
256
|
+
|
|
257
|
+
@value.setter
|
|
258
|
+
def value(self, value):
|
|
259
|
+
if value is None:
|
|
260
|
+
self._value = None
|
|
261
|
+
elif isinstance(value, datetime):
|
|
262
|
+
self._value = value
|
|
263
|
+
elif isinstance(value, six.string_types):
|
|
264
|
+
value = parse(value)
|
|
265
|
+
self._value = value
|
|
266
|
+
else:
|
|
267
|
+
raise ValueError(f"`{value}` invalid type for Timestamp value")
|
|
268
|
+
|
|
269
|
+
def __str__(self):
|
|
270
|
+
return str(self._value)
|
|
271
|
+
|
|
272
|
+
|
|
273
|
+
class EnumeratedValue:
|
|
274
|
+
def __init__(self, enum, value=None):
|
|
275
|
+
self.__enum = enum
|
|
276
|
+
self._value = None
|
|
277
|
+
if value:
|
|
278
|
+
self.set(value)
|
|
279
|
+
|
|
280
|
+
@property
|
|
281
|
+
def value(self):
|
|
282
|
+
return self._value
|
|
283
|
+
|
|
284
|
+
def set(self, value):
|
|
285
|
+
if isinstance(value, six.string_types):
|
|
286
|
+
try:
|
|
287
|
+
self._value = self.__enum[value]
|
|
288
|
+
except KeyError:
|
|
289
|
+
self._value = None
|
|
290
|
+
elif isinstance(value, Enum):
|
|
291
|
+
self._value = value
|
|
292
|
+
else:
|
|
293
|
+
self._value = None
|
|
294
|
+
|
|
295
|
+
def __eq__(self, other):
|
|
296
|
+
if isinstance(other, Enum) or other is None:
|
|
297
|
+
return self._value == other
|
|
298
|
+
elif isinstance(other, six.string_types):
|
|
299
|
+
return self._value == self.__enum[other]
|
|
300
|
+
return NotImplemented
|
|
301
|
+
|
|
302
|
+
def __str__(self):
|
|
303
|
+
if self._value is not None:
|
|
304
|
+
return self._value.name
|
|
305
|
+
else:
|
|
306
|
+
return str(None)
|
|
307
|
+
|
|
308
|
+
|
|
309
|
+
class EnumeratedList(TypedList):
|
|
310
|
+
def __init__(self, enum):
|
|
311
|
+
super().__init__(EnumeratedValue)
|
|
312
|
+
self.__enum = enum
|
|
313
|
+
|
|
314
|
+
def load(self, value):
|
|
315
|
+
if isinstance(value, TypedList):
|
|
316
|
+
value = value.to_list()
|
|
317
|
+
|
|
318
|
+
if isinstance(value, list):
|
|
319
|
+
self.purge()
|
|
320
|
+
self.extend([(EnumeratedValue(self.__enum, item)) for item in value])
|
|
321
|
+
else:
|
|
322
|
+
self.purge()
|
|
323
|
+
self.append(EnumeratedValue(self.__enum, value))
|