binalyze-air-sdk 1.0.1__py3-none-any.whl → 1.0.3__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.
Files changed (142) hide show
  1. binalyze_air/__init__.py +77 -77
  2. binalyze_air/apis/__init__.py +67 -27
  3. binalyze_air/apis/acquisitions.py +107 -0
  4. binalyze_air/apis/api_tokens.py +49 -0
  5. binalyze_air/apis/assets.py +161 -0
  6. binalyze_air/apis/audit_logs.py +26 -0
  7. binalyze_air/apis/{authentication.py → auth.py} +29 -27
  8. binalyze_air/apis/auto_asset_tags.py +79 -75
  9. binalyze_air/apis/backup.py +177 -0
  10. binalyze_air/apis/baseline.py +46 -0
  11. binalyze_air/apis/cases.py +225 -0
  12. binalyze_air/apis/cloud_forensics.py +116 -0
  13. binalyze_air/apis/event_subscription.py +96 -96
  14. binalyze_air/apis/evidence.py +249 -53
  15. binalyze_air/apis/interact.py +153 -36
  16. binalyze_air/apis/investigation_hub.py +234 -0
  17. binalyze_air/apis/license.py +104 -0
  18. binalyze_air/apis/logger.py +83 -0
  19. binalyze_air/apis/multipart_upload.py +201 -0
  20. binalyze_air/apis/notifications.py +115 -0
  21. binalyze_air/apis/organizations.py +267 -0
  22. binalyze_air/apis/params.py +44 -39
  23. binalyze_air/apis/policies.py +186 -0
  24. binalyze_air/apis/preset_filters.py +79 -0
  25. binalyze_air/apis/recent_activities.py +71 -0
  26. binalyze_air/apis/relay_server.py +104 -0
  27. binalyze_air/apis/settings.py +395 -27
  28. binalyze_air/apis/tasks.py +80 -0
  29. binalyze_air/apis/triage.py +197 -0
  30. binalyze_air/apis/user_management.py +183 -74
  31. binalyze_air/apis/webhook_executions.py +50 -0
  32. binalyze_air/apis/webhooks.py +322 -230
  33. binalyze_air/base.py +207 -133
  34. binalyze_air/client.py +217 -1337
  35. binalyze_air/commands/__init__.py +175 -145
  36. binalyze_air/commands/acquisitions.py +661 -387
  37. binalyze_air/commands/api_tokens.py +55 -0
  38. binalyze_air/commands/assets.py +324 -362
  39. binalyze_air/commands/{authentication.py → auth.py} +36 -36
  40. binalyze_air/commands/auto_asset_tags.py +230 -230
  41. binalyze_air/commands/backup.py +47 -0
  42. binalyze_air/commands/baseline.py +32 -396
  43. binalyze_air/commands/cases.py +609 -602
  44. binalyze_air/commands/cloud_forensics.py +88 -0
  45. binalyze_air/commands/event_subscription.py +101 -101
  46. binalyze_air/commands/evidences.py +918 -988
  47. binalyze_air/commands/interact.py +172 -58
  48. binalyze_air/commands/investigation_hub.py +315 -0
  49. binalyze_air/commands/license.py +183 -0
  50. binalyze_air/commands/logger.py +126 -0
  51. binalyze_air/commands/multipart_upload.py +363 -0
  52. binalyze_air/commands/notifications.py +45 -0
  53. binalyze_air/commands/organizations.py +200 -221
  54. binalyze_air/commands/policies.py +175 -203
  55. binalyze_air/commands/preset_filters.py +55 -0
  56. binalyze_air/commands/recent_activities.py +32 -0
  57. binalyze_air/commands/relay_server.py +144 -0
  58. binalyze_air/commands/settings.py +431 -29
  59. binalyze_air/commands/tasks.py +95 -56
  60. binalyze_air/commands/triage.py +224 -360
  61. binalyze_air/commands/user_management.py +351 -126
  62. binalyze_air/commands/webhook_executions.py +77 -0
  63. binalyze_air/config.py +244 -244
  64. binalyze_air/exceptions.py +49 -49
  65. binalyze_air/http_client.py +426 -305
  66. binalyze_air/models/__init__.py +287 -285
  67. binalyze_air/models/acquisitions.py +365 -250
  68. binalyze_air/models/api_tokens.py +73 -0
  69. binalyze_air/models/assets.py +438 -438
  70. binalyze_air/models/audit.py +247 -272
  71. binalyze_air/models/audit_logs.py +14 -0
  72. binalyze_air/models/{authentication.py → auth.py} +69 -69
  73. binalyze_air/models/auto_asset_tags.py +227 -116
  74. binalyze_air/models/backup.py +138 -0
  75. binalyze_air/models/baseline.py +231 -231
  76. binalyze_air/models/cases.py +275 -275
  77. binalyze_air/models/cloud_forensics.py +145 -0
  78. binalyze_air/models/event_subscription.py +170 -171
  79. binalyze_air/models/evidence.py +65 -65
  80. binalyze_air/models/evidences.py +367 -348
  81. binalyze_air/models/interact.py +266 -135
  82. binalyze_air/models/investigation_hub.py +265 -0
  83. binalyze_air/models/license.py +150 -0
  84. binalyze_air/models/logger.py +83 -0
  85. binalyze_air/models/multipart_upload.py +352 -0
  86. binalyze_air/models/notifications.py +138 -0
  87. binalyze_air/models/organizations.py +293 -293
  88. binalyze_air/models/params.py +153 -127
  89. binalyze_air/models/policies.py +260 -249
  90. binalyze_air/models/preset_filters.py +79 -0
  91. binalyze_air/models/recent_activities.py +70 -0
  92. binalyze_air/models/relay_server.py +121 -0
  93. binalyze_air/models/settings.py +538 -84
  94. binalyze_air/models/tasks.py +215 -149
  95. binalyze_air/models/triage.py +141 -142
  96. binalyze_air/models/user_management.py +200 -97
  97. binalyze_air/models/webhook_executions.py +33 -0
  98. binalyze_air/queries/__init__.py +121 -133
  99. binalyze_air/queries/acquisitions.py +155 -155
  100. binalyze_air/queries/api_tokens.py +46 -0
  101. binalyze_air/queries/assets.py +186 -105
  102. binalyze_air/queries/audit.py +400 -416
  103. binalyze_air/queries/{authentication.py → auth.py} +55 -55
  104. binalyze_air/queries/auto_asset_tags.py +59 -59
  105. binalyze_air/queries/backup.py +66 -0
  106. binalyze_air/queries/baseline.py +21 -185
  107. binalyze_air/queries/cases.py +292 -292
  108. binalyze_air/queries/cloud_forensics.py +137 -0
  109. binalyze_air/queries/event_subscription.py +54 -54
  110. binalyze_air/queries/evidence.py +139 -139
  111. binalyze_air/queries/evidences.py +279 -279
  112. binalyze_air/queries/interact.py +140 -28
  113. binalyze_air/queries/investigation_hub.py +329 -0
  114. binalyze_air/queries/license.py +85 -0
  115. binalyze_air/queries/logger.py +58 -0
  116. binalyze_air/queries/multipart_upload.py +180 -0
  117. binalyze_air/queries/notifications.py +71 -0
  118. binalyze_air/queries/organizations.py +222 -222
  119. binalyze_air/queries/params.py +154 -115
  120. binalyze_air/queries/policies.py +149 -149
  121. binalyze_air/queries/preset_filters.py +60 -0
  122. binalyze_air/queries/recent_activities.py +44 -0
  123. binalyze_air/queries/relay_server.py +42 -0
  124. binalyze_air/queries/settings.py +533 -20
  125. binalyze_air/queries/tasks.py +125 -81
  126. binalyze_air/queries/triage.py +230 -230
  127. binalyze_air/queries/user_management.py +193 -83
  128. binalyze_air/queries/webhook_executions.py +39 -0
  129. binalyze_air_sdk-1.0.3.dist-info/METADATA +752 -0
  130. binalyze_air_sdk-1.0.3.dist-info/RECORD +132 -0
  131. {binalyze_air_sdk-1.0.1.dist-info → binalyze_air_sdk-1.0.3.dist-info}/WHEEL +1 -1
  132. binalyze_air/apis/endpoints.py +0 -22
  133. binalyze_air/apis/evidences.py +0 -216
  134. binalyze_air/apis/users.py +0 -68
  135. binalyze_air/commands/users.py +0 -101
  136. binalyze_air/models/endpoints.py +0 -76
  137. binalyze_air/models/users.py +0 -82
  138. binalyze_air/queries/endpoints.py +0 -25
  139. binalyze_air/queries/users.py +0 -69
  140. binalyze_air_sdk-1.0.1.dist-info/METADATA +0 -635
  141. binalyze_air_sdk-1.0.1.dist-info/RECORD +0 -82
  142. {binalyze_air_sdk-1.0.1.dist-info → binalyze_air_sdk-1.0.3.dist-info}/top_level.txt +0 -0
@@ -1,231 +1,323 @@
1
- """
2
- Webhook API for the Binalyze AIR SDK.
3
- Provides webhook trigger functionality for programmatically calling webhook endpoints.
4
- """
5
-
6
- from typing import Dict, Any, Optional, List, Union
7
- import json
8
-
9
- from ..http_client import HTTPClient
10
-
11
-
12
- class WebhookAPI:
13
- """Webhook API for triggering webhook endpoints programmatically."""
14
-
15
- def __init__(self, http_client: HTTPClient):
16
- self.http_client = http_client
17
-
18
- def trigger_get(
19
- self,
20
- slug: str,
21
- data: str,
22
- token: str,
23
- use_webhook_endpoint: bool = True
24
- ) -> Dict[str, Any]:
25
- """
26
- Trigger a webhook via GET request.
27
-
28
- Args:
29
- slug: Webhook slug/name
30
- data: Comma-separated hostnames or IP addresses
31
- token: Webhook token
32
- use_webhook_endpoint: If True, use webhook endpoint directly (no auth needed)
33
- If False, use authenticated API endpoint
34
-
35
- Returns:
36
- Dict containing task details and URLs
37
- """
38
- if use_webhook_endpoint:
39
- # Direct webhook call - no authentication needed, just token
40
- endpoint = f"webhook/{slug}/{data}"
41
- params = {"token": token}
42
-
43
- # Use raw HTTP client for webhook endpoints (they don't use standard API auth)
44
- import requests
45
- base_url = self.http_client.config.host
46
- url = f"{base_url}/api/{endpoint}"
47
-
48
- response = requests.get(
49
- url,
50
- params=params,
51
- verify=self.http_client.config.verify_ssl,
52
- timeout=30
53
- )
54
-
55
- if response.status_code == 200:
56
- return response.json()
57
- elif response.status_code == 403:
58
- return {
59
- "success": False,
60
- "error": "Forbidden",
61
- "message": "Invalid webhook token",
62
- "statusCode": 403
63
- }
64
- elif response.status_code == 404:
65
- return {
66
- "success": False,
67
- "error": "Not Found",
68
- "message": "Webhook not found",
69
- "statusCode": 404
70
- }
71
- else:
72
- return {
73
- "success": False,
74
- "error": f"HTTP {response.status_code}",
75
- "message": response.text,
76
- "statusCode": response.status_code
77
- }
78
- else:
79
- # Use authenticated API endpoint (if available)
80
- endpoint = f"webhook/{slug}/{data}"
81
- params = {"token": token}
82
- return self.http_client.get(endpoint, params=params)
83
-
84
- def trigger_post(
85
- self,
86
- slug: str,
87
- token: str,
88
- payload: Optional[Dict[str, Any]] = None,
89
- use_webhook_endpoint: bool = True
90
- ) -> Dict[str, Any]:
91
- """
92
- Trigger a webhook via POST request.
93
-
94
- Args:
95
- slug: Webhook slug/name
96
- token: Webhook token
97
- payload: Optional POST data/payload
98
- use_webhook_endpoint: If True, use webhook endpoint directly (no auth needed)
99
- If False, use authenticated API endpoint
100
-
101
- Returns:
102
- Dict containing task details and URLs
103
- """
104
- if payload is None:
105
- payload = {}
106
-
107
- if use_webhook_endpoint:
108
- # Direct webhook call - no authentication needed, just token
109
- endpoint = f"webhook/{slug}"
110
- params = {"token": token}
111
-
112
- # Use raw HTTP client for webhook endpoints
113
- import requests
114
- base_url = self.http_client.config.host
115
- url = f"{base_url}/api/{endpoint}"
116
-
117
- response = requests.post(
118
- url,
119
- params=params,
120
- json=payload,
121
- verify=self.http_client.config.verify_ssl,
122
- timeout=30
123
- )
124
-
125
- if response.status_code == 200:
126
- return response.json()
127
- elif response.status_code == 403:
128
- return {
129
- "success": False,
130
- "error": "Forbidden",
131
- "message": "Invalid webhook token",
132
- "statusCode": 403
133
- }
134
- elif response.status_code == 404:
135
- return {
136
- "success": False,
137
- "error": "Not Found",
138
- "message": "Webhook not found",
139
- "statusCode": 404
140
- }
141
- else:
142
- return {
143
- "success": False,
144
- "error": f"HTTP {response.status_code}",
145
- "message": response.text,
146
- "statusCode": response.status_code
147
- }
148
- else:
149
- # Use authenticated API endpoint (if available)
150
- endpoint = f"webhook/{slug}"
151
- params = {"token": token}
152
- return self.http_client.post(endpoint, json_data=payload, params=params)
153
-
154
- def get_task_details(
155
- self,
156
- slug: str,
157
- token: str,
158
- task_id: str,
159
- use_webhook_endpoint: bool = True
160
- ) -> Union[List[Dict[str, Any]], Dict[str, Any]]:
161
- """
162
- Get task assignment details from a webhook.
163
-
164
- Args:
165
- slug: Webhook slug/name
166
- token: Webhook token
167
- task_id: Task ID returned from webhook trigger
168
- use_webhook_endpoint: If True, use webhook endpoint directly (no auth needed)
169
- If False, use authenticated API endpoint
170
-
171
- Returns:
172
- List of task assignment details or Dict with error info
173
- """
174
- if use_webhook_endpoint:
175
- # Direct webhook call - no authentication needed, just token
176
- endpoint = f"webhook/{slug}/assignments"
177
- params = {"token": token, "taskId": task_id}
178
-
179
- # Use raw HTTP client for webhook endpoints
180
- import requests
181
- base_url = self.http_client.config.host
182
- url = f"{base_url}/api/{endpoint}"
183
-
184
- response = requests.get(
185
- url,
186
- params=params,
187
- verify=self.http_client.config.verify_ssl,
188
- timeout=30
189
- )
190
-
191
- if response.status_code == 200:
192
- return response.json()
193
- elif response.status_code == 403:
194
- return {
195
- "success": False,
196
- "error": "Forbidden",
197
- "message": "Invalid webhook token",
198
- "statusCode": 403
199
- }
200
- elif response.status_code == 404:
201
- return {
202
- "success": False,
203
- "error": "Not Found",
204
- "message": "Task not found",
205
- "statusCode": 404
206
- }
207
- else:
208
- return {
209
- "success": False,
210
- "error": f"HTTP {response.status_code}",
211
- "message": response.text,
212
- "statusCode": response.status_code
213
- }
214
- else:
215
- # Use authenticated API endpoint (if available)
216
- endpoint = f"webhook/{slug}/assignments"
217
- params = {"token": token, "taskId": task_id}
218
- return self.http_client.get(endpoint, params=params)
219
-
220
- # Convenience methods with better names
221
- def call_webhook_get(self, slug: str, data: str, token: str) -> Dict[str, Any]:
222
- """Convenience method to call a webhook via GET."""
223
- return self.trigger_get(slug, data, token)
224
-
225
- def call_webhook_post(self, slug: str, token: str, payload: Optional[Dict[str, Any]] = None) -> Dict[str, Any]:
226
- """Convenience method to call a webhook via POST."""
227
- return self.trigger_post(slug, token, payload)
228
-
229
- def get_webhook_task_data(self, slug: str, token: str, task_id: str) -> Union[List[Dict[str, Any]], Dict[str, Any]]:
230
- """Convenience method to get webhook task assignment data."""
1
+ """
2
+ Webhook API for the Binalyze AIR SDK.
3
+ Provides webhook trigger functionality for programmatically calling webhook endpoints,
4
+ plus complete webhook management (CRUD operations).
5
+ """
6
+
7
+ from typing import Dict, Any, Optional, List, Union
8
+ import json
9
+
10
+ from ..http_client import HTTPClient
11
+
12
+
13
+ class WebhookAPI:
14
+ """Webhook API for triggering webhook endpoints programmatically and managing webhooks."""
15
+
16
+ def __init__(self, http_client: HTTPClient):
17
+ self.http_client = http_client
18
+
19
+ # WEBHOOK MANAGEMENT METHODS (CRUD Operations)
20
+ def get_param_parsers(self) -> List[Dict[str, Any]]:
21
+ """Get available webhook parameter parsers."""
22
+ try:
23
+ response = self.http_client.get("webhooks/param-parsers")
24
+ if isinstance(response, dict) and response.get("result"):
25
+ return response["result"]
26
+ return []
27
+ except Exception as e:
28
+ return []
29
+
30
+ def get_webhooks(self, organization_ids: Optional[List[int]] = None, **filter_params) -> Dict[str, Any]:
31
+ """Get webhooks with optional filtering."""
32
+ try:
33
+ # Build query parameters
34
+ params = {}
35
+
36
+ # Add organization filter
37
+ if organization_ids:
38
+ params["filter[organizationIds]"] = ",".join([str(x) for x in organization_ids])
39
+ else:
40
+ params["filter[organizationIds]"] = "0" # Default to organization 0
41
+
42
+ # Add other filters
43
+ for key, value in filter_params.items():
44
+ if value is not None:
45
+ params[f"filter[{key}]"] = str(value)
46
+
47
+ response = self.http_client.get("webhooks", params=params)
48
+ return response
49
+ except Exception as e:
50
+ return {
51
+ "success": False,
52
+ "result": {"entities": [], "totalEntityCount": 0},
53
+ "statusCode": 500,
54
+ "errors": [str(e)]
55
+ }
56
+
57
+ def get_webhook_by_id(self, webhook_id: str) -> Dict[str, Any]:
58
+ """Get a specific webhook by ID."""
59
+ try:
60
+ response = self.http_client.get(f"webhooks/{webhook_id}")
61
+ return response
62
+ except Exception as e:
63
+ return {
64
+ "success": False,
65
+ "result": None,
66
+ "statusCode": 500,
67
+ "errors": [str(e)]
68
+ }
69
+
70
+ def create_webhook(self, webhook_data: Dict[str, Any]) -> Dict[str, Any]:
71
+ """Create a new webhook."""
72
+ try:
73
+ response = self.http_client.post("webhooks", json_data=webhook_data)
74
+ return response
75
+ except Exception as e:
76
+ return {
77
+ "success": False,
78
+ "result": None,
79
+ "statusCode": 500,
80
+ "errors": [str(e)]
81
+ }
82
+
83
+ def update_webhook_by_id(self, webhook_id: str, webhook_data: Dict[str, Any]) -> Dict[str, Any]:
84
+ """Update an existing webhook by ID."""
85
+ try:
86
+ response = self.http_client.put(f"webhooks/{webhook_id}", json_data=webhook_data)
87
+ return response
88
+ except Exception as e:
89
+ return {
90
+ "success": False,
91
+ "result": None,
92
+ "statusCode": 500,
93
+ "errors": [str(e)]
94
+ }
95
+
96
+ def delete_webhook_by_id(self, webhook_id: str) -> Dict[str, Any]:
97
+ """Delete a webhook by ID."""
98
+ try:
99
+ response = self.http_client.delete(f"webhooks/{webhook_id}")
100
+ return response
101
+ except Exception as e:
102
+ return {
103
+ "success": False,
104
+ "result": None,
105
+ "statusCode": 500,
106
+ "errors": [str(e)]
107
+ }
108
+
109
+ # WEBHOOK TRIGGERING METHODS (Legacy functionality preserved)
110
+ def trigger_get(
111
+ self,
112
+ slug: str,
113
+ data: str,
114
+ token: str,
115
+ use_webhook_endpoint: bool = True
116
+ ) -> Dict[str, Any]:
117
+ """
118
+ Trigger a webhook via GET request.
119
+
120
+ Args:
121
+ slug: Webhook slug/name
122
+ data: Comma-separated hostnames or IP addresses
123
+ token: Webhook token
124
+ use_webhook_endpoint: If True, use webhook endpoint directly (no auth needed)
125
+ If False, use authenticated API endpoint
126
+
127
+ Returns:
128
+ Dict containing task details and URLs
129
+ """
130
+ if use_webhook_endpoint:
131
+ # Direct webhook call - no authentication needed, just token
132
+ endpoint = f"webhook/{slug}/{data}"
133
+ params = {"token": token}
134
+
135
+ # Use raw HTTP client for webhook endpoints (they don't use standard API auth)
136
+ import requests
137
+ base_url = self.http_client.config.host
138
+ url = f"{base_url}/api/{endpoint}"
139
+
140
+ response = requests.get(
141
+ url,
142
+ params=params,
143
+ verify=self.http_client.config.verify_ssl,
144
+ timeout=30
145
+ )
146
+
147
+ if response.status_code == 200:
148
+ return response.json()
149
+ elif response.status_code == 403:
150
+ return {
151
+ "success": False,
152
+ "error": "Forbidden",
153
+ "message": "Invalid webhook token",
154
+ "statusCode": 403
155
+ }
156
+ elif response.status_code == 404:
157
+ return {
158
+ "success": False,
159
+ "error": "Not Found",
160
+ "message": "Webhook not found",
161
+ "statusCode": 404
162
+ }
163
+ else:
164
+ return {
165
+ "success": False,
166
+ "error": f"HTTP {response.status_code}",
167
+ "message": response.text,
168
+ "statusCode": response.status_code
169
+ }
170
+ else:
171
+ # Use authenticated API endpoint (if available)
172
+ endpoint = f"webhook/{slug}/{data}"
173
+ params = {"token": token}
174
+ return self.http_client.get(endpoint, params=params)
175
+
176
+ def trigger_post(
177
+ self,
178
+ slug: str,
179
+ token: str,
180
+ payload: Optional[Dict[str, Any]] = None,
181
+ use_webhook_endpoint: bool = True
182
+ ) -> Dict[str, Any]:
183
+ """
184
+ Trigger a webhook via POST request.
185
+
186
+ Args:
187
+ slug: Webhook slug/name
188
+ token: Webhook token
189
+ payload: Optional POST data/payload
190
+ use_webhook_endpoint: If True, use webhook endpoint directly (no auth needed)
191
+ If False, use authenticated API endpoint
192
+
193
+ Returns:
194
+ Dict containing task details and URLs
195
+ """
196
+ if payload is None:
197
+ payload = {}
198
+
199
+ if use_webhook_endpoint:
200
+ # Direct webhook call - no authentication needed, just token
201
+ endpoint = f"webhook/{slug}"
202
+ params = {"token": token}
203
+
204
+ # Use raw HTTP client for webhook endpoints
205
+ import requests
206
+ base_url = self.http_client.config.host
207
+ url = f"{base_url}/api/{endpoint}"
208
+
209
+ response = requests.post(
210
+ url,
211
+ params=params,
212
+ json=payload,
213
+ verify=self.http_client.config.verify_ssl,
214
+ timeout=30
215
+ )
216
+
217
+ if response.status_code == 200:
218
+ return response.json()
219
+ elif response.status_code == 403:
220
+ return {
221
+ "success": False,
222
+ "error": "Forbidden",
223
+ "message": "Invalid webhook token",
224
+ "statusCode": 403
225
+ }
226
+ elif response.status_code == 404:
227
+ return {
228
+ "success": False,
229
+ "error": "Not Found",
230
+ "message": "Webhook not found",
231
+ "statusCode": 404
232
+ }
233
+ else:
234
+ return {
235
+ "success": False,
236
+ "error": f"HTTP {response.status_code}",
237
+ "message": response.text,
238
+ "statusCode": response.status_code
239
+ }
240
+ else:
241
+ # Use authenticated API endpoint (if available)
242
+ endpoint = f"webhook/{slug}"
243
+ params = {"token": token}
244
+ return self.http_client.post(endpoint, json_data=payload, params=params)
245
+
246
+ def get_task_details(
247
+ self,
248
+ slug: str,
249
+ token: str,
250
+ task_id: str,
251
+ use_webhook_endpoint: bool = True
252
+ ) -> Union[List[Dict[str, Any]], Dict[str, Any]]:
253
+ """
254
+ Get task assignment details from a webhook.
255
+
256
+ Args:
257
+ slug: Webhook slug/name
258
+ token: Webhook token
259
+ task_id: Task ID returned from webhook trigger
260
+ use_webhook_endpoint: If True, use webhook endpoint directly (no auth needed)
261
+ If False, use authenticated API endpoint
262
+
263
+ Returns:
264
+ List of task assignment details or Dict with error info
265
+ """
266
+ if use_webhook_endpoint:
267
+ # Direct webhook call - no authentication needed, just token
268
+ endpoint = f"webhook/{slug}/assignments"
269
+ params = {"token": token, "taskId": task_id}
270
+
271
+ # Use raw HTTP client for webhook endpoints
272
+ import requests
273
+ base_url = self.http_client.config.host
274
+ url = f"{base_url}/api/{endpoint}"
275
+
276
+ response = requests.get(
277
+ url,
278
+ params=params,
279
+ verify=self.http_client.config.verify_ssl,
280
+ timeout=30
281
+ )
282
+
283
+ if response.status_code == 200:
284
+ return response.json()
285
+ elif response.status_code == 403:
286
+ return {
287
+ "success": False,
288
+ "error": "Forbidden",
289
+ "message": "Invalid webhook token",
290
+ "statusCode": 403
291
+ }
292
+ elif response.status_code == 404:
293
+ return {
294
+ "success": False,
295
+ "error": "Not Found",
296
+ "message": "Task not found or invalid task ID",
297
+ "statusCode": 404
298
+ }
299
+ else:
300
+ return {
301
+ "success": False,
302
+ "error": f"HTTP {response.status_code}",
303
+ "message": response.text,
304
+ "statusCode": response.status_code
305
+ }
306
+ else:
307
+ # Use authenticated API endpoint (if available)
308
+ endpoint = f"webhook/{slug}/assignments"
309
+ params = {"token": token, "taskId": task_id}
310
+ return self.http_client.get(endpoint, params=params)
311
+
312
+ # CONVENIENCE METHODS (Aliases for backward compatibility)
313
+ def call_webhook_get(self, slug: str, data: str, token: str) -> Dict[str, Any]:
314
+ """Alias for trigger_get - backward compatibility."""
315
+ return self.trigger_get(slug, data, token)
316
+
317
+ def call_webhook_post(self, slug: str, token: str, payload: Optional[Dict[str, Any]] = None) -> Dict[str, Any]:
318
+ """Alias for trigger_post - backward compatibility."""
319
+ return self.trigger_post(slug, token, payload)
320
+
321
+ def get_webhook_task_data(self, slug: str, token: str, task_id: str) -> Union[List[Dict[str, Any]], Dict[str, Any]]:
322
+ """Alias for get_task_details - backward compatibility."""
231
323
  return self.get_task_details(slug, token, task_id)