splunk-soar-sdk 2.3.0__py3-none-any.whl → 2.3.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
soar_sdk/abstract.py CHANGED
@@ -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
soar_sdk/app.py CHANGED
@@ -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,
soar_sdk/app_client.py CHANGED
@@ -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
@@ -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:
soar_sdk/params.py CHANGED
@@ -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
  )
@@ -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.1
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,10 +1,10 @@
1
1
  soar_sdk/__init__.py,sha256=RzAng-ARqpK01SY82lNy4uYJFVG0yW6Q3CccEqbToJ4,726
2
- soar_sdk/abstract.py,sha256=jGXs2Fv5TRpnh5Duz3mWjY8_DAOpY4RSSzvw_z4XN4I,7950
2
+ soar_sdk/abstract.py,sha256=AU5ssJWytMp_RmYOxt_sKBqaFN63UfdMmzmAn0HQE_g,7940
3
3
  soar_sdk/action_results.py,sha256=NQTcQ3NJcYB6h-YNRqO0bCG_hILmTidv2D4FdvCzyDE,11092
4
4
  soar_sdk/actions_manager.py,sha256=wJCyfzkI_6OKZ-Kmll4vRJpGvYdL93Uw-JyEEGnKcw0,5779
5
- soar_sdk/app.py,sha256=lYvaDUYEV6b_uF4CyPh6wlAIbCNISya7bJ8Z2xJyyGY,33356
5
+ soar_sdk/app.py,sha256=EtvIJtL5_WFMmTKn3V0mJex5ZsBxzAf7EzqERU2t0Vg,33184
6
6
  soar_sdk/app_cli_runner.py,sha256=fJoozhyAt7QUMuc02nE5RL_InpsjQBpr6U4rF9sey3E,11627
7
- soar_sdk/app_client.py,sha256=0r3jIvMM8szCEHXOgRu07VaovKH96pZut5rn2GfYcsc,6275
7
+ soar_sdk/app_client.py,sha256=GZmpenBl25-UQVVpELxWRJanmXBWNIQBRphcSAbnZlU,6253
8
8
  soar_sdk/asset.py,sha256=deS8_B5hr7W2fED8_6wUpVriRgiQ5r8TkGVHiasIaro,10666
9
9
  soar_sdk/async_utils.py,sha256=gND8ZiVTqDYLQ88Ua6SN1mInJaEcfa168eOaRoURt3E,1441
10
10
  soar_sdk/colors.py,sha256=--i_iXqfyITUz4O95HMjfZQGbwFZ34bLmBhtfpXXqlQ,1095
@@ -13,7 +13,7 @@ soar_sdk/crypto.py,sha256=qiBMHUQqgn5lPI1DbujSj700s89FuLJrkQgCO9_eBn4,392
13
13
  soar_sdk/exceptions.py,sha256=CxJ_Q6N1jlknO_3ItDQNhHEw2pNWZr3sMLqutYmr5HA,1863
14
14
  soar_sdk/input_spec.py,sha256=BAa36l8IKDvM8SVMjgZ1XcnWZ2F7O052n2415tLeKK8,4690
15
15
  soar_sdk/logging.py,sha256=lSz8PA6hOCw2MHGE0ZSKbw-FzSr1WdbfQ7BHnXBUUY0,11440
16
- soar_sdk/params.py,sha256=Q2tWOzZWNl2Spvnu29iSUfMleW8U7OD-DdCWtkOXRMw,7720
16
+ soar_sdk/params.py,sha256=OomwUt2bkOwzDs9ypmf-ziZmj2D4uIieO85Jo3haWCg,8731
17
17
  soar_sdk/paths.py,sha256=XhpanQCAiTXaulRx440oKu36mnll7P05TethHXgMpgQ,239
18
18
  soar_sdk/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
19
19
  soar_sdk/types.py,sha256=uMFnNOHpmCLrbAhQOgmXjScXiGE67sM8ySN04MhkC3U,602
@@ -50,7 +50,7 @@ soar_sdk/code_renderers/toml_renderer.py,sha256=-zP8UzlYMCVVA5ex9slaNLeFTu4xLjkv
50
50
  soar_sdk/code_renderers/templates/pyproject.toml.jinja,sha256=Ti6A5kWMb902Lbd1kmw8qPgVDPNNzlV6rd0pcVEbVUo,3917
51
51
  soar_sdk/decorators/__init__.py,sha256=ttvapTczeQpReZVYgjTw4qnEqKd7b8pR7lNaCpO0npQ,513
52
52
  soar_sdk/decorators/action.py,sha256=ZuSsowsBeEuenGQw03iyd2uv-Ymp9kQYnhYsx7k7pX8,6695
53
- soar_sdk/decorators/make_request.py,sha256=W_ltGvryTvdKomiJ8gL7rE_KVc1VVodhFYstGxB8d4Q,5527
53
+ soar_sdk/decorators/make_request.py,sha256=Em9GoVMtDF3K8CxzVQmcamC3bLOsnNosd8JCaNh-dKw,5959
54
54
  soar_sdk/decorators/on_poll.py,sha256=xdT0QSa_dnh37XdJNGW-DAZsb9oQO5tjxPbIQmWpaZs,8232
55
55
  soar_sdk/decorators/test_connectivity.py,sha256=8uXMD4NW5bokpsAfBctUrfOR4K_geYLEZUY0Y6uI6aU,3568
56
56
  soar_sdk/decorators/view_handler.py,sha256=jhBzbJcokWOeUWR4_orDRWTXiiVwE9RZdRSvNUYF3S0,7362
@@ -96,8 +96,8 @@ soar_sdk/views/components/pie_chart.py,sha256=LVTeHVJN6nf2vjUs9y7PDBhS0U1fKW750l
96
96
  soar_sdk/webhooks/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
97
97
  soar_sdk/webhooks/models.py,sha256=-rjuFA9cRX5zTLp7cHSHVTkt5eVJD6BdESGbj_qkyHI,4540
98
98
  soar_sdk/webhooks/routing.py,sha256=BKbURSrBPdOTS5UFL-mHzFEr-Fj04mJMx9KeiPrZ2VQ,6872
99
- splunk_soar_sdk-2.3.0.dist-info/METADATA,sha256=WGypNiW3i7PR8Eef-5QYJUwWSR1ua062kpRU86c7g8Y,7361
100
- splunk_soar_sdk-2.3.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
101
- splunk_soar_sdk-2.3.0.dist-info/entry_points.txt,sha256=CgBjo2ZWpYNkt9TgvToL26h2Tg1yt8FbvYTb5NVgNuc,51
102
- splunk_soar_sdk-2.3.0.dist-info/licenses/LICENSE,sha256=gNCGrGhrSQb1PUzBOByVUN1tvaliwLZfna-QU2r2hQ8,11345
103
- splunk_soar_sdk-2.3.0.dist-info/RECORD,,
99
+ splunk_soar_sdk-2.3.1.dist-info/METADATA,sha256=-Ec3iyRoRcJLJqcQPrUAq9_LEC_UjyM6VLPKijRSR6g,7361
100
+ splunk_soar_sdk-2.3.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
101
+ splunk_soar_sdk-2.3.1.dist-info/entry_points.txt,sha256=CgBjo2ZWpYNkt9TgvToL26h2Tg1yt8FbvYTb5NVgNuc,51
102
+ splunk_soar_sdk-2.3.1.dist-info/licenses/LICENSE,sha256=gNCGrGhrSQb1PUzBOByVUN1tvaliwLZfna-QU2r2hQ8,11345
103
+ splunk_soar_sdk-2.3.1.dist-info/RECORD,,