splunk-soar-sdk 2.3.0__tar.gz → 2.3.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 (221) hide show
  1. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/PKG-INFO +1 -1
  2. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/pyproject.toml +1 -1
  3. splunk_soar_sdk-2.3.2/release_notes.txt +23 -0
  4. splunk_soar_sdk-2.3.2/release_version.txt +1 -0
  5. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/src/soar_sdk/abstract.py +1 -1
  6. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/src/soar_sdk/app.py +4 -9
  7. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/src/soar_sdk/app_client.py +2 -2
  8. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/src/soar_sdk/cli/init/cli.py +2 -2
  9. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/src/soar_sdk/cli/manifests/deserializers.py +1 -10
  10. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/src/soar_sdk/compat.py +10 -0
  11. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/src/soar_sdk/decorators/make_request.py +17 -5
  12. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/src/soar_sdk/meta/app.py +18 -3
  13. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/src/soar_sdk/params.py +30 -2
  14. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/tests/cli/test_convert_cli.py +1 -1
  15. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/tests/cli/test_deserializers.py +7 -5
  16. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/tests/cli/test_utils.py +17 -0
  17. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/tests/example_app/app.json +4 -7
  18. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/tests/example_app_with_webhook/app.json +1 -4
  19. splunk_soar_sdk-2.3.2/tests/mocks/__init__.py +0 -0
  20. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/tests/test_actions_manager.py +6 -18
  21. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/tests/test_make_request_action.py +17 -2
  22. splunk_soar_sdk-2.3.2/tests/test_params.py +43 -0
  23. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/uv.lock +1 -1
  24. splunk_soar_sdk-2.3.0/release_notes.txt +0 -31
  25. splunk_soar_sdk-2.3.0/release_version.txt +0 -1
  26. splunk_soar_sdk-2.3.0/tests/test_params.py +0 -21
  27. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/.github/ISSUE_TEMPLATE/bug.md +0 -0
  28. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  29. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/.github/pull_request_template.md +0 -0
  30. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/.github/utils/github.js +0 -0
  31. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/.github/utils/update_version.py +0 -0
  32. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/.github/workflows/code_quality.yml +0 -0
  33. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/.github/workflows/commit_hygiene.yml +0 -0
  34. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/.github/workflows/generate_docs.yml +0 -0
  35. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/.github/workflows/semantic_release.yml +0 -0
  36. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/.gitignore +0 -0
  37. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/.pre-commit-config.yaml +0 -0
  38. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/.releaserc +0 -0
  39. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/LICENSE +0 -0
  40. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/README.md +0 -0
  41. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/commitlint.config.js +0 -0
  42. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/docs/api_reference.rst +0 -0
  43. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/docs/app_structure/index.rst +0 -0
  44. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/docs/app_structure/pre-commit-config.yaml.rst +0 -0
  45. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/docs/app_structure/pyproject.toml.rst +0 -0
  46. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/docs/app_structure/src_app.rst +0 -0
  47. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/docs/changelog.rst +0 -0
  48. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/docs/cli_reference.rst +0 -0
  49. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/docs/conf.py +0 -0
  50. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/docs/custom_views/index.rst +0 -0
  51. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/docs/custom_views/reusable_components.md +0 -0
  52. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/docs/custom_views/templates.md +0 -0
  53. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/docs/custom_views/view_handlers.md +0 -0
  54. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/docs/getting_started/defining_asset.rst +0 -0
  55. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/docs/getting_started/first_action.rst +0 -0
  56. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/docs/getting_started/index.rst +0 -0
  57. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/docs/getting_started/init_app.rst +0 -0
  58. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/docs/getting_started/installation.rst +0 -0
  59. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/docs/getting_started/testing_and_building.rst +0 -0
  60. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/docs/index.rst +0 -0
  61. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/src/soar_sdk/__init__.py +0 -0
  62. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/src/soar_sdk/action_results.py +0 -0
  63. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/src/soar_sdk/actions_manager.py +0 -0
  64. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/src/soar_sdk/apis/__init__.py +0 -0
  65. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/src/soar_sdk/apis/artifact.py +0 -0
  66. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/src/soar_sdk/apis/container.py +0 -0
  67. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/src/soar_sdk/apis/utils.py +0 -0
  68. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/src/soar_sdk/apis/vault.py +0 -0
  69. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/src/soar_sdk/app_cli_runner.py +0 -0
  70. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/src/soar_sdk/app_templates/basic_app/.gitignore +0 -0
  71. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/src/soar_sdk/app_templates/basic_app/.pre-commit-config.yaml +0 -0
  72. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/src/soar_sdk/app_templates/basic_app/logo.svg +0 -0
  73. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/src/soar_sdk/app_templates/basic_app/logo_dark.svg +0 -0
  74. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/src/soar_sdk/app_templates/basic_app/src/__init__.py +0 -0
  75. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/src/soar_sdk/app_templates/basic_app/uv.lock +0 -0
  76. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/src/soar_sdk/asset.py +0 -0
  77. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/src/soar_sdk/async_utils.py +0 -0
  78. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/src/soar_sdk/cli/__init__.py +0 -0
  79. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/src/soar_sdk/cli/cli.py +0 -0
  80. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/src/soar_sdk/cli/init/__init__.py +0 -0
  81. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/src/soar_sdk/cli/manifests/__init__.py +0 -0
  82. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/src/soar_sdk/cli/manifests/cli.py +0 -0
  83. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/src/soar_sdk/cli/manifests/processors.py +0 -0
  84. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/src/soar_sdk/cli/manifests/serializers.py +0 -0
  85. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/src/soar_sdk/cli/package/cli.py +0 -0
  86. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/src/soar_sdk/cli/package/utils.py +0 -0
  87. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/src/soar_sdk/cli/path_utils.py +0 -0
  88. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/src/soar_sdk/cli/utils.py +0 -0
  89. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/src/soar_sdk/code_renderers/__init__.py +0 -0
  90. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/src/soar_sdk/code_renderers/action_renderer.py +0 -0
  91. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/src/soar_sdk/code_renderers/app_renderer.py +0 -0
  92. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/src/soar_sdk/code_renderers/asset_renderer.py +0 -0
  93. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/src/soar_sdk/code_renderers/renderer.py +0 -0
  94. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/src/soar_sdk/code_renderers/templates/pyproject.toml.jinja +0 -0
  95. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/src/soar_sdk/code_renderers/toml_renderer.py +0 -0
  96. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/src/soar_sdk/colors.py +0 -0
  97. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/src/soar_sdk/crypto.py +0 -0
  98. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/src/soar_sdk/decorators/__init__.py +0 -0
  99. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/src/soar_sdk/decorators/action.py +0 -0
  100. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/src/soar_sdk/decorators/on_poll.py +0 -0
  101. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/src/soar_sdk/decorators/test_connectivity.py +0 -0
  102. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/src/soar_sdk/decorators/view_handler.py +0 -0
  103. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/src/soar_sdk/decorators/webhook.py +0 -0
  104. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/src/soar_sdk/exceptions.py +0 -0
  105. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/src/soar_sdk/input_spec.py +0 -0
  106. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/src/soar_sdk/logging.py +0 -0
  107. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/src/soar_sdk/meta/__init__.py +0 -0
  108. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/src/soar_sdk/meta/actions.py +0 -0
  109. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/src/soar_sdk/meta/adapters.py +0 -0
  110. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/src/soar_sdk/meta/datatypes.py +0 -0
  111. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/src/soar_sdk/meta/dependencies.py +0 -0
  112. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/src/soar_sdk/meta/webhooks.py +0 -0
  113. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/src/soar_sdk/models/__init__.py +0 -0
  114. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/src/soar_sdk/models/artifact.py +0 -0
  115. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/src/soar_sdk/models/container.py +0 -0
  116. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/src/soar_sdk/models/vault_attachment.py +0 -0
  117. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/src/soar_sdk/models/view.py +0 -0
  118. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/src/soar_sdk/paths.py +0 -0
  119. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/src/soar_sdk/py.typed +0 -0
  120. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/src/soar_sdk/shims/phantom/action_result.py +0 -0
  121. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/src/soar_sdk/shims/phantom/app.py +0 -0
  122. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/src/soar_sdk/shims/phantom/base_connector.py +0 -0
  123. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/src/soar_sdk/shims/phantom/connector_result.py +0 -0
  124. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/src/soar_sdk/shims/phantom/consts.py +0 -0
  125. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/src/soar_sdk/shims/phantom/encryption_helper.py +0 -0
  126. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/src/soar_sdk/shims/phantom/install_info.py +0 -0
  127. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/src/soar_sdk/shims/phantom/json_keys.py +0 -0
  128. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/src/soar_sdk/shims/phantom/ph_ipc.py +0 -0
  129. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/src/soar_sdk/shims/phantom/vault.py +0 -0
  130. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/src/soar_sdk/shims/phantom_common/app_interface/app_interface.py +0 -0
  131. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/src/soar_sdk/shims/phantom_common/encryption/encryption_manager_factory.py +0 -0
  132. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/src/soar_sdk/templates/base/base_template.html +0 -0
  133. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/src/soar_sdk/templates/base/error.html +0 -0
  134. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/src/soar_sdk/templates/base/header.html +0 -0
  135. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/src/soar_sdk/templates/base/logo_header.html +0 -0
  136. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/src/soar_sdk/templates/components/pie_chart.html +0 -0
  137. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/src/soar_sdk/templates/widgets/widget_resize_snippet.html +0 -0
  138. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/src/soar_sdk/templates/widgets/widget_template.html +0 -0
  139. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/src/soar_sdk/types.py +0 -0
  140. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/src/soar_sdk/views/__init__.py +0 -0
  141. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/src/soar_sdk/views/component_registry.py +0 -0
  142. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/src/soar_sdk/views/components/__init__.py +0 -0
  143. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/src/soar_sdk/views/components/pie_chart.py +0 -0
  144. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/src/soar_sdk/views/template_filters.py +0 -0
  145. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/src/soar_sdk/views/template_renderer.py +0 -0
  146. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/src/soar_sdk/views/view_parser.py +0 -0
  147. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/src/soar_sdk/webhooks/__init__.py +0 -0
  148. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/src/soar_sdk/webhooks/models.py +0 -0
  149. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/src/soar_sdk/webhooks/routing.py +0 -0
  150. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/test.png +0 -0
  151. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/test.txt +0 -0
  152. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/tests/__init__.py +0 -0
  153. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/tests/cli/__init__.py +0 -0
  154. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/tests/cli/datapath_parse.py +0 -0
  155. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/tests/cli/manifests/__init__.py +0 -0
  156. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/tests/cli/manifests/test_processors.py +0 -0
  157. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/tests/cli/test_assets/converted_app/actions.py.txt +0 -0
  158. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/tests/cli/test_cli.py +0 -0
  159. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/tests/cli/test_init_cli.py +0 -0
  160. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/tests/cli/test_manifests_cli.py +0 -0
  161. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/tests/cli/test_package_cli.py +0 -0
  162. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/tests/cli/test_serializers.py +0 -0
  163. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/tests/code_renderers/test_action_renderer.py +0 -0
  164. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/tests/conftest.py +0 -0
  165. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/tests/example_app/example_asset.json +0 -0
  166. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/tests/example_app/logo.svg +0 -0
  167. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/tests/example_app/logo_dark.svg +0 -0
  168. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/tests/example_app/pyproject.toml +0 -0
  169. /splunk_soar_sdk-2.3.0/tests/example_app/src/actions/__init__.py → /splunk_soar_sdk-2.3.2/tests/example_app/release_notes/v1.md +0 -0
  170. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/tests/example_app/src/__init__.py +0 -0
  171. {splunk_soar_sdk-2.3.0/tests/interfaces → splunk_soar_sdk-2.3.2/tests/example_app/src/actions}/__init__.py +0 -0
  172. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/tests/example_app/src/actions/async_action.py +0 -0
  173. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/tests/example_app/src/actions/generate_category.py +0 -0
  174. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/tests/example_app/src/actions/reverse_string.py +0 -0
  175. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/tests/example_app/src/app.py +0 -0
  176. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/tests/example_app/src/ignoreme.txt +0 -0
  177. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/tests/example_app/templates/reverse_string.html +0 -0
  178. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/tests/example_app/uv.lock +0 -0
  179. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/tests/example_app_with_webhook/logo.svg +0 -0
  180. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/tests/example_app_with_webhook/logo_dark.svg +0 -0
  181. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/tests/example_app_with_webhook/pyproject.toml +0 -0
  182. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/tests/example_app_with_webhook/src/__init__.py +0 -0
  183. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/tests/example_app_with_webhook/src/app.py +0 -0
  184. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/tests/example_app_with_webhook/uv.lock +0 -0
  185. {splunk_soar_sdk-2.3.0/tests/meta → splunk_soar_sdk-2.3.2/tests/interfaces}/__init__.py +0 -0
  186. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/tests/interfaces/test_artifact_interface.py +0 -0
  187. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/tests/interfaces/test_container_interface.py +0 -0
  188. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/tests/interfaces/test_vault_interface.py +0 -0
  189. {splunk_soar_sdk-2.3.0/tests/mocks → splunk_soar_sdk-2.3.2/tests/meta}/__init__.py +0 -0
  190. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/tests/meta/test_actions.py +0 -0
  191. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/tests/meta/test_adapters.py +0 -0
  192. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/tests/meta/test_datatypes.py +0 -0
  193. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/tests/meta/test_dependencies.py +0 -0
  194. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/tests/meta/test_webhooks.py +0 -0
  195. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/tests/mocks/dynamic_mocks.py +0 -0
  196. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/tests/mocks/importable_action.py +0 -0
  197. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/tests/stubs.py +0 -0
  198. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/tests/test_action_results.py +0 -0
  199. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/tests/test_app.py +0 -0
  200. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/tests/test_app_action.py +0 -0
  201. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/tests/test_app_action_params.py +0 -0
  202. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/tests/test_app_action_results.py +0 -0
  203. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/tests/test_app_client.py +0 -0
  204. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/tests/test_app_runner.py +0 -0
  205. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/tests/test_asset.py +0 -0
  206. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/tests/test_assets/splunk-sdk-2.1.0.tar.gz +0 -0
  207. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/tests/test_async_integration.py +0 -0
  208. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/tests/test_async_utils.py +0 -0
  209. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/tests/test_code_renderers.py +0 -0
  210. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/tests/test_compat.py +0 -0
  211. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/tests/test_container.py +0 -0
  212. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/tests/test_custom_views.py +0 -0
  213. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/tests/test_encryption.py +0 -0
  214. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/tests/test_logging.py +0 -0
  215. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/tests/test_on_poll.py +0 -0
  216. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/tests/test_template_filters.py +0 -0
  217. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/tests/test_template_renderer.py +0 -0
  218. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/tests/test_test_connectivity.py +0 -0
  219. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/tests/test_view_parser.py +0 -0
  220. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/tests/webhooks/test_models.py +0 -0
  221. {splunk_soar_sdk-2.3.0 → splunk_soar_sdk-2.3.2}/tests/webhooks/test_routing.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: splunk-soar-sdk
3
- Version: 2.3.0
3
+ Version: 2.3.2
4
4
  Summary: The official framework for developing and testing Splunk SOAR Apps
5
5
  Project-URL: Homepage, https://github.com/phantomcyber/splunk-soar-sdk
6
6
  Project-URL: Documentation, https://github.com/phantomcyber/splunk-soar-sdk
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "splunk-soar-sdk"
3
- version = "2.3.0"
3
+ version = "2.3.2"
4
4
  description = "The official framework for developing and testing Splunk SOAR Apps"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.9, <3.14"
@@ -0,0 +1,23 @@
1
+ ## [2.3.2](https://github.com/phantomcyber/splunk-soar-sdk/compare/2.3.1...2.3.2) (2025-10-10)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * python versions should be strings not list ([b21b0d5](https://github.com/phantomcyber/splunk-soar-sdk/commit/b21b0d500300bd70440f5c9267f6a12746975fec))
7
+ * release notes are required in the app for soars app updates and new apps modals ([f5ca7ad](https://github.com/phantomcyber/splunk-soar-sdk/commit/f5ca7ad1136801a393e4ffb6d209990fc4bfab80))
8
+
9
+
10
+
11
+
12
+
13
+ ## [2.3.2](https://github.com/phantomcyber/splunk-soar-sdk/compare/2.3.1...2.3.2) (2025-10-10)
14
+
15
+
16
+ ### Bug Fixes
17
+
18
+ * python versions should be strings not list ([b21b0d5](https://github.com/phantomcyber/splunk-soar-sdk/commit/b21b0d500300bd70440f5c9267f6a12746975fec))
19
+ * release notes are required in the app for soars app updates and new apps modals ([f5ca7ad](https://github.com/phantomcyber/splunk-soar-sdk/commit/f5ca7ad1136801a393e4ffb6d209990fc4bfab80))
20
+
21
+
22
+
23
+
@@ -0,0 +1 @@
1
+ 2.3.2
@@ -234,6 +234,6 @@ class SOARClient(Generic[SummaryType]):
234
234
  pass
235
235
 
236
236
  @abstractmethod
237
- def get_message(self) -> Optional[str]:
237
+ def get_message(self) -> str:
238
238
  """Get the summary message for the action run."""
239
239
  pass
@@ -101,7 +101,7 @@ class App:
101
101
  product_name: str,
102
102
  publisher: str,
103
103
  appid: str,
104
- python_version: Optional[list[PythonVersion]] = None,
104
+ python_version: Optional[Union[list[PythonVersion], str]] = None,
105
105
  min_phantom_version: str = MIN_PHANTOM_VERSION,
106
106
  fips_compliant: bool = False,
107
107
  asset_cls: type[BaseAsset] = BaseAsset,
@@ -113,7 +113,7 @@ class App:
113
113
  raise ValueError(f"Appid is not a valid uuid: {appid}")
114
114
 
115
115
  if python_version is None:
116
- python_version = PythonVersion.all()
116
+ python_version = PythonVersion.all_csv()
117
117
 
118
118
  self.app_meta_info = {
119
119
  "name": name,
@@ -636,7 +636,7 @@ class App:
636
636
  ],
637
637
  actions_manager: ActionsManager,
638
638
  action_params: Optional[Params] = None,
639
- message: Optional[str] = None,
639
+ message: str = "",
640
640
  summary: Optional[ActionOutput] = None,
641
641
  ) -> bool:
642
642
  """Handles multiple ways of returning response from action.
@@ -657,9 +657,7 @@ class App:
657
657
  )
658
658
  # Handle empty list/iterator case
659
659
  if not statuses:
660
- result = ActionOutput(
661
- status=True, message=message or "Action completed successfully"
662
- )
660
+ result = ActionOutput(status=True, message=message)
663
661
  else:
664
662
  return all(statuses)
665
663
 
@@ -667,9 +665,6 @@ class App:
667
665
  output_dict = result.dict(by_alias=True)
668
666
  param_dict = action_params.dict() if action_params else None
669
667
 
670
- if not message:
671
- message = "Action completed successfully"
672
-
673
668
  result = ActionResult(
674
669
  status=True,
675
670
  message=message,
@@ -44,7 +44,7 @@ class AppClient(SOARClient[SummaryType]):
44
44
  self.basic_auth: Optional[BasicAuth] = None
45
45
 
46
46
  self._summary: Optional[SummaryType] = None
47
- self._message: Optional[str] = None
47
+ self._message: str = ""
48
48
  self.__container_id: int = 0
49
49
  self.__asset_id: str = ""
50
50
 
@@ -171,6 +171,6 @@ class AppClient(SOARClient[SummaryType]):
171
171
  """Get the summary for the action result."""
172
172
  return self._summary
173
173
 
174
- def get_message(self) -> Optional[str]:
174
+ def get_message(self) -> str:
175
175
  """Get the message for the action result."""
176
176
  return self._message
@@ -269,11 +269,11 @@ def convert_connector_to_sdk(
269
269
  # Convert the main module path to the SDK format, but save a reference to the original
270
270
  app_meta.main_module = "src.app:app"
271
271
 
272
- app_python_versions = app_meta.python_version
272
+ app_python_versions = PythonVersion.from_csv(app_meta.python_version)
273
273
  enforced_python_versions = PythonVersion.all()
274
274
  if set(app_python_versions) != set(enforced_python_versions):
275
275
  rprint(
276
- f"[yellow]The provided app declares support for Python versions {[str(v) for v in app_python_versions]}.[/]"
276
+ f"[yellow]The provided app declares support for Python versions '{app_meta.python_version}'.[/]"
277
277
  )
278
278
  rprint(
279
279
  f"[yellow]The converted app will support the default versions {[str(v) for v in enforced_python_versions]}.[/]"
@@ -6,7 +6,7 @@ import pydantic
6
6
 
7
7
  from soar_sdk.action_results import ActionOutput, OutputFieldSpecification, OutputField
8
8
  from soar_sdk.cli.utils import normalize_field_name, NormalizationResult
9
- from soar_sdk.compat import PythonVersion, remove_when_soar_newer_than
9
+ from soar_sdk.compat import remove_when_soar_newer_than
10
10
  from soar_sdk.meta.actions import ActionMeta
11
11
  from soar_sdk.meta.app import AppMeta
12
12
  from soar_sdk.params import Params, Param
@@ -41,15 +41,6 @@ class AppMetaDeserializer:
41
41
  """
42
42
  manifest: dict[str, Any] = json.loads(json_path.read_text())
43
43
 
44
- # Massage the python_version field, which may be a comma-separated string
45
- python_version = manifest.pop("python_version", None)
46
- if isinstance(python_version, str):
47
- manifest["python_version"] = PythonVersion.from_csv(python_version)
48
- elif isinstance(python_version, list):
49
- manifest["python_version"] = [
50
- PythonVersion.from_str(py) for py in python_version
51
- ]
52
-
53
44
  deserialized_actions = [
54
45
  ActionDeserializer.from_action_json(action)
55
46
  for action in manifest.get("actions", [])
@@ -59,11 +59,21 @@ class PythonVersion(str, Enum):
59
59
  cls.from_str(version.strip()) for version in versions if version.strip()
60
60
  ]
61
61
 
62
+ @classmethod
63
+ def to_csv(cls, versions: list["PythonVersion"]) -> str:
64
+ """Converts a list of PythonVersion enums to a comma-separated string."""
65
+ return ",".join(str(v) for v in versions)
66
+
62
67
  @classmethod
63
68
  def all(cls) -> list["PythonVersion"]:
64
69
  """Returns a list of all supported Python versions."""
65
70
  return [cls.PY_3_9, cls.PY_3_13]
66
71
 
72
+ @classmethod
73
+ def all_csv(cls) -> str:
74
+ """Returns a comma-separated string of all supported Python versions."""
75
+ return ",".join(str(v) for v in cls.all())
76
+
67
77
  @classmethod
68
78
  def to_requires_python(cls, versions: list["PythonVersion"]) -> str:
69
79
  """Converts a list of PythonVersions to a PEP-508 compatible requires-python string."""
@@ -43,19 +43,31 @@ class MakeRequestDecorator:
43
43
  "The 'make_request' decorator can only be used once per App instance."
44
44
  )
45
45
 
46
- # Validate function signature - must have at least one parameter of type MakeRequestParams
46
+ # Validate function signature - must have exactly one parameter of type MakeRequestParams
47
47
  signature = inspect.signature(function)
48
48
  params = list(signature.parameters.values())
49
49
 
50
- if not any(param.annotation == MakeRequestParams for param in params):
50
+ make_request_params = [
51
+ param
52
+ for param in params
53
+ if inspect.isclass(param.annotation)
54
+ and issubclass(param.annotation, MakeRequestParams)
55
+ ]
56
+
57
+ if len(make_request_params) == 0:
58
+ raise TypeError(
59
+ "Make request action function must have exactly one parameter of type MakeRequestParams or its subclass."
60
+ )
61
+ elif len(make_request_params) > 1:
62
+ param_names = [p.name for p in make_request_params]
51
63
  raise TypeError(
52
- f"Make request action function must have at least one parameter of type MakeRequestParams, got {params[0].annotation}"
64
+ f"Make request action function can only have one MakeRequestParams parameter, "
65
+ f"but found {len(make_request_params)}: {param_names}"
53
66
  )
54
67
 
55
68
  action_identifier = "make_request"
56
69
  action_name = "make request"
57
- # for make request action use MakeRequestParams
58
- validated_params_class = MakeRequestParams
70
+ validated_params_class = make_request_params[0].annotation
59
71
 
60
72
  return_type = inspect.signature(function).return_annotation
61
73
  if return_type is not inspect.Signature.empty:
@@ -1,5 +1,5 @@
1
- from pydantic import BaseModel, Field
2
- from typing import Optional
1
+ from pydantic import BaseModel, Field, validator
2
+ from typing import Optional, Union
3
3
 
4
4
  from soar_sdk.asset import AssetFieldSpecification
5
5
  from soar_sdk.compat import PythonVersion
@@ -32,7 +32,7 @@ class AppMeta(BaseModel):
32
32
  logo: str = ""
33
33
  logo_dark: str = ""
34
34
  product_name: str = ""
35
- python_version: list[PythonVersion] = Field(default_factory=PythonVersion.all)
35
+ python_version: str = Field(default_factory=PythonVersion.all_csv)
36
36
  product_version_regex: str = ".*"
37
37
  publisher: str = ""
38
38
  utctime_updated: str = ""
@@ -47,6 +47,21 @@ class AppMeta(BaseModel):
47
47
 
48
48
  webhook: Optional[WebhookMeta]
49
49
 
50
+ @validator("python_version", pre=True)
51
+ def convert_python_version_to_csv(cls, v: Union[list, str]) -> str:
52
+ """Converts python_version to a comma-separated string if it's a list and validates versions."""
53
+ if isinstance(v, list):
54
+ # Validate each version in the list and convert to CSV
55
+ validated_versions = [PythonVersion.from_str(str(version)) for version in v]
56
+ return PythonVersion.to_csv(validated_versions)
57
+ elif isinstance(v, str):
58
+ # Validate the CSV string by parsing it and convert back to CSV
59
+ validated_versions = PythonVersion.from_csv(v)
60
+ return PythonVersion.to_csv(validated_versions)
61
+ raise ValueError(
62
+ f"Invalid python_version type must be a list or a comma-separated string: {v}"
63
+ )
64
+
50
65
  def to_json_manifest(self) -> dict:
51
66
  """Converts the AppMeta instance to a JSON-compatible dictionary."""
52
67
  return self.dict(exclude_none=True)
@@ -1,4 +1,4 @@
1
- from typing import Optional, Union, Any
1
+ from typing import Optional, Union, Any, ClassVar
2
2
  from typing_extensions import NotRequired, TypedDict
3
3
 
4
4
  from pydantic.fields import Field, Undefined
@@ -178,6 +178,34 @@ class OnPollParams(Params):
178
178
  class MakeRequestParams(Params):
179
179
  """Canonical parameters for the special make request action."""
180
180
 
181
+ # Define allowed field names for subclasses
182
+ _ALLOWED_FIELDS: ClassVar[set[str]] = {
183
+ "http_method",
184
+ "endpoint",
185
+ "headers",
186
+ "query_parameters",
187
+ "body",
188
+ "timeout",
189
+ "verify_ssl",
190
+ }
191
+
192
+ def __init_subclass__(cls, **kwargs: dict[str, Any]) -> None:
193
+ """Validate that subclasses only define allowed fields."""
194
+ super().__init_subclass__(**kwargs)
195
+ cls._validate_make_request_fields()
196
+
197
+ @classmethod
198
+ def _validate_make_request_fields(cls) -> None:
199
+ """Ensure subclasses only define allowed MakeRequest fields."""
200
+ # Check if any fields are not in the allowed set
201
+ invalid_fields = set(cls.__fields__.keys()) - cls._ALLOWED_FIELDS
202
+
203
+ if invalid_fields:
204
+ raise TypeError(
205
+ f"MakeRequestParams subclass '{cls.__name__}' can only define these fields: "
206
+ f"{sorted(cls._ALLOWED_FIELDS)}. Invalid fields: {sorted(invalid_fields)}"
207
+ )
208
+
181
209
  http_method: str = Param(
182
210
  description="The HTTP method to use for the request.",
183
211
  required=True,
@@ -194,7 +222,7 @@ class MakeRequestParams(Params):
194
222
  required=False,
195
223
  )
196
224
 
197
- query_params: str = Param(
225
+ query_parameters: str = Param(
198
226
  description="The query string to send with the request.",
199
227
  required=False,
200
228
  )
@@ -223,7 +223,7 @@ def test_convert_cli_updates_py_versions(runner, tmp_path, app_meta):
223
223
  print(result.output) # For debugging purposes
224
224
 
225
225
  assert result.exit_code == 0
226
- assert "declares support for Python versions ['3.9']" in result.output
226
+ assert "declares support for Python versions '3.9'" in result.output
227
227
  assert "will support the default versions ['3.9', '3.13']" in result.output
228
228
  assert (
229
229
  'requires-python = ">=3.9, <3.14"'
@@ -100,9 +100,9 @@ def test_from_app_json_basic_deserialization(basic_app_data, create_app_json):
100
100
  @pytest.mark.parametrize(
101
101
  "python_version_input,expected",
102
102
  [
103
- ("3.9,3.13", [PythonVersion.PY_3_9, PythonVersion.PY_3_13]),
104
- (["3.9", "3.13"], [PythonVersion.PY_3_9, PythonVersion.PY_3_13]),
105
- (None, PythonVersion.all()), # Should use default when None
103
+ ("3.9,3.13", f"{PythonVersion.PY_3_9},{PythonVersion.PY_3_13}"),
104
+ (["3.9", "3.13"], f"{PythonVersion.PY_3_9},{PythonVersion.PY_3_13}"),
105
+ (None, PythonVersion.all_csv()), # Should use default when None
106
106
  ],
107
107
  )
108
108
  def test_from_app_json_python_version_handling(
@@ -127,7 +127,7 @@ def test_from_app_json_python_version_missing(basic_app_data, create_app_json):
127
127
 
128
128
  # Should use default from AppMeta model
129
129
  result = deserialized_result.app_meta
130
- assert result.python_version == PythonVersion.all()
130
+ assert result.python_version == PythonVersion.all_csv()
131
131
 
132
132
 
133
133
  def test_from_app_json_invalid_python_version(basic_app_data, create_app_json):
@@ -322,7 +322,9 @@ def test_from_app_json_complex_example(create_app_json):
322
322
  assert result.name == "example_app"
323
323
  assert result.appid == "9b388c08-67de-4ca4-817f-26f8fb7cbf55"
324
324
  assert result.product_vendor == "Splunk Inc."
325
- assert result.python_version == [PythonVersion.PY_3_9, PythonVersion.PY_3_13]
325
+ assert (
326
+ result.python_version == f"{PythonVersion.PY_3_9},{PythonVersion.PY_3_13}"
327
+ )
326
328
  assert result.project_name == "example_app"
327
329
  assert len(result.actions) == 1
328
330
  assert result.fips_compliant is False
@@ -2,6 +2,7 @@ import pytest
2
2
  import keyword
3
3
 
4
4
  from soar_sdk.cli.utils import normalize_field_name
5
+ from soar_sdk.meta.app import AppMeta
5
6
 
6
7
 
7
8
  class TestNormalizeFieldName:
@@ -60,3 +61,19 @@ class TestNormalizeFieldName:
60
61
 
61
62
  with pytest.raises(ValueError, match="must contain at least one letter"):
62
63
  normalize_field_name("______")
64
+
65
+
66
+ def test_bad_python_version_type():
67
+ """Test that an invalid python_version type raises a ValueError."""
68
+ with pytest.raises(
69
+ ValueError,
70
+ match="Invalid python_version type must be a list or a comma-separated string",
71
+ ):
72
+ AppMeta(
73
+ project_name="test_app",
74
+ description="Test app",
75
+ license="Copyright (c) 2025 Splunk Inc.",
76
+ app_version="1.0.0",
77
+ package_name="test_app",
78
+ python_version=123,
79
+ )
@@ -12,10 +12,7 @@
12
12
  "logo": "logo.svg",
13
13
  "logo_dark": "logo_dark.svg",
14
14
  "product_name": "Example App",
15
- "python_version": [
16
- "3.9",
17
- "3.13"
18
- ],
15
+ "python_version": "3.9,3.13",
19
16
  "product_version_regex": ".*",
20
17
  "publisher": "Splunk Inc.",
21
18
  "utctime_updated": "2025-09-09T15:29:27.279851Z",
@@ -499,9 +496,9 @@
499
496
  "primary": false,
500
497
  "allow_list": false
501
498
  },
502
- "query_params": {
499
+ "query_parameters": {
503
500
  "order": 3,
504
- "name": "query_params",
501
+ "name": "query_parameters",
505
502
  "description": "The query string to send with the request.",
506
503
  "data_type": "string",
507
504
  "required": false,
@@ -562,7 +559,7 @@
562
559
  "data_type": "string"
563
560
  },
564
561
  {
565
- "data_path": "action_result.parameter.query_params",
562
+ "data_path": "action_result.parameter.query_parameters",
566
563
  "data_type": "string"
567
564
  },
568
565
  {
@@ -12,10 +12,7 @@
12
12
  "logo": "logo.svg",
13
13
  "logo_dark": "logo_dark.svg",
14
14
  "product_name": "Example App",
15
- "python_version": [
16
- "3.9",
17
- "3.13"
18
- ],
15
+ "python_version": "3.9,3.13",
19
16
  "product_version_regex": ".*",
20
17
  "publisher": "Splunk Inc.",
21
18
  "utctime_updated": "2025-04-17T12:00:00.000000Z",
File without changes
@@ -98,10 +98,7 @@ def test_action_called_returning_iterator(
98
98
  example_app.handle(simple_action_input.json())
99
99
 
100
100
  assert len(example_app.actions_manager.get_results()) == 5
101
- assert all(
102
- "success" in result.message
103
- for result in example_app.actions_manager.get_results()
104
- )
101
+ assert all(result.status for result in example_app.actions_manager.get_results())
105
102
 
106
103
 
107
104
  def test_async_action_called_returning_iterator(
@@ -120,10 +117,7 @@ def test_async_action_called_returning_iterator(
120
117
  example_app.handle(simple_action_input.json())
121
118
 
122
119
  assert len(example_app.actions_manager.get_results()) == 5
123
- assert all(
124
- "success" in result.message
125
- for result in example_app.actions_manager.get_results()
126
- )
120
+ assert all(result.status for result in example_app.actions_manager.get_results())
127
121
 
128
122
 
129
123
  def test_action_called_returning_list(
@@ -139,10 +133,7 @@ def test_action_called_returning_list(
139
133
  example_app.handle(simple_action_input.json())
140
134
 
141
135
  assert len(example_app.actions_manager.get_results()) == 5
142
- assert all(
143
- "success" in result.message
144
- for result in example_app.actions_manager.get_results()
145
- )
136
+ assert all(result.status for result in example_app.actions_manager.get_results())
146
137
 
147
138
 
148
139
  def test_async_action_called_returning_list(
@@ -158,10 +149,7 @@ def test_async_action_called_returning_list(
158
149
  example_app.handle(simple_action_input.json())
159
150
 
160
151
  assert len(example_app.actions_manager.get_results()) == 5
161
- assert all(
162
- "success" in result.message
163
- for result in example_app.actions_manager.get_results()
164
- )
152
+ assert all(result.status for result in example_app.actions_manager.get_results())
165
153
 
166
154
 
167
155
  def test_action_called_with_default_message_set(
@@ -174,7 +162,7 @@ def test_action_called_with_default_message_set(
174
162
  example_app.handle(simple_action_input.json())
175
163
 
176
164
  assert len(example_app.actions_manager.get_results()) == 1
177
- assert "success" in example_app.actions_manager.get_results()[0].message
165
+ assert example_app.actions_manager.get_results()[0].status
178
166
 
179
167
 
180
168
  def test_action_called_with_timezone_asset(example_app: App):
@@ -204,7 +192,7 @@ def test_action_called_with_timezone_asset(example_app: App):
204
192
  example_app.handle(action_input.json())
205
193
 
206
194
  assert len(example_app.actions_manager.get_results()) == 1
207
- assert "success" in example_app.actions_manager.get_results()[0].message
195
+ assert example_app.actions_manager.get_results()[0].status
208
196
 
209
197
 
210
198
  def test_actions_provider_running_undefined_action(
@@ -61,7 +61,7 @@ def test_make_request_action_without_make_request_params(app_with_action: App):
61
61
  pass
62
62
 
63
63
  assert (
64
- "Make request action function must have at least one parameter of type MakeRequestParams, got <class 'soar_sdk.abstract.SOARClient'>"
64
+ "Make request action function must have exactly one parameter of type MakeRequestParams or its subclass."
65
65
  in str(exception_info)
66
66
  )
67
67
 
@@ -72,7 +72,22 @@ def test_make_request_action_without_make_request_params(app_with_action: App):
72
72
  pass
73
73
 
74
74
  assert (
75
- "Make request action function must have at least one parameter of type MakeRequestParams, got <class 'soar_sdk.params.Params'>"
75
+ "Make request action function must have exactly one parameter of type MakeRequestParams or its subclass."
76
+ in str(exception_info)
77
+ )
78
+
79
+
80
+ def test_make_request_action_with_multiple_params(app_with_action: App):
81
+ with pytest.raises(TypeError) as exception_info:
82
+
83
+ @app_with_action.make_request()
84
+ def http_action(
85
+ params: MakeRequestParams, params2: MakeRequestParams, asset: ValidAsset
86
+ ) -> MakeRequestOutput:
87
+ pass
88
+
89
+ assert (
90
+ "Make request action function can only have one MakeRequestParams parameter, but found 2: ['params', 'params2']"
76
91
  in str(exception_info)
77
92
  )
78
93
 
@@ -0,0 +1,43 @@
1
+ import pytest
2
+ from pydantic import ValidationError
3
+
4
+ from soar_sdk.params import Param, Params, MakeRequestParams
5
+
6
+ from tests.stubs import SampleActionParams
7
+
8
+
9
+ def test_models_have_params_validated():
10
+ with pytest.raises(ValidationError):
11
+ SampleActionParams(field1="five")
12
+
13
+
14
+ def test_sensitive_param_must_be_str():
15
+ class BrokenParams(Params):
16
+ secret: bool = Param(sensitive=True)
17
+
18
+ with pytest.raises(TypeError) as e:
19
+ BrokenParams._to_json_schema()
20
+
21
+ assert e.match("Sensitive parameter secret must be type str, not bool")
22
+
23
+
24
+ def test_make_request_params_validation():
25
+ with pytest.raises(TypeError) as e:
26
+
27
+ class BrokenMakeRequestParams(MakeRequestParams):
28
+ not_allowed: str = Param(description="Not allowed")
29
+
30
+ assert (
31
+ str(e.value)
32
+ == "MakeRequestParams subclass 'BrokenMakeRequestParams' can only define these fields: ['body', 'endpoint', 'headers', 'http_method', 'query_parameters', 'timeout', 'verify_ssl']. Invalid fields: ['not_allowed']"
33
+ )
34
+
35
+
36
+ def test_make_request_params_subclass_schema():
37
+ class MakeRequestParamsSubclass(MakeRequestParams):
38
+ query_parameters: str = Param(description="Query parameters for virustotal")
39
+
40
+ assert (
41
+ MakeRequestParamsSubclass._to_json_schema()["query_parameters"]["description"]
42
+ == "Query parameters for virustotal"
43
+ )
@@ -1291,7 +1291,7 @@ wheels = [
1291
1291
 
1292
1292
  [[package]]
1293
1293
  name = "splunk-soar-sdk"
1294
- version = "2.3.0"
1294
+ version = "2.3.2"
1295
1295
  source = { editable = "." }
1296
1296
  dependencies = [
1297
1297
  { name = "beautifulsoup4", marker = "(python_full_version < '3.10' and platform_machine == 'arm64' and sys_platform == 'darwin') or (python_full_version >= '3.13' and platform_machine == 'arm64' and sys_platform == 'darwin') or (python_full_version < '3.10' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version >= '3.13' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.10' and platform_machine == 'aarch64' and sys_platform == 'linux') or (python_full_version >= '3.13' and platform_machine == 'aarch64' and sys_platform == 'linux') or (python_full_version < '3.10' and platform_machine == 'x86_64' and sys_platform == 'linux') or (python_full_version >= '3.13' and platform_machine == 'x86_64' and sys_platform == 'linux')" },
@@ -1,31 +0,0 @@
1
- # [2.3.0](https://github.com/phantomcyber/splunk-soar-sdk/compare/2.2.0...2.3.0) (2025-10-02)
2
-
3
-
4
- ### Bug Fixes
5
-
6
- * get rid of column_order and maintain counter instead ([c9b011d](https://github.com/phantomcyber/splunk-soar-sdk/commit/c9b011d84688f22b5ac2aa7f32a29468762ebe0d))
7
-
8
-
9
- ### Features
10
-
11
- * adding column name and column order to params as well ([69a752e](https://github.com/phantomcyber/splunk-soar-sdk/commit/69a752e19d9c730ef319277480aa0a24fca03c2e))
12
-
13
-
14
-
15
-
16
-
17
- # [2.3.0](https://github.com/phantomcyber/splunk-soar-sdk/compare/2.2.0...2.3.0) (2025-10-02)
18
-
19
-
20
- ### Bug Fixes
21
-
22
- * get rid of column_order and maintain counter instead ([c9b011d](https://github.com/phantomcyber/splunk-soar-sdk/commit/c9b011d84688f22b5ac2aa7f32a29468762ebe0d))
23
-
24
-
25
- ### Features
26
-
27
- * adding column name and column order to params as well ([69a752e](https://github.com/phantomcyber/splunk-soar-sdk/commit/69a752e19d9c730ef319277480aa0a24fca03c2e))
28
-
29
-
30
-
31
-
@@ -1 +0,0 @@
1
- 2.3.0
@@ -1,21 +0,0 @@
1
- import pytest
2
- from pydantic import ValidationError
3
-
4
- from soar_sdk.params import Param, Params
5
-
6
- from tests.stubs import SampleActionParams
7
-
8
-
9
- def test_models_have_params_validated():
10
- with pytest.raises(ValidationError):
11
- SampleActionParams(field1="five")
12
-
13
-
14
- def test_sensitive_param_must_be_str():
15
- class BrokenParams(Params):
16
- secret: bool = Param(sensitive=True)
17
-
18
- with pytest.raises(TypeError) as e:
19
- BrokenParams._to_json_schema()
20
-
21
- assert e.match("Sensitive parameter secret must be type str, not bool")