smartsheet-python-sdk 3.8.0__tar.gz → 4.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 (285) hide show
  1. smartsheet_python_sdk-4.0.0/.claude/skills/implement-api-endpoint/SKILL.md +377 -0
  2. smartsheet_python_sdk-4.0.0/.claude/skills/review-api-endpoint/SKILL.md +559 -0
  3. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/.github/workflows/publish-distribution.yaml +6 -5
  4. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/.github/workflows/publish-documentation.yaml +5 -5
  5. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/.github/workflows/test-build.yaml +17 -20
  6. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/.gitignore +10 -0
  7. smartsheet_python_sdk-4.0.0/ADVANCED.md +396 -0
  8. smartsheet_python_sdk-4.0.0/AGENTS.md +288 -0
  9. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/CHANGELOG.md +58 -1
  10. smartsheet_python_sdk-4.0.0/CLAUDE.md +3 -0
  11. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/CONTRIBUTING.md +84 -10
  12. {smartsheet_python_sdk-3.8.0/smartsheet_python_sdk.egg-info → smartsheet_python_sdk-4.0.0}/PKG-INFO +24 -26
  13. smartsheet_python_sdk-4.0.0/TESTING.md +114 -0
  14. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/pyproject.toml +8 -6
  15. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/folders.py +1 -61
  16. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/__init__.py +11 -1
  17. smartsheet_python_sdk-4.0.0/smartsheet/models/create_report_request.py +107 -0
  18. smartsheet_python_sdk-4.0.0/smartsheet/models/create_report_result.py +105 -0
  19. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/enums/__init__.py +5 -0
  20. smartsheet_python_sdk-4.0.0/smartsheet/models/enums/report_aggregation_type.py +27 -0
  21. smartsheet_python_sdk-4.0.0/smartsheet/models/enums/report_asset_type.py +22 -0
  22. smartsheet_python_sdk-4.0.0/smartsheet/models/enums/report_boolean_operator.py +22 -0
  23. smartsheet_python_sdk-4.0.0/smartsheet/models/enums/report_destination_type.py +22 -0
  24. smartsheet_python_sdk-4.0.0/smartsheet/models/enums/report_filter_operator.py +56 -0
  25. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/enums/seat_type.py +2 -0
  26. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/event.py +9 -0
  27. smartsheet_python_sdk-4.0.0/smartsheet/models/report_column_identifier.py +117 -0
  28. smartsheet_python_sdk-4.0.0/smartsheet/models/report_definition.py +98 -0
  29. smartsheet_python_sdk-4.0.0/smartsheet/models/report_destination.py +64 -0
  30. smartsheet_python_sdk-4.0.0/smartsheet/models/report_filter_criterion.py +100 -0
  31. smartsheet_python_sdk-4.0.0/smartsheet/models/report_filter_expression.py +126 -0
  32. smartsheet_python_sdk-4.0.0/smartsheet/models/report_grouping_criterion.py +83 -0
  33. smartsheet_python_sdk-4.0.0/smartsheet/models/report_scope_inclusion.py +68 -0
  34. smartsheet_python_sdk-4.0.0/smartsheet/models/report_sorting_criterion.py +73 -0
  35. smartsheet_python_sdk-4.0.0/smartsheet/models/report_summarizing_criterion.py +73 -0
  36. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/sheet.py +0 -34
  37. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/reports.py +150 -119
  38. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/sheets.py +1 -155
  39. smartsheet_python_sdk-4.0.0/smartsheet/sights.py +236 -0
  40. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/smartsheet.py +5 -5
  41. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/types.py +20 -5
  42. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/users.py +14 -2
  43. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/util.py +5 -2
  44. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/version.py +3 -3
  45. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/webhooks.py +12 -9
  46. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/workspaces.py +11 -251
  47. smartsheet_python_sdk-4.0.0/tests/mock_api/events/__init__.py +0 -0
  48. smartsheet_python_sdk-4.0.0/tests/mock_api/events/common_test_constants.py +38 -0
  49. smartsheet_python_sdk-4.0.0/tests/mock_api/events/test_list_events.py +233 -0
  50. smartsheet_python_sdk-4.0.0/tests/mock_api/reports/common_test_constants.py +4 -0
  51. smartsheet_python_sdk-4.0.0/tests/mock_api/reports/test_add_report_columns.py +319 -0
  52. smartsheet_python_sdk-4.0.0/tests/mock_api/reports/test_add_report_scope.py +124 -0
  53. smartsheet_python_sdk-4.0.0/tests/mock_api/reports/test_create_report.py +487 -0
  54. smartsheet_python_sdk-4.0.0/tests/mock_api/reports/test_delete_report.py +77 -0
  55. smartsheet_python_sdk-4.0.0/tests/mock_api/reports/test_remove_report_scope.py +124 -0
  56. smartsheet_python_sdk-4.0.0/tests/mock_api/reports/test_update_report_definition.py +234 -0
  57. smartsheet_python_sdk-4.0.0/tests/mock_api/test_mock_api_reports.py +55 -0
  58. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/tests/mock_api/test_mock_api_sights.py +2 -1
  59. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/tests/mock_api/test_mock_api_workspaces.py +26 -26
  60. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/tests/mock_api/test_mock_serialization.py +1 -26
  61. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/tests/mock_api/users/test_list_user_plans.py +19 -2
  62. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/tests/mock_api/users/test_list_users.py +44 -0
  63. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/tests/mock_api/users/test_user_upgrade_downgrade.py +21 -0
  64. smartsheet_python_sdk-4.0.0/tests/test_enumerated_value_set.py +366 -0
  65. smartsheet_python_sdk-4.0.0/uv.lock +3225 -0
  66. smartsheet_python_sdk-3.8.0/ADVANCED.md +0 -263
  67. smartsheet_python_sdk-3.8.0/Makefile +0 -57
  68. smartsheet_python_sdk-3.8.0/PKG-INFO +0 -124
  69. smartsheet_python_sdk-3.8.0/docs-source/Makefile +0 -153
  70. smartsheet_python_sdk-3.8.0/docs-source/smartsheet_api.rst +0 -186
  71. smartsheet_python_sdk-3.8.0/docs-source/smartsheet_enums.rst +0 -290
  72. smartsheet_python_sdk-3.8.0/docs-source/smartsheet_exceptions.rst +0 -7
  73. smartsheet_python_sdk-3.8.0/docs-source/smartsheet_models.rst +0 -978
  74. smartsheet_python_sdk-3.8.0/docs-source/smartsheet_types.rst +0 -7
  75. smartsheet_python_sdk-3.8.0/setup.cfg +0 -4
  76. smartsheet_python_sdk-3.8.0/smartsheet/models/share.py +0 -183
  77. smartsheet_python_sdk-3.8.0/smartsheet/sights.py +0 -425
  78. smartsheet_python_sdk-3.8.0/smartsheet/templates.py +0 -90
  79. smartsheet_python_sdk-3.8.0/smartsheet_python_sdk.egg-info/SOURCES.txt +0 -247
  80. smartsheet_python_sdk-3.8.0/smartsheet_python_sdk.egg-info/dependency_links.txt +0 -1
  81. smartsheet_python_sdk-3.8.0/smartsheet_python_sdk.egg-info/requires.txt +0 -30
  82. smartsheet_python_sdk-3.8.0/smartsheet_python_sdk.egg-info/top_level.txt +0 -1
  83. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/.gitchangelog.rc +0 -0
  84. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/.gitchangelog.tpl +0 -0
  85. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  86. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  87. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/.github/pull_request_template.md +0 -0
  88. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/.markdownlint.json +0 -0
  89. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/.roo/roomotes.yml +0 -0
  90. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/ISSUE-FIRST.md +0 -0
  91. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/LICENSE.md +0 -0
  92. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/NOTICE +0 -0
  93. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/README.md +0 -0
  94. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/docs-source/conf.py +0 -0
  95. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/docs-source/index.rst +0 -0
  96. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/__init__.py +0 -0
  97. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/attachments.py +0 -0
  98. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/cells.py +0 -0
  99. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/contacts.py +0 -0
  100. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/discussions.py +0 -0
  101. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/events.py +0 -0
  102. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/exceptions.py +0 -0
  103. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/favorites.py +0 -0
  104. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/groups.py +0 -0
  105. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/home.py +0 -0
  106. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/images.py +0 -0
  107. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/access_token.py +0 -0
  108. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/account.py +0 -0
  109. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/alternate_email.py +0 -0
  110. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/asset_share.py +0 -0
  111. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/asset_shares_paginated_result.py +0 -0
  112. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/attachment.py +0 -0
  113. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/auto_number_format.py +0 -0
  114. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/automation_action.py +0 -0
  115. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/automation_rule.py +0 -0
  116. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/boolean_object_value.py +0 -0
  117. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/bulk_item_failure.py +0 -0
  118. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/bulk_item_result.py +0 -0
  119. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/cell.py +0 -0
  120. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/cell_data_item.py +0 -0
  121. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/cell_history.py +0 -0
  122. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/cell_link.py +0 -0
  123. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/cell_link_widget_content.py +0 -0
  124. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/chart_widget_content.py +0 -0
  125. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/column.py +0 -0
  126. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/comment.py +0 -0
  127. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/contact.py +0 -0
  128. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/contact_object_value.py +0 -0
  129. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/container_destination.py +0 -0
  130. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/copy_or_move_row_destination.py +0 -0
  131. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/copy_or_move_row_directive.py +0 -0
  132. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/copy_or_move_row_result.py +0 -0
  133. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/criteria.py +0 -0
  134. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/cross_sheet_reference.py +0 -0
  135. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/currency.py +0 -0
  136. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/date_object_value.py +0 -0
  137. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/datetime_object_value.py +0 -0
  138. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/discussion.py +0 -0
  139. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/downloaded_file.py +0 -0
  140. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/duration.py +0 -0
  141. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/email.py +0 -0
  142. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/enums/access_level.py +0 -0
  143. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/enums/asset_type.py +0 -0
  144. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/enums/attachment_parent_type.py +0 -0
  145. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/enums/attachment_sub_type.py +0 -0
  146. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/enums/attachment_type.py +0 -0
  147. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/enums/automation_action_frequency.py +0 -0
  148. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/enums/automation_action_type.py +0 -0
  149. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/enums/automation_rule_disabled_reason.py +0 -0
  150. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/enums/cell_link_status.py +0 -0
  151. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/enums/column_type.py +0 -0
  152. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/enums/criteria_target.py +0 -0
  153. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/enums/cross_sheet_reference_status.py +0 -0
  154. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/enums/currency_code.py +0 -0
  155. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/enums/day_descriptors.py +0 -0
  156. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/enums/day_ordinal.py +0 -0
  157. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/enums/event_action.py +0 -0
  158. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/enums/event_object_type.py +0 -0
  159. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/enums/event_source.py +0 -0
  160. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/enums/favorite_type.py +0 -0
  161. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/enums/global_template.py +0 -0
  162. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/enums/operator.py +0 -0
  163. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/enums/paper_type.py +0 -0
  164. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/enums/predecessor_type.py +0 -0
  165. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/enums/publish_accessible_by.py +0 -0
  166. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/enums/schedule_type.py +0 -0
  167. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/enums/share_scope.py +0 -0
  168. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/enums/share_type.py +0 -0
  169. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/enums/sheet_email_format.py +0 -0
  170. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/enums/sheet_filter_operator.py +0 -0
  171. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/enums/sheet_filter_type.py +0 -0
  172. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/enums/sort_direction.py +0 -0
  173. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/enums/symbol.py +0 -0
  174. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/enums/system_column_type.py +0 -0
  175. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/enums/update_request_status.py +0 -0
  176. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/enums/user_status.py +0 -0
  177. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/enums/widget_type.py +0 -0
  178. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/error.py +0 -0
  179. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/error_result.py +0 -0
  180. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/event_result.py +0 -0
  181. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/explicit_null.py +0 -0
  182. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/favorite.py +0 -0
  183. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/folder.py +0 -0
  184. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/font_family.py +0 -0
  185. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/format_details.py +0 -0
  186. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/format_tables.py +0 -0
  187. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/group.py +0 -0
  188. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/group_member.py +0 -0
  189. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/home.py +0 -0
  190. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/hyperlink.py +0 -0
  191. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/image.py +0 -0
  192. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/image_url.py +0 -0
  193. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/image_url_map.py +0 -0
  194. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/image_widget_content.py +0 -0
  195. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/index_result.py +0 -0
  196. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/json_object.py +0 -0
  197. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/multi_contact_object_value.py +0 -0
  198. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/multi_picklist_object_value.py +0 -0
  199. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/multi_row_email.py +0 -0
  200. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/number_object_value.py +0 -0
  201. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/o_auth_error.py +0 -0
  202. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/object_value.py +0 -0
  203. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/paginated_children_result.py +0 -0
  204. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/predecessor.py +0 -0
  205. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/predecessor_list.py +0 -0
  206. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/primitive_object_value.py +0 -0
  207. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/profile_image.py +0 -0
  208. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/project_settings.py +0 -0
  209. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/recipient.py +0 -0
  210. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/report.py +0 -0
  211. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/report_cell.py +0 -0
  212. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/report_column.py +0 -0
  213. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/report_publish.py +0 -0
  214. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/report_row.py +0 -0
  215. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/report_widget_content.py +0 -0
  216. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/result.py +0 -0
  217. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/row.py +0 -0
  218. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/row_email.py +0 -0
  219. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/row_mapping.py +0 -0
  220. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/schedule.py +0 -0
  221. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/scope.py +0 -0
  222. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/search_result.py +0 -0
  223. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/search_result_item.py +0 -0
  224. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/selection_range.py +0 -0
  225. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/sent_update_request.py +0 -0
  226. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/server_info.py +0 -0
  227. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/sheet_email.py +0 -0
  228. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/sheet_filter.py +0 -0
  229. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/sheet_filter_details.py +0 -0
  230. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/sheet_publish.py +0 -0
  231. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/sheet_summary.py +0 -0
  232. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/sheet_user_permissions.py +0 -0
  233. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/sheet_user_settings.py +0 -0
  234. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/shortcut_data_item.py +0 -0
  235. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/shortcut_widget_content.py +0 -0
  236. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/sight.py +0 -0
  237. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/sight_publish.py +0 -0
  238. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/sort_criterion.py +0 -0
  239. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/sort_specifier.py +0 -0
  240. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/source.py +0 -0
  241. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/string_object_value.py +0 -0
  242. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/summary_field.py +0 -0
  243. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/template.py +0 -0
  244. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/title_rich_text_widget_content.py +0 -0
  245. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/token_paginated_result.py +0 -0
  246. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/update_request.py +0 -0
  247. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/user.py +0 -0
  248. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/user_model.py +0 -0
  249. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/user_plan.py +0 -0
  250. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/user_profile.py +0 -0
  251. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/version.py +0 -0
  252. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/web_content_widget_content.py +0 -0
  253. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/webhook.py +0 -0
  254. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/webhook_secret.py +0 -0
  255. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/webhook_stats.py +0 -0
  256. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/webhook_subscope.py +0 -0
  257. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/widget.py +0 -0
  258. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/widget_content.py +0 -0
  259. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/widget_hyperlink.py +0 -0
  260. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/models/workspace.py +0 -0
  261. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/object_value.py +0 -0
  262. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/passthrough.py +0 -0
  263. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/search.py +0 -0
  264. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/server.py +0 -0
  265. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/session.py +0 -0
  266. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/sharing.py +0 -0
  267. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/smartsheet/token.py +0 -0
  268. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/tests/__init__.py +0 -0
  269. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/tests/mock_api/__init__.py +0 -0
  270. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/tests/mock_api/favorites/__init__.py +0 -0
  271. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/tests/mock_api/favorites/common_test_constants.py +0 -0
  272. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/tests/mock_api/favorites/test_is_favorite.py +0 -0
  273. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/tests/mock_api/mock_api_test_helper.py +0 -0
  274. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/tests/mock_api/test_mock_api_automation_rules.py +0 -0
  275. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/tests/mock_api/test_mock_api_columns.py +0 -0
  276. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/tests/mock_api/test_mock_api_folders.py +0 -0
  277. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/tests/mock_api/test_mock_api_rows.py +0 -0
  278. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/tests/mock_api/test_mock_api_sharing.py +0 -0
  279. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/tests/mock_api/test_mock_api_sheets.py +0 -0
  280. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/tests/mock_api/test_mock_change_agent.py +0 -0
  281. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/tests/mock_api/users/common_test_constants.py +0 -0
  282. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/tests/mock_api/users/test_deactivate_user.py +0 -0
  283. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/tests/mock_api/users/test_reactivate_user.py +0 -0
  284. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/tests/mock_api/users/test_remove_user_from_plan.py +0 -0
  285. {smartsheet_python_sdk-3.8.0 → smartsheet_python_sdk-4.0.0}/tests/test_util_serialize_dict.py +0 -0
@@ -0,0 +1,377 @@
1
+ ---
2
+ name: implement-api-endpoint
3
+ description: Use when adding or modifying API endpoints in smartsheet-python-sdk - implementing resource methods, handling request/response serialization, or updating endpoint parameters
4
+ ---
5
+
6
+ # Implement API Endpoint
7
+
8
+ ## Overview
9
+
10
+ Complete workflow for implementing SDK endpoints: resource method, model objects, serialization, comprehensive tests (5 required types), and documentation. **Implementation alone is ~20% of the work.**
11
+
12
+ **CRITICAL REQUIREMENTS:**
13
+ 1. You MUST use TodoWrite to create a todo for EACH checklist item below before starting implementation
14
+ 2. You MUST have OpenAPI spec for the endpoint (Smartsheet public API: https://developers.smartsheet.com/_spec/api/smartsheet/openapi.json OR user-provided spec path)
15
+ 3. Implementation MUST exactly match the spec (parameters, types, request/response structure)
16
+
17
+ ## When to Use
18
+
19
+ - Adding new SDK endpoint (GET, POST, PUT, DELETE, PATCH)
20
+ - Modifying existing endpoint (parameters, return type, behavior)
21
+ - Updating endpoint for API changes
22
+
23
+ **GOLD STANDARD TEMPLATE: tests/mock_api/reports/**
24
+ **Before implementing, review report tests as your reference implementation. Follow these patterns exactly.**
25
+
26
+ **Not done until:** All 4 components exist (code, tests, WireMock mappings, docs) AND verified against OpenAPI spec
27
+
28
+ ## Core Pattern
29
+
30
+ SDK endpoints require 4 components in order:
31
+
32
+ ```
33
+ 1. Resource Method (smartsheet/{resource}.py)
34
+ 2. Mock API Tests (tests/mock_api/{resource}/)
35
+ 3. WireMock Mappings (smartsheet-sdk-tests repo)
36
+ 4. Documentation (docs-source/)
37
+ ```
38
+
39
+ **Implementation is NOT done until all 4 exist.**
40
+
41
+ ## Implementation Checklist
42
+
43
+ **STOP: Before writing ANY code:**
44
+
45
+ 1. **Obtain OpenAPI spec:**
46
+ - Use Smartsheet public API spec: https://developers.smartsheet.com/_spec/api/smartsheet/openapi.json
47
+ - OR if endpoint not documented there, request spec path from user
48
+ - **Cannot proceed without spec - ask user if not provided**
49
+
50
+ 2. **Obtain WireMock mappings:**
51
+ - Use Smartsheet SDK tests repo: https://github.com/smartsheet/smartsheet-sdk-tests
52
+ - OR request local filesystem path from user
53
+ - **Cannot proceed without mappings - ask user if not provided**
54
+
55
+ 3. **Use TodoWrite to create a todo for EVERY checkbox below**
56
+
57
+ **Violating these rules means incomplete/incorrect work. Always verify spec and mappings first, create todos second.**
58
+
59
+ ### 0. OpenAPI Spec Verification
60
+
61
+ **MUST be completed before implementation:**
62
+
63
+ - [ ] OpenAPI spec obtained (public API URL or user-provided path)
64
+ - [ ] Endpoint exists in spec with correct path
65
+ - [ ] HTTP method matches spec
66
+ - [ ] Request parameters match spec (names, types, required/optional)
67
+ - [ ] Request body schema matches spec (for POST/PUT/PATCH)
68
+ - [ ] Response schema matches spec (structure, property types)
69
+ - [ ] Error responses documented in spec
70
+ - [ ] Query parameters match spec (names, types, format)
71
+
72
+ ### 0b. WireMock Mappings Verification
73
+
74
+ **MUST be obtained before implementation:**
75
+
76
+ - [ ] WireMock mappings obtained from:
77
+ - Smartsheet SDK tests repo: https://github.com/smartsheet/smartsheet-sdk-tests
78
+ - OR user-provided path on local filesystem
79
+ - [ ] **Cannot proceed without mappings - ask user if not provided**
80
+ - [ ] Mapping exists for: `/{resource}/{method}/all-response-body-properties`
81
+ - [ ] Mapping exists for: `/{resource}/{method}/required-response-body-properties` (if applicable)
82
+ - [ ] Global error mappings verified: `/errors/400-response`, `/errors/500-response`
83
+ - [ ] Response jsonBody in mappings matches OpenAPI spec schema
84
+ - [ ] Request body schema in mappings matches OpenAPI spec (for POST/PUT/PATCH)
85
+
86
+ ### 1. Resource Method Implementation
87
+
88
+ **File:** `smartsheet/{resource}.py`
89
+
90
+ **ALL items must match OpenAPI spec exactly:**
91
+
92
+ - [ ] **Type definitions created** for request/response models (MANDATORY for new endpoints)
93
+ - [ ] **Python 3.7 compatibility verified** - type hints, syntax, no 3.8+ features
94
+ - [ ] Method signature with proper type hints (parameter types from spec)
95
+ - [ ] Parameter names match spec (snake_case conversion from camelCase)
96
+ - [ ] Required vs optional parameters match spec
97
+ - [ ] Docstring with Args and Returns sections (descriptions from spec)
98
+ - [ ] Create operation: `_op = fresh_operation("method_name")`
99
+ - [ ] Set HTTP method from spec: `_op["method"] = "GET/POST/PUT/DELETE"`
100
+ - [ ] Set path with placeholders from spec: `_op["path"] = "/resource/{id}"`
101
+ - [ ] Add query params matching spec: `_op["query_params"]["param"] = value`
102
+ - [ ] Add request body matching spec schema (if POST/PUT/PATCH): `_op["json"] = payload`
103
+ - [ ] Define expected response type from spec: `expected = "ModelName"` or `["Result", "ModelName"]`
104
+ - [ ] Prepare and execute: `prepped = self._base.prepare_request(_op)` then `return self._base.request(prepped, expected, _op)`
105
+ - [ ] Return type from spec: `Union[ExpectedType, Error]`
106
+ - [ ] **All type definitions use Python 3.7 compatible syntax**
107
+
108
+ **Reference:** See @ADVANCED.md "Resource Module Organization" for delegation pattern
109
+
110
+ ### 2. Mock API Tests (5 Required Types)
111
+
112
+ **File:** `tests/mock_api/{resource}/test_{method_name}.py`
113
+
114
+ **CRITICAL: All 5 test types MUST exist. Tests MUST strictly follow @TESTING.md standards. No exceptions - this is a MANDATORY checklist for development.**
115
+
116
+ **GOLD STANDARD: Use tests/mock_api/reports/ as your template. Copy the assertion patterns, structure, and style exactly.**
117
+
118
+ **Test data must match OpenAPI spec:**
119
+ - Request parameters use spec-defined types and formats
120
+ - Response assertions match spec schema exactly
121
+ - Error responses match spec error schemas
122
+
123
+ - [ ] **`test_{method}_generated_url_is_correct`**
124
+ - Use `uuid.uuid4().hex` for request_id
125
+ - Call `get_mock_api_client(test_scenario_name, request_id)`
126
+ - Execute SDK method
127
+ - Use `get_wiremock_request(request_id)` to retrieve actual request
128
+ - Parse URL with `urlparse()` and `parse_qs()`
129
+ - Assert complete query object: `assert query == {...}` (NOT property-by-property) [TESTING.md lines 73-74]
130
+ - **ALWAYS assert query parameters, even if empty:** `assert not query`
131
+ - Assert URL path matches expected
132
+
133
+ - [ ] **`test_{method}_all_response_properties`**
134
+ - Call SDK method with test scenario
135
+ - Assert response type with `isinstance(response, ExpectedType)`
136
+ - For wrapped responses (Result, IndexResult): assert BOTH wrapper and inner type
137
+ - Assert complete response: `assert response.to_dict() == {...}` (whole object, NOT properties)
138
+ - **Response structure must match OpenAPI spec schema exactly**
139
+ - Retrieve request with `get_wiremock_request(request_id)`
140
+ - Parse body with `json.loads(wiremock_request["body"])`
141
+ - Assert complete request body: `assert request_body == {...}`
142
+ - **ALWAYS assert request body, even if empty for GET/DELETE:** `assert not request_body`
143
+ - For POST/PUT/PATCH: **Request body must match OpenAPI spec schema (camelCase, correct types)**
144
+
145
+ - [ ] **`test_{method}_required_response_properties`** (if applicable)
146
+ - Same pattern as all_response_properties
147
+ - Only create if WireMock mapping exists for minimal response
148
+ - Tests SDK handles responses with only required fields
149
+ - **ALWAYS assert request body, even if empty for GET/DELETE:** `assert not request_body`
150
+
151
+ - [ ] **`test_{method}_error_4xx`**
152
+ - Use test scenario `/errors/400-response` (catch-all)
153
+ - Call SDK method
154
+ - Assert `isinstance(response, Error)`
155
+
156
+ - [ ] **`test_{method}_error_5xx`**
157
+ - Use test scenario `/errors/500-response` (catch-all)
158
+ - Call SDK method
159
+ - Assert `isinstance(response, Error)`
160
+
161
+ **Constants file:** `tests/mock_api/{resource}/common_test_constants.py`
162
+ - [ ] Add test constants for IDs, expected values, enums
163
+
164
+ **MANDATORY REFERENCE:**
165
+ - See @TESTING.md "Mock API Test Standards" for complete assertion rules
166
+ - **Use tests/mock_api/reports/ as your implementation template - copy the patterns exactly**
167
+
168
+ ### 3. WireMock Mappings
169
+
170
+ **Repository:** [smartsheet-sdk-tests](https://github.com/smartsheet/smartsheet-sdk-tests)
171
+
172
+ **Required mappings:**
173
+ - [ ] `{resource}/{method}/all-response-body-properties.json`
174
+ - [ ] `{resource}/{method}/required-response-body-properties.json` (if applicable)
175
+ - [ ] Error mappings exist globally: `/errors/400-response`, `/errors/500-response`
176
+
177
+ **Mapping structure (must match OpenAPI spec):**
178
+ ```json
179
+ {
180
+ "request": {
181
+ "urlPathTemplate": "/2.0/{resource}/{id}",
182
+ "method": "GET",
183
+ "headers": {
184
+ "Authorization": {"matches": "Bearer .*"},
185
+ "x-test-name": {"equalTo": "/{resource}/{method}/all-response-body-properties"},
186
+ "x-request-id": {"matches": ".*"}
187
+ }
188
+ },
189
+ "response": {
190
+ "status": 200,
191
+ "jsonBody": { /* Must match OpenAPI response schema */ }
192
+ }
193
+ }
194
+ ```
195
+
196
+ - [ ] Response jsonBody matches OpenAPI spec response schema exactly
197
+ - [ ] Request body schema matches spec (for POST/PUT/PATCH mappings)
198
+ - [ ] Status codes match spec
199
+
200
+ ### 4. Documentation Updates
201
+
202
+ **File:** `docs-source/smartsheet_api.rst` (for API resources)
203
+
204
+ - [ ] **Check if docs-source update required** (see @ADVANCED.md for when updates are needed)
205
+ - [ ] Add method to appropriate module section
206
+ - [ ] Follow automodule pattern: `.. automethod:: {ResourceClass}.{method_name}`
207
+ - [ ] Rebuild docs: `uv run sphinx-build -b html docs-source docs-source/_build/html`
208
+ - [ ] Verify in `docs-source/_build/html/index.html`
209
+
210
+ **Reference:** See @CONTRIBUTING.md "Documentation" section for file mappings and @ADVANCED.md for documentation requirements
211
+
212
+ ## Quick Reference: SDK Patterns
213
+
214
+ | Endpoint Type | Request Body | Response Type | Test Count |
215
+ |---------------|--------------|---------------|------------|
216
+ | GET single | None | `Model` or Error | 5 (skip required if N/A) |
217
+ | GET list | None | `IndexResult[Model]` | 5 |
218
+ | POST | `_op["json"]` | `Result[Model]` | 5 (must test request body) |
219
+ | PUT | `_op["json"]` | `Result[Model]` | 5 (must test request body) |
220
+ | DELETE | None | `Result[None]` | 5 |
221
+
222
+ ## Common Mistakes
223
+
224
+ | Mistake | Reality | Fix |
225
+ |---------|---------|-----|
226
+ | "I don't need the spec" | Cannot verify correctness without it | Get spec URL/path first |
227
+ | "Spec roughly matches" | SDK must match spec exactly | Verify every parameter/field |
228
+ | "Implementation done" | Tests + docs still needed (~80% of work) | Complete all 4 checklist sections |
229
+ | "Endpoint is production-ready" | Without tests? No, it's 20% done | All 5 test types required |
230
+ | "I'll add tests later" | Tests verify correctness NOW | Tests before marking complete |
231
+ | Skipping TodoWrite | Incomplete work looks complete | Create todos FIRST, always |
232
+ | Property-by-property assertions | Allows extra properties to creep in | Use `.to_dict() == {...}` |
233
+ | Missing request body assertions | Request serialization bugs undetected | Assert `request_body == {...}` for POST/PUT/PATCH |
234
+ | Skipping error tests | Error handling untested | Both 4xx and 5xx required |
235
+ | Only 3 of 5 test types | Incomplete coverage | All 5 types MUST exist |
236
+ | "Docs are obvious" | Sphinx won't auto-discover | Must add to .rst files |
237
+ | "Quick implementation" without todos | 80% of work gets skipped | Todos first, no exceptions |
238
+ | Tests don't match TESTING.md | Standards exist for a reason | Follow @TESTING.md strictly |
239
+ | "I don't need WireMock mappings yet" | Tests will fail without them | Get mappings location first |
240
+ | "Mappings can be created later" | Tests depend on mappings existing | Mappings prerequisite, not optional |
241
+ | Missing type definitions | Type definitions MANDATORY for new endpoints | Create type defs first |
242
+ | Using Python 3.8+ features | Must support 3.7 | Check syntax compatibility |
243
+ | Skipping docs check | ADVANCED.md defines requirements | Verify docs needed |
244
+
245
+ ## Red Flags - STOP and Complete Checklist
246
+
247
+ These thoughts mean STOP - you're taking shortcuts:
248
+
249
+ - **No OpenAPI spec verified** - Cannot proceed without spec
250
+ - **No WireMock mappings verified** - Cannot proceed without mappings
251
+ - **Haven't reviewed reports tests** - Must review gold standard template first
252
+ - "I'll check the spec later" - Spec MUST be verified first
253
+ - "I know the pattern" - Review reports tests anyway, don't rely on memory
254
+ - "Mappings probably exist" - Must verify, not assume
255
+ - Only implementation file changed (no tests/docs)
256
+ - "Implementation complete" or "endpoint is production-ready"
257
+ - "Quick implementation" without TodoWrite
258
+ - No todos created from checklist
259
+ - Missing any of 5 test types
260
+ - WireMock mappings not created
261
+ - Tests use property-by-property assertions
262
+ - Documentation not updated
263
+ - "I'll add tests/docs in follow-up PR"
264
+ - "Tests can wait" or "just need implementation"
265
+ - Started coding before creating todos
266
+ - Request/response doesn't match spec exactly
267
+ - No type definitions created for new endpoint
268
+ - Using Python 3.8+ syntax (walrus operator, positional-only params)
269
+ - Didn't check ADVANCED.md for docs requirements
270
+
271
+ **All of these mean: Work incomplete. Return to checklist, verify spec and mappings, create ALL todos first.**
272
+
273
+ **Implementation without spec verification, mappings, tests, and docs is NOT production-ready. It's 20% done.**
274
+
275
+ ## Example: Complete Implementation
276
+
277
+ **NOTE: This is a simplified example. For complete gold standard implementation, see tests/mock_api/reports/test_create_report.py**
278
+
279
+ **Scenario:** Add `Contacts.get_contact(contact_id)`
280
+
281
+ ### 1. Resource Method
282
+ ```python
283
+ # smartsheet/contacts.py
284
+ def get_contact(self, contact_id: str) -> Union[Contact, Error]:
285
+ """Get a contact by ID.
286
+
287
+ Args:
288
+ contact_id (str): Contact ID (email address)
289
+
290
+ Returns:
291
+ Union[Contact, Error]: Contact object or Error
292
+ """
293
+ _op = fresh_operation("get_contact")
294
+ _op["method"] = "GET"
295
+ _op["path"] = f"/contacts/{contact_id}"
296
+
297
+ expected = "Contact"
298
+ prepped = self._base.prepare_request(_op)
299
+ return self._base.request(prepped, expected, _op)
300
+ ```
301
+
302
+ ### 2. Tests (5 types)
303
+ ```python
304
+ # tests/mock_api/contacts/test_get_contact.py
305
+ import uuid
306
+ from urllib.parse import urlparse
307
+ from smartsheet.models import Contact, Error
308
+ from tests.mock_api.mock_api_test_helper import (
309
+ get_mock_api_client, get_wiremock_request
310
+ )
311
+
312
+ def test_get_contact_generated_url_is_correct():
313
+ request_id = uuid.uuid4().hex
314
+ client = get_mock_api_client(
315
+ "/contacts/get-contact/all-response-body-properties", request_id
316
+ )
317
+
318
+ client.Contacts.get_contact("user@example.com")
319
+
320
+ wiremock_request = get_wiremock_request(request_id)
321
+ url = urlparse(wiremock_request["absoluteUrl"])
322
+ assert url.path == "/2.0/contacts/user@example.com"
323
+
324
+ def test_get_contact_all_response_properties():
325
+ request_id = uuid.uuid4().hex
326
+ client = get_mock_api_client(
327
+ "/contacts/get-contact/all-response-body-properties", request_id
328
+ )
329
+
330
+ response = client.Contacts.get_contact("user@example.com")
331
+
332
+ assert isinstance(response, Contact)
333
+ assert response.to_dict() == {
334
+ "id": "user@example.com",
335
+ "email": "user@example.com",
336
+ "name": "User Name"
337
+ }
338
+
339
+ def test_get_contact_error_4xx():
340
+ request_id = uuid.uuid4().hex
341
+ client = get_mock_api_client("/errors/400-response", request_id)
342
+
343
+ response = client.Contacts.get_contact("invalid")
344
+ assert isinstance(response, Error)
345
+
346
+ def test_get_contact_error_5xx():
347
+ request_id = uuid.uuid4().hex
348
+ client = get_mock_api_client("/errors/500-response", request_id)
349
+
350
+ response = client.Contacts.get_contact("user@example.com")
351
+ assert isinstance(response, Error)
352
+ ```
353
+
354
+ ### 3. Documentation
355
+ ```rst
356
+ # docs-source/smartsheet_api.rst
357
+ Contacts
358
+ --------
359
+ .. automethod:: Contacts.get_contact
360
+ ```
361
+
362
+ ## The Bottom Line
363
+
364
+ **Implementation without tests and documentation is incomplete work.**
365
+
366
+ The baseline pattern: agents write implementation quickly, then stop at ~20% complete. Time pressure triggers "implementation = done" rationalization.
367
+
368
+ Follow the 4-part checklist completely. All 5 test types are required. Whole-object assertions prevent regressions. Documentation updates are not optional.
369
+
370
+ **No Exceptions:**
371
+ - Not for "simple endpoints" - all require tests
372
+ - Not for "modifications" - updated endpoints need updated tests
373
+ - Not for "time pressure" - incomplete work creates more pressure later
374
+ - Not for "stakeholder waiting" - shipping untested code is worse
375
+ - Never skip TodoWrite - creates accountability
376
+
377
+ **The rule: Create ALL todos from checklist FIRST. Then complete them. Mark done only when all 4 components exist.**