growsurf-python 1.1.0__tar.gz → 1.1.2__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 (171) hide show
  1. growsurf_python-1.1.2/.release-please-manifest.json +3 -0
  2. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/CHANGELOG.md +20 -0
  3. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/PKG-INFO +2 -2
  4. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/README.md +1 -1
  5. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/api.md +0 -3
  6. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/pyproject.toml +1 -1
  7. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/_client.py +2 -0
  8. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/_version.py +1 -1
  9. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/resources/account.py +20 -14
  10. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/resources/campaign/campaign.py +0 -81
  11. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/resources/campaign/reward.py +6 -4
  12. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/types/__init__.py +0 -4
  13. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/types/rotate_api_key_response.py +1 -1
  14. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/tests/api_resources/test_campaign.py +0 -85
  15. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/tests/test_client.py +22 -0
  16. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/uv.lock +1 -1
  17. growsurf_python-1.1.0/.release-please-manifest.json +0 -3
  18. growsurf_python-1.1.0/src/growsurf/types/referral_flow_screenshots_response.py +0 -34
  19. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/.gitignore +0 -0
  20. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/CONTRIBUTING.md +0 -0
  21. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/LICENSE +0 -0
  22. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/SECURITY.md +0 -0
  23. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/bin/check-release-environment +0 -0
  24. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/bin/publish-pypi +0 -0
  25. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/examples/.keep +0 -0
  26. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/release-please-config.json +0 -0
  27. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/requirements-dev.lock +0 -0
  28. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/__init__.py +0 -0
  29. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/_base_client.py +0 -0
  30. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/_compat.py +0 -0
  31. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/_constants.py +0 -0
  32. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/_exceptions.py +0 -0
  33. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/_files.py +0 -0
  34. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/_models.py +0 -0
  35. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/_qs.py +0 -0
  36. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/_resource.py +0 -0
  37. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/_response.py +0 -0
  38. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/_streaming.py +0 -0
  39. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/_types.py +0 -0
  40. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/_utils/__init__.py +0 -0
  41. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/_utils/_compat.py +0 -0
  42. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/_utils/_datetime_parse.py +0 -0
  43. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/_utils/_json.py +0 -0
  44. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/_utils/_logs.py +0 -0
  45. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/_utils/_path.py +0 -0
  46. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/_utils/_proxy.py +0 -0
  47. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/_utils/_reflection.py +0 -0
  48. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/_utils/_resources_proxy.py +0 -0
  49. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/_utils/_streams.py +0 -0
  50. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/_utils/_sync.py +0 -0
  51. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/_utils/_transform.py +0 -0
  52. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/_utils/_typing.py +0 -0
  53. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/_utils/_utils.py +0 -0
  54. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/lib/.keep +0 -0
  55. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/py.typed +0 -0
  56. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/resources/__init__.py +0 -0
  57. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/resources/campaign/__init__.py +0 -0
  58. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/resources/campaign/commission.py +0 -0
  59. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/resources/campaign/design.py +0 -0
  60. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/resources/campaign/emails.py +0 -0
  61. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/resources/campaign/installation.py +0 -0
  62. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/resources/campaign/options.py +0 -0
  63. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/resources/campaign/participant.py +0 -0
  64. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/resources/campaign/rewards.py +0 -0
  65. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/resources/campaign/webhooks.py +0 -0
  66. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/types/account.py +0 -0
  67. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/types/account_create_params.py +0 -0
  68. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/types/account_update_params.py +0 -0
  69. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/types/campaign/__init__.py +0 -0
  70. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/types/campaign/campaign.py +0 -0
  71. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/types/campaign/campaign_design.py +0 -0
  72. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/types/campaign/campaign_emails.py +0 -0
  73. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/types/campaign/campaign_installation.py +0 -0
  74. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/types/campaign/campaign_options.py +0 -0
  75. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/types/campaign/campaign_reward_list_response.py +0 -0
  76. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/types/campaign/commission_approve_response.py +0 -0
  77. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/types/campaign/commission_delete_response.py +0 -0
  78. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/types/campaign/delete_reward_response.py +0 -0
  79. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/types/campaign/delete_webhook_response.py +0 -0
  80. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/types/campaign/email_participant_response.py +0 -0
  81. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/types/campaign/fraud_risk_level.py +0 -0
  82. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/types/campaign/participant.py +0 -0
  83. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/types/campaign/participant_activity_logs_response.py +0 -0
  84. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/types/campaign/participant_add_params.py +0 -0
  85. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/types/campaign/participant_analytics_params.py +0 -0
  86. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/types/campaign/participant_analytics_response.py +0 -0
  87. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/types/campaign/participant_bulk_delete_params.py +0 -0
  88. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/types/campaign/participant_bulk_delete_response.py +0 -0
  89. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/types/campaign/participant_delete_response.py +0 -0
  90. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/types/campaign/participant_email_params.py +0 -0
  91. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/types/campaign/participant_list_activity_logs_params.py +0 -0
  92. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/types/campaign/participant_list_commissions_params.py +0 -0
  93. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/types/campaign/participant_list_payouts_params.py +0 -0
  94. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/types/campaign/participant_list_referrals_params.py +0 -0
  95. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/types/campaign/participant_list_rewards_params.py +0 -0
  96. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/types/campaign/participant_list_rewards_response.py +0 -0
  97. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/types/campaign/participant_record_transaction_params.py +0 -0
  98. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/types/campaign/participant_record_transaction_response.py +0 -0
  99. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/types/campaign/participant_refund_transaction_params.py +0 -0
  100. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/types/campaign/participant_refund_transaction_response.py +0 -0
  101. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/types/campaign/participant_reward.py +0 -0
  102. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/types/campaign/participant_send_invites_params.py +0 -0
  103. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/types/campaign/participant_send_invites_response.py +0 -0
  104. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/types/campaign/participant_trigger_referral_params.py +0 -0
  105. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/types/campaign/participant_trigger_referral_response.py +0 -0
  106. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/types/campaign/participant_update_params.py +0 -0
  107. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/types/campaign/referral_source.py +0 -0
  108. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/types/campaign/referral_status.py +0 -0
  109. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/types/campaign/reward.py +0 -0
  110. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/types/campaign/reward_approve_params.py +0 -0
  111. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/types/campaign/reward_approve_response.py +0 -0
  112. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/types/campaign/reward_create_params.py +0 -0
  113. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/types/campaign/reward_delete_response.py +0 -0
  114. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/types/campaign/reward_fulfill_response.py +0 -0
  115. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/types/campaign/reward_tax_valuation.py +0 -0
  116. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/types/campaign/reward_update_params.py +0 -0
  117. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/types/campaign/webhook.py +0 -0
  118. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/types/campaign/webhook_create_params.py +0 -0
  119. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/types/campaign/webhook_event.py +0 -0
  120. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/types/campaign/webhook_list_response.py +0 -0
  121. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/types/campaign/webhook_test_params.py +0 -0
  122. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/types/campaign/webhook_test_response.py +0 -0
  123. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/types/campaign/webhook_update_params.py +0 -0
  124. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/types/campaign_create_mobile_participant_token_params.py +0 -0
  125. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/types/campaign_create_mobile_participant_token_response.py +0 -0
  126. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/types/campaign_create_params.py +0 -0
  127. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/types/campaign_list_commissions_params.py +0 -0
  128. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/types/campaign_list_leaderboard_params.py +0 -0
  129. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/types/campaign_list_participants_params.py +0 -0
  130. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/types/campaign_list_payouts_params.py +0 -0
  131. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/types/campaign_list_referrals_params.py +0 -0
  132. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/types/campaign_list_response.py +0 -0
  133. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/types/campaign_retrieve_analytics_params.py +0 -0
  134. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/types/campaign_retrieve_analytics_response.py +0 -0
  135. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/types/campaign_update_params.py +0 -0
  136. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/types/commission_structure.py +0 -0
  137. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/types/create_account_response.py +0 -0
  138. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/types/participant_commission_list.py +0 -0
  139. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/types/participant_list.py +0 -0
  140. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/types/participant_payout_list.py +0 -0
  141. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/types/referral_list.py +0 -0
  142. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/src/growsurf/types/verification_email_response.py +0 -0
  143. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/tests/__init__.py +0 -0
  144. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/tests/api_resources/__init__.py +0 -0
  145. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/tests/api_resources/campaign/__init__.py +0 -0
  146. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/tests/api_resources/campaign/test_commission.py +0 -0
  147. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/tests/api_resources/campaign/test_design.py +0 -0
  148. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/tests/api_resources/campaign/test_emails.py +0 -0
  149. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/tests/api_resources/campaign/test_installation.py +0 -0
  150. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/tests/api_resources/campaign/test_options.py +0 -0
  151. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/tests/api_resources/campaign/test_participant.py +0 -0
  152. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/tests/api_resources/campaign/test_reward.py +0 -0
  153. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/tests/api_resources/campaign/test_rewards.py +0 -0
  154. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/tests/api_resources/campaign/test_webhooks.py +0 -0
  155. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/tests/api_resources/test_account.py +0 -0
  156. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/tests/conftest.py +0 -0
  157. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/tests/sample_file.txt +0 -0
  158. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/tests/test_extract_files.py +0 -0
  159. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/tests/test_files.py +0 -0
  160. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/tests/test_models.py +0 -0
  161. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/tests/test_qs.py +0 -0
  162. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/tests/test_required_args.py +0 -0
  163. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/tests/test_response.py +0 -0
  164. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/tests/test_streaming.py +0 -0
  165. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/tests/test_transform.py +0 -0
  166. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/tests/test_utils/test_datetime_parse.py +0 -0
  167. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/tests/test_utils/test_json.py +0 -0
  168. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/tests/test_utils/test_path.py +0 -0
  169. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/tests/test_utils/test_proxy.py +0 -0
  170. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/tests/test_utils/test_typing.py +0 -0
  171. {growsurf_python-1.1.0 → growsurf_python-1.1.2}/tests/utils.py +0 -0
@@ -0,0 +1,3 @@
1
+ {
2
+ ".": "1.1.2"
3
+ }
@@ -1,5 +1,25 @@
1
1
  # Changelog
2
2
 
3
+ ## [1.1.2](https://github.com/growsurf/growsurf-python/compare/v1.1.1...v1.1.2) (2026-07-11)
4
+
5
+
6
+ ### Bug Fixes
7
+
8
+ * support retry-safe API key rotation ([8656a44](https://github.com/growsurf/growsurf-python/commit/8656a4469e8e48a6ad7252ad1c9241d8cef09ee2))
9
+
10
+ ## [1.1.1](https://github.com/growsurf/growsurf-python/compare/v1.1.0...v1.1.1) (2026-07-09)
11
+
12
+
13
+ ### Bug Fixes
14
+
15
+ * remove referral screenshot REST surface ([28e5902](https://github.com/growsurf/growsurf-python/commit/28e59029205433515d7797b99985fd480ed3a67a))
16
+ * skip mobile token mock tests ([b3592eb](https://github.com/growsurf/growsurf-python/commit/b3592eb63df762cb7539250f6c939f265a7a9fe1))
17
+
18
+
19
+ ### Documentation
20
+
21
+ * reduce PyPI badge cache ([358dd6d](https://github.com/growsurf/growsurf-python/commit/358dd6dc1a69895e12a87772e77561e967f2cf2d))
22
+
3
23
  ## [1.1.0](https://github.com/growsurf/growsurf-python/compare/v1.0.0...v1.1.0) (2026-07-08)
4
24
 
5
25
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: growsurf-python
3
- Version: 1.1.0
3
+ Version: 1.1.2
4
4
  Summary: The official Python library for the growsurf API
5
5
  Project-URL: Homepage, https://github.com/growsurf/growsurf-python
6
6
  Project-URL: Repository, https://github.com/growsurf/growsurf-python
@@ -36,7 +36,7 @@ Description-Content-Type: text/markdown
36
36
  # Growsurf Python API library
37
37
 
38
38
  <!-- prettier-ignore -->
39
- [![PyPI version](https://img.shields.io/pypi/v/growsurf-python.svg?label=pypi%20(stable))](https://pypi.org/project/growsurf-python/)
39
+ [![PyPI version](https://img.shields.io/pypi/v/growsurf-python.svg?label=pypi%20(stable)&cacheSeconds=300)](https://pypi.org/project/growsurf-python/)
40
40
 
41
41
  The Growsurf Python library provides convenient access to the Growsurf REST API from any Python 3.9+
42
42
  application. The library includes type definitions for all request params and response fields,
@@ -1,7 +1,7 @@
1
1
  # Growsurf Python API library
2
2
 
3
3
  <!-- prettier-ignore -->
4
- [![PyPI version](https://img.shields.io/pypi/v/growsurf-python.svg?label=pypi%20(stable))](https://pypi.org/project/growsurf-python/)
4
+ [![PyPI version](https://img.shields.io/pypi/v/growsurf-python.svg?label=pypi%20(stable)&cacheSeconds=300)](https://pypi.org/project/growsurf-python/)
5
5
 
6
6
  The Growsurf Python library provides convenient access to the Growsurf REST API from any Python 3.9+
7
7
  application. The library includes type definitions for all request params and response fields,
@@ -33,8 +33,6 @@ from growsurf.types import (
33
33
  ParticipantPayoutList,
34
34
  ReferralList,
35
35
  CampaignListResponse,
36
- ReferralFlowScreenshot,
37
- ReferralFlowScreenshotsResponse,
38
36
  CampaignCreateMobileParticipantTokenResponse,
39
37
  CampaignRetrieveAnalyticsResponse,
40
38
  )
@@ -47,7 +45,6 @@ Methods:
47
45
  - <code title="patch /campaign/{id}">client.campaign.<a href="./src/growsurf/resources/campaign/campaign.py">update</a>(id, \*\*<a href="src/growsurf/types/campaign_update_params.py">params</a>) -> <a href="./src/growsurf/types/campaign/campaign.py">Campaign</a></code>
48
46
  - <code title="get /campaigns">client.campaign.<a href="./src/growsurf/resources/campaign/campaign.py">list</a>() -> <a href="./src/growsurf/types/campaign_list_response.py">CampaignListResponse</a></code>
49
47
  - <code title="post /campaign/{id}/clone">client.campaign.<a href="./src/growsurf/resources/campaign/campaign.py">clone</a>(id) -> <a href="./src/growsurf/types/campaign/campaign.py">Campaign</a></code>
50
- - <code title="get /campaign/{id}/referral-flow-screenshots">client.campaign.<a href="./src/growsurf/resources/campaign/campaign.py">get_referral_flow_screenshots</a>(id) -> <a href="./src/growsurf/types/referral_flow_screenshots_response.py">ReferralFlowScreenshotsResponse</a></code>
51
48
  - <code title="post /campaign/{id}/mobile-participant-token">client.campaign.<a href="./src/growsurf/resources/campaign/campaign.py">create_mobile_participant_token</a>(id, \*\*<a href="src/growsurf/types/campaign_create_mobile_participant_token_params.py">params</a>) -> <a href="./src/growsurf/types/campaign_create_mobile_participant_token_response.py">CampaignCreateMobileParticipantTokenResponse</a></code>
52
49
  - <code title="get /campaign/{id}/commissions">client.campaign.<a href="./src/growsurf/resources/campaign/campaign.py">list_commissions</a>(id, \*\*<a href="src/growsurf/types/campaign_list_commissions_params.py">params</a>) -> <a href="./src/growsurf/types/participant_commission_list.py">ParticipantCommissionList</a></code>
53
50
  - <code title="get /campaign/{id}/leaderboard">client.campaign.<a href="./src/growsurf/resources/campaign/campaign.py">list_leaderboard</a>(id, \*\*<a href="src/growsurf/types/campaign_list_leaderboard_params.py">params</a>) -> <a href="./src/growsurf/types/participant_list.py">ParticipantList</a></code>
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "growsurf-python"
3
- version = "1.1.0"
3
+ version = "1.1.2"
4
4
  description = "The official Python library for the growsurf API"
5
5
  dynamic = ["readme"]
6
6
  license = "Apache-2.0"
@@ -115,6 +115,7 @@ class Growsurf(SyncAPIClient):
115
115
  custom_query=default_query,
116
116
  _strict_response_validation=_strict_response_validation,
117
117
  )
118
+ self._idempotency_header = "Idempotency-Key"
118
119
 
119
120
  @cached_property
120
121
  def account(self) -> AccountResource:
@@ -311,6 +312,7 @@ class AsyncGrowsurf(AsyncAPIClient):
311
312
  custom_query=default_query,
312
313
  _strict_response_validation=_strict_response_validation,
313
314
  )
315
+ self._idempotency_header = "Idempotency-Key"
314
316
 
315
317
  @cached_property
316
318
  def account(self) -> AsyncAccountResource:
@@ -1,4 +1,4 @@
1
1
  # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2
2
 
3
3
  __title__ = "growsurf"
4
- __version__ = "1.1.0" # x-release-please-version
4
+ __version__ = "1.1.2" # x-release-please-version
@@ -65,9 +65,10 @@ class AccountResource(SyncAPIResource):
65
65
  an API key, so you can call it on a client constructed with any placeholder
66
66
  `api_key`.
67
67
 
68
- The response includes an API key for the new account, but the key is locked
69
- until the account's email address is verified: authenticated endpoints outside
70
- the Accounts group return a `403` with error code `EMAIL_NOT_VERIFIED_ERROR`
68
+ The response includes an API key for the new account, shown once in the
69
+ response. The key is locked until the account's email address is verified:
70
+ authenticated endpoints outside the Accounts group return a `403` with error
71
+ code `EMAIL_NOT_VERIFIED_ERROR`
71
72
  until then (resend the email via the resend-verification-email endpoint, then
72
73
  retry). A welcome email is sent to the address with the verification link and a
73
74
  set-password link for dashboard access. Accounts whose email is never verified
@@ -183,11 +184,13 @@ class AccountResource(SyncAPIResource):
183
184
  timeout: float | httpx.Timeout | None | NotGiven = not_given,
184
185
  ) -> RotateApiKeyResponse:
185
186
  """
186
- Generates a new API key and immediately revokes the old one.
187
+ Generates a new API key and invalidates the key used for the request.
187
188
 
188
- The key used to make this request stops working as soon as the response is
189
- returned update every integration that used the old key with the new one. The
190
- account owner is notified by email whenever the key is rotated.
189
+ The SDK sends a retry-safe `Idempotency-Key`, so automatic retries return the
190
+ same replacement. Store the returned key, then update every integration that
191
+ used the old key. The account owner is notified by email whenever the key is
192
+ rotated. Requires an API key with `api_key:rotate`. This operation is available
193
+ only through the REST API or a GrowSurf API SDK, not through MCP.
191
194
  """
192
195
  return self._post(
193
196
  "/account/api-key",
@@ -288,9 +291,10 @@ class AsyncAccountResource(AsyncAPIResource):
288
291
  an API key, so you can call it on a client constructed with any placeholder
289
292
  `api_key`.
290
293
 
291
- The response includes an API key for the new account, but the key is locked
292
- until the account's email address is verified: authenticated endpoints outside
293
- the Accounts group return a `403` with error code `EMAIL_NOT_VERIFIED_ERROR`
294
+ The response includes an API key for the new account, shown once in the
295
+ response. The key is locked until the account's email address is verified:
296
+ authenticated endpoints outside the Accounts group return a `403` with error
297
+ code `EMAIL_NOT_VERIFIED_ERROR`
294
298
  until then (resend the email via the resend-verification-email endpoint, then
295
299
  retry). A welcome email is sent to the address with the verification link and a
296
300
  set-password link for dashboard access. Accounts whose email is never verified
@@ -406,11 +410,13 @@ class AsyncAccountResource(AsyncAPIResource):
406
410
  timeout: float | httpx.Timeout | None | NotGiven = not_given,
407
411
  ) -> RotateApiKeyResponse:
408
412
  """
409
- Generates a new API key and immediately revokes the old one.
413
+ Generates a new API key and invalidates the key used for the request.
410
414
 
411
- The key used to make this request stops working as soon as the response is
412
- returned update every integration that used the old key with the new one. The
413
- account owner is notified by email whenever the key is rotated.
415
+ The SDK sends a retry-safe `Idempotency-Key`, so automatic retries return the
416
+ same replacement. Store the returned key, then update every integration that
417
+ used the old key. The account owner is notified by email whenever the key is
418
+ rotated. Requires an API key with `api_key:rotate`. This operation is available
419
+ only through the REST API or a GrowSurf API SDK, not through MCP.
414
420
  """
415
421
  return await self._post(
416
422
  "/account/api-key",
@@ -109,7 +109,6 @@ from ...types.campaign_list_response import CampaignListResponse
109
109
  from ...types.participant_payout_list import ParticipantPayoutList
110
110
  from ...types.campaign.referral_status import ReferralStatus
111
111
  from ...types.participant_commission_list import ParticipantCommissionList
112
- from ...types.referral_flow_screenshots_response import ReferralFlowScreenshotsResponse
113
112
  from ...types.campaign_retrieve_analytics_response import CampaignRetrieveAnalyticsResponse
114
113
  from ...types.campaign_create_mobile_participant_token_response import CampaignCreateMobileParticipantTokenResponse
115
114
 
@@ -377,40 +376,6 @@ class CampaignResource(SyncAPIResource):
377
376
  cast_to=Campaign,
378
377
  )
379
378
 
380
- def get_referral_flow_screenshots(
381
- self,
382
- id: str,
383
- *,
384
- # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
385
- # The extra values given here take precedence over values defined on the client or passed to this method.
386
- extra_headers: Headers | None = None,
387
- extra_query: Query | None = None,
388
- extra_body: Body | None = None,
389
- timeout: float | httpx.Timeout | None | NotGiven = not_given,
390
- ) -> ReferralFlowScreenshotsResponse:
391
- """
392
- Captures two preview screenshots for the program: the authenticated referrer
393
- view and the referred-friend view.
394
-
395
- Args:
396
- extra_headers: Send extra headers
397
-
398
- extra_query: Add additional query parameters to the request
399
-
400
- extra_body: Add additional JSON properties to the request
401
-
402
- timeout: Override the client-level default timeout for this request, in seconds
403
- """
404
- if not id:
405
- raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
406
- return self._get(
407
- path_template("/campaign/{id}/referral-flow-screenshots", id=id),
408
- options=make_request_options(
409
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
410
- ),
411
- cast_to=ReferralFlowScreenshotsResponse,
412
- )
413
-
414
379
  def create_mobile_participant_token(
415
380
  self,
416
381
  id: str,
@@ -1113,40 +1078,6 @@ class AsyncCampaignResource(AsyncAPIResource):
1113
1078
  cast_to=Campaign,
1114
1079
  )
1115
1080
 
1116
- async def get_referral_flow_screenshots(
1117
- self,
1118
- id: str,
1119
- *,
1120
- # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
1121
- # The extra values given here take precedence over values defined on the client or passed to this method.
1122
- extra_headers: Headers | None = None,
1123
- extra_query: Query | None = None,
1124
- extra_body: Body | None = None,
1125
- timeout: float | httpx.Timeout | None | NotGiven = not_given,
1126
- ) -> ReferralFlowScreenshotsResponse:
1127
- """
1128
- Captures two preview screenshots for the program: the authenticated referrer
1129
- view and the referred-friend view.
1130
-
1131
- Args:
1132
- extra_headers: Send extra headers
1133
-
1134
- extra_query: Add additional query parameters to the request
1135
-
1136
- extra_body: Add additional JSON properties to the request
1137
-
1138
- timeout: Override the client-level default timeout for this request, in seconds
1139
- """
1140
- if not id:
1141
- raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
1142
- return await self._get(
1143
- path_template("/campaign/{id}/referral-flow-screenshots", id=id),
1144
- options=make_request_options(
1145
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
1146
- ),
1147
- cast_to=ReferralFlowScreenshotsResponse,
1148
- )
1149
-
1150
1081
  async def create_mobile_participant_token(
1151
1082
  self,
1152
1083
  id: str,
@@ -1607,9 +1538,6 @@ class CampaignResourceWithRawResponse:
1607
1538
  self.clone = to_raw_response_wrapper(
1608
1539
  campaign.clone,
1609
1540
  )
1610
- self.get_referral_flow_screenshots = to_raw_response_wrapper(
1611
- campaign.get_referral_flow_screenshots,
1612
- )
1613
1541
  self.create_mobile_participant_token = to_raw_response_wrapper(
1614
1542
  campaign.create_mobile_participant_token,
1615
1543
  )
@@ -1696,9 +1624,6 @@ class AsyncCampaignResourceWithRawResponse:
1696
1624
  self.clone = async_to_raw_response_wrapper(
1697
1625
  campaign.clone,
1698
1626
  )
1699
- self.get_referral_flow_screenshots = async_to_raw_response_wrapper(
1700
- campaign.get_referral_flow_screenshots,
1701
- )
1702
1627
  self.create_mobile_participant_token = async_to_raw_response_wrapper(
1703
1628
  campaign.create_mobile_participant_token,
1704
1629
  )
@@ -1785,9 +1710,6 @@ class CampaignResourceWithStreamingResponse:
1785
1710
  self.clone = to_streamed_response_wrapper(
1786
1711
  campaign.clone,
1787
1712
  )
1788
- self.get_referral_flow_screenshots = to_streamed_response_wrapper(
1789
- campaign.get_referral_flow_screenshots,
1790
- )
1791
1713
  self.create_mobile_participant_token = to_streamed_response_wrapper(
1792
1714
  campaign.create_mobile_participant_token,
1793
1715
  )
@@ -1874,9 +1796,6 @@ class AsyncCampaignResourceWithStreamingResponse:
1874
1796
  self.clone = async_to_streamed_response_wrapper(
1875
1797
  campaign.clone,
1876
1798
  )
1877
- self.get_referral_flow_screenshots = async_to_streamed_response_wrapper(
1878
- campaign.get_referral_flow_screenshots,
1879
- )
1880
1799
  self.create_mobile_participant_token = async_to_streamed_response_wrapper(
1881
1800
  campaign.create_mobile_participant_token,
1882
1801
  )
@@ -96,7 +96,8 @@ class RewardResource(SyncAPIResource):
96
96
  timeout: float | httpx.Timeout | None | NotGiven = not_given,
97
97
  ) -> RewardApproveResponse:
98
98
  """
99
- Approves a manually approved reward earned by a participant.
99
+ Approves a manually approved reward earned by a participant. Requires
100
+ `reward:write`. Passing `fulfill=True` also requires `reward:fulfill`.
100
101
 
101
102
  Args:
102
103
  fulfill: Set true to mark the reward as fulfilled after approval.
@@ -135,7 +136,7 @@ class RewardResource(SyncAPIResource):
135
136
  timeout: float | httpx.Timeout | None | NotGiven = not_given,
136
137
  ) -> RewardFulfillResponse:
137
138
  """
138
- Marks an approved participant reward as fulfilled.
139
+ Marks an approved participant reward as fulfilled. Requires `reward:fulfill`.
139
140
 
140
141
  Args:
141
142
  extra_headers: Send extra headers
@@ -232,7 +233,8 @@ class AsyncRewardResource(AsyncAPIResource):
232
233
  timeout: float | httpx.Timeout | None | NotGiven = not_given,
233
234
  ) -> RewardApproveResponse:
234
235
  """
235
- Approves a manually approved reward earned by a participant.
236
+ Approves a manually approved reward earned by a participant. Requires
237
+ `reward:write`. Passing `fulfill=True` also requires `reward:fulfill`.
236
238
 
237
239
  Args:
238
240
  fulfill: Set true to mark the reward as fulfilled after approval.
@@ -271,7 +273,7 @@ class AsyncRewardResource(AsyncAPIResource):
271
273
  timeout: float | httpx.Timeout | None | NotGiven = not_given,
272
274
  ) -> RewardFulfillResponse:
273
275
  """
274
- Marks an approved participant reward as fulfilled.
276
+ Marks an approved participant reward as fulfilled. Requires `reward:fulfill`.
275
277
 
276
278
  Args:
277
279
  extra_headers: Send extra headers
@@ -23,10 +23,6 @@ from .campaign_list_commissions_params import CampaignListCommissionsParams as C
23
23
  from .campaign_list_leaderboard_params import CampaignListLeaderboardParams as CampaignListLeaderboardParams
24
24
  from .campaign_list_participants_params import CampaignListParticipantsParams as CampaignListParticipantsParams
25
25
  from .campaign_retrieve_analytics_params import CampaignRetrieveAnalyticsParams as CampaignRetrieveAnalyticsParams
26
- from .referral_flow_screenshots_response import (
27
- ReferralFlowScreenshot as ReferralFlowScreenshot,
28
- ReferralFlowScreenshotsResponse as ReferralFlowScreenshotsResponse,
29
- )
30
26
  from .campaign_retrieve_analytics_response import CampaignRetrieveAnalyticsResponse as CampaignRetrieveAnalyticsResponse
31
27
  from .campaign_create_mobile_participant_token_params import (
32
28
  CampaignCreateMobileParticipantTokenParams as CampaignCreateMobileParticipantTokenParams,
@@ -9,4 +9,4 @@ __all__ = ["RotateApiKeyResponse"]
9
9
 
10
10
  class RotateApiKeyResponse(BaseModel):
11
11
  api_key: str = FieldInfo(alias="apiKey")
12
- """The new API key. The previous key is revoked immediately."""
12
+ """The new API key. Store it now; the key used for rotation stops working immediately."""
@@ -15,7 +15,6 @@ from growsurf.types import (
15
15
  CampaignListResponse,
16
16
  ParticipantPayoutList,
17
17
  ParticipantCommissionList,
18
- ReferralFlowScreenshotsResponse,
19
18
  CampaignRetrieveAnalyticsResponse,
20
19
  CampaignCreateMobileParticipantTokenResponse,
21
20
  )
@@ -240,48 +239,6 @@ class TestCampaign:
240
239
  "",
241
240
  )
242
241
 
243
- @pytest.mark.skip(reason="Mock server tests are disabled")
244
- @parametrize
245
- def test_method_get_referral_flow_screenshots(self, client: Growsurf) -> None:
246
- campaign = client.campaign.get_referral_flow_screenshots(
247
- "id",
248
- )
249
- assert_matches_type(ReferralFlowScreenshotsResponse, campaign, path=["response"])
250
-
251
- @pytest.mark.skip(reason="Mock server tests are disabled")
252
- @parametrize
253
- def test_raw_response_get_referral_flow_screenshots(self, client: Growsurf) -> None:
254
- response = client.campaign.with_raw_response.get_referral_flow_screenshots(
255
- "id",
256
- )
257
-
258
- assert response.is_closed is True
259
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
260
- campaign = response.parse()
261
- assert_matches_type(ReferralFlowScreenshotsResponse, campaign, path=["response"])
262
-
263
- @pytest.mark.skip(reason="Mock server tests are disabled")
264
- @parametrize
265
- def test_streaming_response_get_referral_flow_screenshots(self, client: Growsurf) -> None:
266
- with client.campaign.with_streaming_response.get_referral_flow_screenshots(
267
- "id",
268
- ) as response:
269
- assert not response.is_closed
270
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
271
-
272
- campaign = response.parse()
273
- assert_matches_type(ReferralFlowScreenshotsResponse, campaign, path=["response"])
274
-
275
- assert cast(Any, response.is_closed) is True
276
-
277
- @pytest.mark.skip(reason="Mock server tests are disabled")
278
- @parametrize
279
- def test_path_params_get_referral_flow_screenshots(self, client: Growsurf) -> None:
280
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
281
- client.campaign.with_raw_response.get_referral_flow_screenshots(
282
- "",
283
- )
284
-
285
242
  @pytest.mark.skip(reason="Mock server tests are disabled")
286
243
  @parametrize
287
244
  def test_method_create_mobile_participant_token(self, client: Growsurf) -> None:
@@ -890,48 +847,6 @@ class TestAsyncCampaign:
890
847
  "",
891
848
  )
892
849
 
893
- @pytest.mark.skip(reason="Mock server tests are disabled")
894
- @parametrize
895
- async def test_method_get_referral_flow_screenshots(self, async_client: AsyncGrowsurf) -> None:
896
- campaign = await async_client.campaign.get_referral_flow_screenshots(
897
- "id",
898
- )
899
- assert_matches_type(ReferralFlowScreenshotsResponse, campaign, path=["response"])
900
-
901
- @pytest.mark.skip(reason="Mock server tests are disabled")
902
- @parametrize
903
- async def test_raw_response_get_referral_flow_screenshots(self, async_client: AsyncGrowsurf) -> None:
904
- response = await async_client.campaign.with_raw_response.get_referral_flow_screenshots(
905
- "id",
906
- )
907
-
908
- assert response.is_closed is True
909
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
910
- campaign = await response.parse()
911
- assert_matches_type(ReferralFlowScreenshotsResponse, campaign, path=["response"])
912
-
913
- @pytest.mark.skip(reason="Mock server tests are disabled")
914
- @parametrize
915
- async def test_streaming_response_get_referral_flow_screenshots(self, async_client: AsyncGrowsurf) -> None:
916
- async with async_client.campaign.with_streaming_response.get_referral_flow_screenshots(
917
- "id",
918
- ) as response:
919
- assert not response.is_closed
920
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
921
-
922
- campaign = await response.parse()
923
- assert_matches_type(ReferralFlowScreenshotsResponse, campaign, path=["response"])
924
-
925
- assert cast(Any, response.is_closed) is True
926
-
927
- @pytest.mark.skip(reason="Mock server tests are disabled")
928
- @parametrize
929
- async def test_path_params_get_referral_flow_screenshots(self, async_client: AsyncGrowsurf) -> None:
930
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
931
- await async_client.campaign.with_raw_response.get_referral_flow_screenshots(
932
- "",
933
- )
934
-
935
850
  @pytest.mark.skip(reason="Mock server tests are disabled")
936
851
  @parametrize
937
852
  async def test_method_create_mobile_participant_token(self, async_client: AsyncGrowsurf) -> None:
@@ -399,6 +399,17 @@ class TestGrowsurf:
399
399
  test_client.close()
400
400
  test_client2.close()
401
401
 
402
+ def test_mutating_requests_include_a_retry_stable_idempotency_key(self, client: Growsurf) -> None:
403
+ options = FinalRequestOptions(method="post", url="/account/api-key")
404
+ options.idempotency_key = client._idempotency_key()
405
+ request = client._build_request(options)
406
+
407
+ assert client._idempotency_header == "Idempotency-Key"
408
+ idempotency_key = request.headers.get("Idempotency-Key")
409
+ assert idempotency_key is not None
410
+ assert idempotency_key.startswith("stainless-python-retry-")
411
+ assert options.idempotency_key == idempotency_key
412
+
402
413
  def test_validate_headers(self) -> None:
403
414
  client = Growsurf(base_url=base_url, api_key=api_key, _strict_response_validation=True)
404
415
  request = client._build_request(FinalRequestOptions(method="get", url="/foo"))
@@ -1314,6 +1325,17 @@ class TestAsyncGrowsurf:
1314
1325
  await test_client.close()
1315
1326
  await test_client2.close()
1316
1327
 
1328
+ def test_mutating_requests_include_a_retry_stable_idempotency_key(self, client: AsyncGrowsurf) -> None:
1329
+ options = FinalRequestOptions(method="post", url="/account/api-key")
1330
+ options.idempotency_key = client._idempotency_key()
1331
+ request = client._build_request(options)
1332
+
1333
+ assert client._idempotency_header == "Idempotency-Key"
1334
+ idempotency_key = request.headers.get("Idempotency-Key")
1335
+ assert idempotency_key is not None
1336
+ assert idempotency_key.startswith("stainless-python-retry-")
1337
+ assert options.idempotency_key == idempotency_key
1338
+
1317
1339
  def test_validate_headers(self) -> None:
1318
1340
  client = AsyncGrowsurf(base_url=base_url, api_key=api_key, _strict_response_validation=True)
1319
1341
  request = client._build_request(FinalRequestOptions(method="get", url="/foo"))
@@ -420,7 +420,7 @@ wheels = [
420
420
 
421
421
  [[package]]
422
422
  name = "growsurf-python"
423
- version = "0.8.0"
423
+ version = "1.1.1"
424
424
  source = { editable = "." }
425
425
  dependencies = [
426
426
  { name = "anyio" },
@@ -1,3 +0,0 @@
1
- {
2
- ".": "1.1.0"
3
- }
@@ -1,34 +0,0 @@
1
- # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2
-
3
- from typing_extensions import Literal
4
-
5
- from pydantic import Field as FieldInfo
6
-
7
- from .._models import BaseModel
8
-
9
- __all__ = ["ReferralFlowScreenshotsResponse", "ReferralFlowScreenshot"]
10
-
11
-
12
- class ReferralFlowScreenshot(BaseModel):
13
- view: Literal["referrer", "referredFriend"]
14
- """The referral-flow view captured in this screenshot."""
15
-
16
- url: str
17
- """Image URL for the generated screenshot."""
18
-
19
- width: int
20
- """Screenshot viewport width in CSS pixels."""
21
-
22
- height: int
23
- """Screenshot viewport height in CSS pixels."""
24
-
25
-
26
- class ReferralFlowScreenshotsResponse(BaseModel):
27
- referrer: ReferralFlowScreenshot
28
- """Screenshot of the referral flow as a signed-in referrer sees it."""
29
-
30
- referred_friend: ReferralFlowScreenshot = FieldInfo(alias="referredFriend")
31
- """Screenshot of the referral flow as the referred friend sees it."""
32
-
33
- generated_at: int = FieldInfo(alias="generatedAt")
34
- """When the screenshots were generated, as a Unix timestamp in milliseconds."""
File without changes