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.
- binalyze_air/__init__.py +77 -77
- binalyze_air/apis/__init__.py +67 -27
- binalyze_air/apis/acquisitions.py +107 -0
- binalyze_air/apis/api_tokens.py +49 -0
- binalyze_air/apis/assets.py +161 -0
- binalyze_air/apis/audit_logs.py +26 -0
- binalyze_air/apis/{authentication.py → auth.py} +29 -27
- binalyze_air/apis/auto_asset_tags.py +79 -75
- binalyze_air/apis/backup.py +177 -0
- binalyze_air/apis/baseline.py +46 -0
- binalyze_air/apis/cases.py +225 -0
- binalyze_air/apis/cloud_forensics.py +116 -0
- binalyze_air/apis/event_subscription.py +96 -96
- binalyze_air/apis/evidence.py +249 -53
- binalyze_air/apis/interact.py +153 -36
- binalyze_air/apis/investigation_hub.py +234 -0
- binalyze_air/apis/license.py +104 -0
- binalyze_air/apis/logger.py +83 -0
- binalyze_air/apis/multipart_upload.py +201 -0
- binalyze_air/apis/notifications.py +115 -0
- binalyze_air/apis/organizations.py +267 -0
- binalyze_air/apis/params.py +44 -39
- binalyze_air/apis/policies.py +186 -0
- binalyze_air/apis/preset_filters.py +79 -0
- binalyze_air/apis/recent_activities.py +71 -0
- binalyze_air/apis/relay_server.py +104 -0
- binalyze_air/apis/settings.py +395 -27
- binalyze_air/apis/tasks.py +80 -0
- binalyze_air/apis/triage.py +197 -0
- binalyze_air/apis/user_management.py +183 -74
- binalyze_air/apis/webhook_executions.py +50 -0
- binalyze_air/apis/webhooks.py +322 -230
- binalyze_air/base.py +207 -133
- binalyze_air/client.py +217 -1337
- binalyze_air/commands/__init__.py +175 -145
- binalyze_air/commands/acquisitions.py +661 -387
- binalyze_air/commands/api_tokens.py +55 -0
- binalyze_air/commands/assets.py +324 -362
- binalyze_air/commands/{authentication.py → auth.py} +36 -36
- binalyze_air/commands/auto_asset_tags.py +230 -230
- binalyze_air/commands/backup.py +47 -0
- binalyze_air/commands/baseline.py +32 -396
- binalyze_air/commands/cases.py +609 -602
- binalyze_air/commands/cloud_forensics.py +88 -0
- binalyze_air/commands/event_subscription.py +101 -101
- binalyze_air/commands/evidences.py +918 -988
- binalyze_air/commands/interact.py +172 -58
- binalyze_air/commands/investigation_hub.py +315 -0
- binalyze_air/commands/license.py +183 -0
- binalyze_air/commands/logger.py +126 -0
- binalyze_air/commands/multipart_upload.py +363 -0
- binalyze_air/commands/notifications.py +45 -0
- binalyze_air/commands/organizations.py +200 -221
- binalyze_air/commands/policies.py +175 -203
- binalyze_air/commands/preset_filters.py +55 -0
- binalyze_air/commands/recent_activities.py +32 -0
- binalyze_air/commands/relay_server.py +144 -0
- binalyze_air/commands/settings.py +431 -29
- binalyze_air/commands/tasks.py +95 -56
- binalyze_air/commands/triage.py +224 -360
- binalyze_air/commands/user_management.py +351 -126
- binalyze_air/commands/webhook_executions.py +77 -0
- binalyze_air/config.py +244 -244
- binalyze_air/exceptions.py +49 -49
- binalyze_air/http_client.py +426 -305
- binalyze_air/models/__init__.py +287 -285
- binalyze_air/models/acquisitions.py +365 -250
- binalyze_air/models/api_tokens.py +73 -0
- binalyze_air/models/assets.py +438 -438
- binalyze_air/models/audit.py +247 -272
- binalyze_air/models/audit_logs.py +14 -0
- binalyze_air/models/{authentication.py → auth.py} +69 -69
- binalyze_air/models/auto_asset_tags.py +227 -116
- binalyze_air/models/backup.py +138 -0
- binalyze_air/models/baseline.py +231 -231
- binalyze_air/models/cases.py +275 -275
- binalyze_air/models/cloud_forensics.py +145 -0
- binalyze_air/models/event_subscription.py +170 -171
- binalyze_air/models/evidence.py +65 -65
- binalyze_air/models/evidences.py +367 -348
- binalyze_air/models/interact.py +266 -135
- binalyze_air/models/investigation_hub.py +265 -0
- binalyze_air/models/license.py +150 -0
- binalyze_air/models/logger.py +83 -0
- binalyze_air/models/multipart_upload.py +352 -0
- binalyze_air/models/notifications.py +138 -0
- binalyze_air/models/organizations.py +293 -293
- binalyze_air/models/params.py +153 -127
- binalyze_air/models/policies.py +260 -249
- binalyze_air/models/preset_filters.py +79 -0
- binalyze_air/models/recent_activities.py +70 -0
- binalyze_air/models/relay_server.py +121 -0
- binalyze_air/models/settings.py +538 -84
- binalyze_air/models/tasks.py +215 -149
- binalyze_air/models/triage.py +141 -142
- binalyze_air/models/user_management.py +200 -97
- binalyze_air/models/webhook_executions.py +33 -0
- binalyze_air/queries/__init__.py +121 -133
- binalyze_air/queries/acquisitions.py +155 -155
- binalyze_air/queries/api_tokens.py +46 -0
- binalyze_air/queries/assets.py +186 -105
- binalyze_air/queries/audit.py +400 -416
- binalyze_air/queries/{authentication.py → auth.py} +55 -55
- binalyze_air/queries/auto_asset_tags.py +59 -59
- binalyze_air/queries/backup.py +66 -0
- binalyze_air/queries/baseline.py +21 -185
- binalyze_air/queries/cases.py +292 -292
- binalyze_air/queries/cloud_forensics.py +137 -0
- binalyze_air/queries/event_subscription.py +54 -54
- binalyze_air/queries/evidence.py +139 -139
- binalyze_air/queries/evidences.py +279 -279
- binalyze_air/queries/interact.py +140 -28
- binalyze_air/queries/investigation_hub.py +329 -0
- binalyze_air/queries/license.py +85 -0
- binalyze_air/queries/logger.py +58 -0
- binalyze_air/queries/multipart_upload.py +180 -0
- binalyze_air/queries/notifications.py +71 -0
- binalyze_air/queries/organizations.py +222 -222
- binalyze_air/queries/params.py +154 -115
- binalyze_air/queries/policies.py +149 -149
- binalyze_air/queries/preset_filters.py +60 -0
- binalyze_air/queries/recent_activities.py +44 -0
- binalyze_air/queries/relay_server.py +42 -0
- binalyze_air/queries/settings.py +533 -20
- binalyze_air/queries/tasks.py +125 -81
- binalyze_air/queries/triage.py +230 -230
- binalyze_air/queries/user_management.py +193 -83
- binalyze_air/queries/webhook_executions.py +39 -0
- binalyze_air_sdk-1.0.3.dist-info/METADATA +752 -0
- binalyze_air_sdk-1.0.3.dist-info/RECORD +132 -0
- {binalyze_air_sdk-1.0.1.dist-info → binalyze_air_sdk-1.0.3.dist-info}/WHEEL +1 -1
- binalyze_air/apis/endpoints.py +0 -22
- binalyze_air/apis/evidences.py +0 -216
- binalyze_air/apis/users.py +0 -68
- binalyze_air/commands/users.py +0 -101
- binalyze_air/models/endpoints.py +0 -76
- binalyze_air/models/users.py +0 -82
- binalyze_air/queries/endpoints.py +0 -25
- binalyze_air/queries/users.py +0 -69
- binalyze_air_sdk-1.0.1.dist-info/METADATA +0 -635
- binalyze_air_sdk-1.0.1.dist-info/RECORD +0 -82
- {binalyze_air_sdk-1.0.1.dist-info → binalyze_air_sdk-1.0.3.dist-info}/top_level.txt +0 -0
@@ -1,56 +1,56 @@
|
|
1
|
-
"""
|
2
|
-
|
3
|
-
"""
|
4
|
-
|
5
|
-
from ..base import Query
|
6
|
-
from ..models.
|
7
|
-
from ..http_client import HTTPClient
|
8
|
-
|
9
|
-
|
10
|
-
class CheckAuthStatusQuery(Query[AuthStatus]):
|
11
|
-
"""Query to check authentication status."""
|
12
|
-
|
13
|
-
def __init__(self, http_client: HTTPClient):
|
14
|
-
self.http_client = http_client
|
15
|
-
|
16
|
-
def execute(self) -> AuthStatus:
|
17
|
-
"""Execute the auth status check query."""
|
18
|
-
# Try different endpoint patterns since auth endpoints may vary
|
19
|
-
endpoints_to_try = [
|
20
|
-
"auth/check", # Original pattern
|
21
|
-
# Note: /api/public/auth/check may not exist in all API versions
|
22
|
-
# The HTTP client will add the api_prefix automatically
|
23
|
-
]
|
24
|
-
|
25
|
-
last_exception = None
|
26
|
-
|
27
|
-
for endpoint in endpoints_to_try:
|
28
|
-
try:
|
29
|
-
response = self.http_client.get(endpoint)
|
30
|
-
|
31
|
-
if response.get("success"):
|
32
|
-
result = response.get("result", {})
|
33
|
-
|
34
|
-
# Use Pydantic to parse the User data with proper field aliasing
|
35
|
-
user = User.model_validate(result)
|
36
|
-
return AuthStatus(authenticated=True, user=user)
|
37
|
-
else:
|
38
|
-
# Return unauthenticated status for failed responses
|
39
|
-
return AuthStatus(authenticated=False)
|
40
|
-
|
41
|
-
except Exception as e:
|
42
|
-
last_exception = e
|
43
|
-
continue # Try next endpoint
|
44
|
-
|
45
|
-
# If all endpoints failed, check if it's because auth features are disabled
|
46
|
-
if last_exception and "auth-management-via-api" in str(last_exception):
|
47
|
-
# Auth features are disabled - this is a configuration issue, not authentication failure
|
48
|
-
# We can't determine auth status, so return a special state
|
49
|
-
return AuthStatus(authenticated=False)
|
50
|
-
|
51
|
-
# If we get here, all endpoints failed
|
52
|
-
if last_exception:
|
53
|
-
raise last_exception
|
54
|
-
|
55
|
-
# Return unauthenticated status as fallback
|
1
|
+
"""
|
2
|
+
Auth-related queries for the Binalyze AIR SDK.
|
3
|
+
"""
|
4
|
+
|
5
|
+
from ..base import Query
|
6
|
+
from ..models.auth import AuthStatus, User, UserProfile, UserRole
|
7
|
+
from ..http_client import HTTPClient
|
8
|
+
|
9
|
+
|
10
|
+
class CheckAuthStatusQuery(Query[AuthStatus]):
|
11
|
+
"""Query to check authentication status."""
|
12
|
+
|
13
|
+
def __init__(self, http_client: HTTPClient):
|
14
|
+
self.http_client = http_client
|
15
|
+
|
16
|
+
def execute(self) -> AuthStatus:
|
17
|
+
"""Execute the auth status check query."""
|
18
|
+
# Try different endpoint patterns since auth endpoints may vary
|
19
|
+
endpoints_to_try = [
|
20
|
+
"auth/check", # Original pattern
|
21
|
+
# Note: /api/public/auth/check may not exist in all API versions
|
22
|
+
# The HTTP client will add the api_prefix automatically
|
23
|
+
]
|
24
|
+
|
25
|
+
last_exception = None
|
26
|
+
|
27
|
+
for endpoint in endpoints_to_try:
|
28
|
+
try:
|
29
|
+
response = self.http_client.get(endpoint)
|
30
|
+
|
31
|
+
if response.get("success"):
|
32
|
+
result = response.get("result", {})
|
33
|
+
|
34
|
+
# Use Pydantic to parse the User data with proper field aliasing
|
35
|
+
user = User.model_validate(result)
|
36
|
+
return AuthStatus(authenticated=True, user=user)
|
37
|
+
else:
|
38
|
+
# Return unauthenticated status for failed responses
|
39
|
+
return AuthStatus(authenticated=False)
|
40
|
+
|
41
|
+
except Exception as e:
|
42
|
+
last_exception = e
|
43
|
+
continue # Try next endpoint
|
44
|
+
|
45
|
+
# If all endpoints failed, check if it's because auth features are disabled
|
46
|
+
if last_exception and "auth-management-via-api" in str(last_exception):
|
47
|
+
# Auth features are disabled - this is a configuration issue, not authentication failure
|
48
|
+
# We can't determine auth status, so return a special state
|
49
|
+
return AuthStatus(authenticated=False)
|
50
|
+
|
51
|
+
# If we get here, all endpoints failed
|
52
|
+
if last_exception:
|
53
|
+
raise last_exception
|
54
|
+
|
55
|
+
# Return unauthenticated status as fallback
|
56
56
|
return AuthStatus(authenticated=False)
|
@@ -1,60 +1,60 @@
|
|
1
|
-
"""
|
2
|
-
Auto Asset Tags-related queries for the Binalyze AIR SDK.
|
3
|
-
"""
|
4
|
-
|
5
|
-
from typing import List, Optional
|
6
|
-
|
7
|
-
from ..base import Query
|
8
|
-
from ..models.auto_asset_tags import AutoAssetTag, AutoAssetTagFilter
|
9
|
-
from ..http_client import HTTPClient
|
10
|
-
|
11
|
-
|
12
|
-
class ListAutoAssetTagsQuery(Query[List[AutoAssetTag]]):
|
13
|
-
"""Query to list auto asset tags."""
|
14
|
-
|
15
|
-
def __init__(self, http_client: HTTPClient, filter_params: Optional[AutoAssetTagFilter] = None):
|
16
|
-
self.http_client = http_client
|
17
|
-
self.filter_params = filter_params
|
18
|
-
|
19
|
-
def execute(self) -> List[AutoAssetTag]:
|
20
|
-
"""Execute the list auto asset tags query."""
|
21
|
-
params = {}
|
22
|
-
|
23
|
-
# Add default organization filtering if no filter is provided
|
24
|
-
if self.filter_params:
|
25
|
-
params = self.filter_params.to_params()
|
26
|
-
else:
|
27
|
-
# Default organization filtering - critical for the API to work
|
28
|
-
params["filter[organizationIds]"] = "0"
|
29
|
-
|
30
|
-
# Ensure organization filtering is always present
|
31
|
-
if "filter[organizationIds]" not in params and "filter[organizationId]" not in params:
|
32
|
-
params["filter[organizationIds]"] = "0"
|
33
|
-
|
34
|
-
response = self.http_client.get("auto-asset-tag", params=params)
|
35
|
-
|
36
|
-
if response.get("success"):
|
37
|
-
tags_data = response.get("result", {}).get("entities", [])
|
38
|
-
# Use Pydantic parsing with proper field aliasing
|
39
|
-
return [AutoAssetTag.model_validate(tag_data) for tag_data in tags_data]
|
40
|
-
|
41
|
-
return []
|
42
|
-
|
43
|
-
|
44
|
-
class GetAutoAssetTagQuery(Query[AutoAssetTag]):
|
45
|
-
"""Query to get auto asset tag by ID."""
|
46
|
-
|
47
|
-
def __init__(self, http_client: HTTPClient, tag_id: str):
|
48
|
-
self.http_client = http_client
|
49
|
-
self.tag_id = tag_id
|
50
|
-
|
51
|
-
def execute(self) -> AutoAssetTag:
|
52
|
-
"""Execute the get auto asset tag query."""
|
53
|
-
response = self.http_client.get(f"auto-asset-tag/{self.tag_id}")
|
54
|
-
|
55
|
-
if response.get("success"):
|
56
|
-
tag_data = response.get("result", {})
|
57
|
-
# Use Pydantic parsing with proper field aliasing
|
58
|
-
return AutoAssetTag.model_validate(tag_data)
|
59
|
-
|
1
|
+
"""
|
2
|
+
Auto Asset Tags-related queries for the Binalyze AIR SDK.
|
3
|
+
"""
|
4
|
+
|
5
|
+
from typing import List, Optional
|
6
|
+
|
7
|
+
from ..base import Query
|
8
|
+
from ..models.auto_asset_tags import AutoAssetTag, AutoAssetTagFilter
|
9
|
+
from ..http_client import HTTPClient
|
10
|
+
|
11
|
+
|
12
|
+
class ListAutoAssetTagsQuery(Query[List[AutoAssetTag]]):
|
13
|
+
"""Query to list auto asset tags."""
|
14
|
+
|
15
|
+
def __init__(self, http_client: HTTPClient, filter_params: Optional[AutoAssetTagFilter] = None):
|
16
|
+
self.http_client = http_client
|
17
|
+
self.filter_params = filter_params
|
18
|
+
|
19
|
+
def execute(self) -> List[AutoAssetTag]:
|
20
|
+
"""Execute the list auto asset tags query."""
|
21
|
+
params = {}
|
22
|
+
|
23
|
+
# Add default organization filtering if no filter is provided
|
24
|
+
if self.filter_params:
|
25
|
+
params = self.filter_params.to_params()
|
26
|
+
else:
|
27
|
+
# Default organization filtering - critical for the API to work
|
28
|
+
params["filter[organizationIds]"] = "0"
|
29
|
+
|
30
|
+
# Ensure organization filtering is always present
|
31
|
+
if "filter[organizationIds]" not in params and "filter[organizationId]" not in params:
|
32
|
+
params["filter[organizationIds]"] = "0"
|
33
|
+
|
34
|
+
response = self.http_client.get("auto-asset-tag", params=params)
|
35
|
+
|
36
|
+
if response.get("success"):
|
37
|
+
tags_data = response.get("result", {}).get("entities", [])
|
38
|
+
# Use Pydantic parsing with proper field aliasing
|
39
|
+
return [AutoAssetTag.model_validate(tag_data) for tag_data in tags_data]
|
40
|
+
|
41
|
+
return []
|
42
|
+
|
43
|
+
|
44
|
+
class GetAutoAssetTagQuery(Query[AutoAssetTag]):
|
45
|
+
"""Query to get auto asset tag by ID."""
|
46
|
+
|
47
|
+
def __init__(self, http_client: HTTPClient, tag_id: str):
|
48
|
+
self.http_client = http_client
|
49
|
+
self.tag_id = tag_id
|
50
|
+
|
51
|
+
def execute(self) -> AutoAssetTag:
|
52
|
+
"""Execute the get auto asset tag query."""
|
53
|
+
response = self.http_client.get(f"auto-asset-tag/{self.tag_id}")
|
54
|
+
|
55
|
+
if response.get("success"):
|
56
|
+
tag_data = response.get("result", {})
|
57
|
+
# Use Pydantic parsing with proper field aliasing
|
58
|
+
return AutoAssetTag.model_validate(tag_data)
|
59
|
+
|
60
60
|
raise Exception(f"Auto asset tag not found: {self.tag_id}")
|
@@ -0,0 +1,66 @@
|
|
1
|
+
"""
|
2
|
+
Backup queries for the Binalyze AIR SDK.
|
3
|
+
"""
|
4
|
+
|
5
|
+
from typing import Optional, Dict, Any
|
6
|
+
|
7
|
+
from ..base import Query
|
8
|
+
from ..models.backup import (
|
9
|
+
BackupHistoryResponse, BackupFilter, BackupDownloadInfo
|
10
|
+
)
|
11
|
+
from ..http_client import HTTPClient
|
12
|
+
|
13
|
+
|
14
|
+
class GetBackupHistoryQuery(Query[BackupHistoryResponse]):
|
15
|
+
"""Query to get backup history with optional filtering."""
|
16
|
+
|
17
|
+
def __init__(self, http_client: HTTPClient, filter_params: Optional[BackupFilter] = None):
|
18
|
+
self.http_client = http_client
|
19
|
+
self.filter_params = filter_params or BackupFilter()
|
20
|
+
|
21
|
+
def execute(self) -> BackupHistoryResponse:
|
22
|
+
"""Execute the query."""
|
23
|
+
params = {}
|
24
|
+
|
25
|
+
# Add pagination parameters
|
26
|
+
if self.filter_params.page_size is not None:
|
27
|
+
params["pageSize"] = self.filter_params.page_size
|
28
|
+
if self.filter_params.page_number is not None:
|
29
|
+
params["pageNumber"] = self.filter_params.page_number
|
30
|
+
if self.filter_params.sort_type is not None:
|
31
|
+
params["sortType"] = self.filter_params.sort_type
|
32
|
+
if self.filter_params.sort_by is not None:
|
33
|
+
params["sortBy"] = self.filter_params.sort_by
|
34
|
+
|
35
|
+
# Add filter parameters
|
36
|
+
if self.filter_params.search_term is not None:
|
37
|
+
params["filter[searchTerm]"] = self.filter_params.search_term
|
38
|
+
if self.filter_params.username is not None:
|
39
|
+
params["filter[username]"] = self.filter_params.username
|
40
|
+
if self.filter_params.source is not None:
|
41
|
+
params["filter[source]"] = self.filter_params.source
|
42
|
+
if self.filter_params.status is not None:
|
43
|
+
params["filter[status]"] = self.filter_params.status
|
44
|
+
if self.filter_params.start_date is not None:
|
45
|
+
params["filter[startDate]"] = self.filter_params.start_date.isoformat()
|
46
|
+
if self.filter_params.end_date is not None:
|
47
|
+
params["filter[endDate]"] = self.filter_params.end_date.isoformat()
|
48
|
+
if self.filter_params.location is not None:
|
49
|
+
params["filter[location]"] = self.filter_params.location
|
50
|
+
|
51
|
+
response = self.http_client.get("backup/history", params=params)
|
52
|
+
return BackupHistoryResponse(**response["result"])
|
53
|
+
|
54
|
+
|
55
|
+
class GetBackupDownloadQuery(Query[Dict[str, Any]]):
|
56
|
+
"""Query to get backup download information."""
|
57
|
+
|
58
|
+
def __init__(self, http_client: HTTPClient, backup_id: str):
|
59
|
+
self.http_client = http_client
|
60
|
+
self.backup_id = backup_id
|
61
|
+
|
62
|
+
def execute(self) -> Dict[str, Any]:
|
63
|
+
"""Execute the query."""
|
64
|
+
# This endpoint typically returns a file download or download URL
|
65
|
+
response = self.http_client.get(f"backup/{self.backup_id}/download")
|
66
|
+
return response
|
binalyze_air/queries/baseline.py
CHANGED
@@ -1,185 +1,21 @@
|
|
1
|
-
"""
|
2
|
-
Baseline-related queries for the Binalyze AIR SDK.
|
3
|
-
"""
|
4
|
-
|
5
|
-
from typing import
|
6
|
-
|
7
|
-
from ..base import Query
|
8
|
-
from ..
|
9
|
-
|
10
|
-
|
11
|
-
)
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
self.
|
22
|
-
|
23
|
-
def execute(self) -> List[Baseline]:
|
24
|
-
"""Execute the query to list baselines."""
|
25
|
-
params = {}
|
26
|
-
if self.filter_params:
|
27
|
-
params = self.filter_params.model_dump(exclude_none=True)
|
28
|
-
|
29
|
-
response = self.http_client.get("baselines", params=params)
|
30
|
-
|
31
|
-
if response.get("success"):
|
32
|
-
baselines_data = response.get("result", {}).get("entities", [])
|
33
|
-
# Use Pydantic parsing with proper field aliasing
|
34
|
-
return [Baseline.model_validate(baseline_data) for baseline_data in baselines_data]
|
35
|
-
|
36
|
-
return []
|
37
|
-
|
38
|
-
|
39
|
-
class GetBaselineQuery(Query[Baseline]):
|
40
|
-
"""Query to get a specific baseline by ID."""
|
41
|
-
|
42
|
-
def __init__(self, http_client: HTTPClient, baseline_id: str):
|
43
|
-
self.http_client = http_client
|
44
|
-
self.baseline_id = baseline_id
|
45
|
-
|
46
|
-
def execute(self) -> Baseline:
|
47
|
-
"""Execute the query to get baseline details."""
|
48
|
-
response = self.http_client.get(f"baselines/{self.baseline_id}")
|
49
|
-
|
50
|
-
if response.get("success"):
|
51
|
-
baseline_data = response.get("result", {})
|
52
|
-
# Use Pydantic parsing with proper field aliasing
|
53
|
-
return Baseline.model_validate(baseline_data)
|
54
|
-
|
55
|
-
raise Exception(f"Baseline not found: {self.baseline_id}")
|
56
|
-
|
57
|
-
|
58
|
-
class GetBaselineComparisonsQuery(Query[List[BaselineComparison]]):
|
59
|
-
"""Query to get baseline comparisons."""
|
60
|
-
|
61
|
-
def __init__(self, http_client: HTTPClient, baseline_id: str):
|
62
|
-
self.http_client = http_client
|
63
|
-
self.baseline_id = baseline_id
|
64
|
-
|
65
|
-
def execute(self) -> List[BaselineComparison]:
|
66
|
-
"""Execute the query to get baseline comparisons."""
|
67
|
-
response = self.http_client.get(f"baselines/{self.baseline_id}/comparisons")
|
68
|
-
|
69
|
-
if response.get("success"):
|
70
|
-
comparisons_data = response.get("result", {}).get("entities", [])
|
71
|
-
comparisons = []
|
72
|
-
for comparison_data in comparisons_data:
|
73
|
-
# Parse changes if present
|
74
|
-
changes = []
|
75
|
-
for change_data in comparison_data.get("changes", []):
|
76
|
-
# Use Pydantic parsing for changes
|
77
|
-
changes.append(BaselineChange.model_validate(change_data))
|
78
|
-
|
79
|
-
# Add parsed changes to comparison data
|
80
|
-
comparison_data["changes"] = changes
|
81
|
-
|
82
|
-
# Use Pydantic parsing with proper field aliasing
|
83
|
-
comparisons.append(BaselineComparison.model_validate(comparison_data))
|
84
|
-
|
85
|
-
return comparisons
|
86
|
-
|
87
|
-
return []
|
88
|
-
|
89
|
-
|
90
|
-
class GetBaselineComparisonQuery(Query[BaselineComparison]):
|
91
|
-
"""Query to get a specific baseline comparison by ID."""
|
92
|
-
|
93
|
-
def __init__(self, http_client: HTTPClient, comparison_id: str):
|
94
|
-
self.http_client = http_client
|
95
|
-
self.comparison_id = comparison_id
|
96
|
-
|
97
|
-
def execute(self) -> BaselineComparison:
|
98
|
-
"""Execute the query to get baseline comparison details."""
|
99
|
-
response = self.http_client.get(f"baselines/comparisons/{self.comparison_id}")
|
100
|
-
|
101
|
-
if response.get("success"):
|
102
|
-
comparison_data = response.get("result", {})
|
103
|
-
|
104
|
-
# Parse changes if present
|
105
|
-
changes = []
|
106
|
-
for change_data in comparison_data.get("changes", []):
|
107
|
-
# Use Pydantic parsing for changes
|
108
|
-
changes.append(BaselineChange.model_validate(change_data))
|
109
|
-
|
110
|
-
# Add parsed changes to comparison data
|
111
|
-
comparison_data["changes"] = changes
|
112
|
-
|
113
|
-
# Use Pydantic parsing with proper field aliasing
|
114
|
-
return BaselineComparison.model_validate(comparison_data)
|
115
|
-
|
116
|
-
raise Exception(f"Baseline comparison not found: {self.comparison_id}")
|
117
|
-
|
118
|
-
|
119
|
-
class ListBaselineProfilesQuery(Query[List[BaselineProfile]]):
|
120
|
-
"""Query to list baseline profiles."""
|
121
|
-
|
122
|
-
def __init__(self, http_client: HTTPClient, organization_ids: Optional[List[int]] = None):
|
123
|
-
self.http_client = http_client
|
124
|
-
self.organization_ids = organization_ids or [0]
|
125
|
-
|
126
|
-
def execute(self) -> List[BaselineProfile]:
|
127
|
-
"""Execute the query to list baseline profiles."""
|
128
|
-
params = {
|
129
|
-
"filter[organizationIds]": ",".join(map(str, self.organization_ids))
|
130
|
-
}
|
131
|
-
|
132
|
-
response = self.http_client.get("baseline-profiles", params=params)
|
133
|
-
|
134
|
-
if response.get("success"):
|
135
|
-
profiles_data = response.get("result", {}).get("entities", [])
|
136
|
-
# Use Pydantic parsing with proper field aliasing
|
137
|
-
return [BaselineProfile.model_validate(profile_data) for profile_data in profiles_data]
|
138
|
-
|
139
|
-
return []
|
140
|
-
|
141
|
-
|
142
|
-
class GetBaselineProfileQuery(Query[BaselineProfile]):
|
143
|
-
"""Query to get a specific baseline profile by ID."""
|
144
|
-
|
145
|
-
def __init__(self, http_client: HTTPClient, profile_id: str):
|
146
|
-
self.http_client = http_client
|
147
|
-
self.profile_id = profile_id
|
148
|
-
|
149
|
-
def execute(self) -> BaselineProfile:
|
150
|
-
"""Execute the query to get baseline profile details."""
|
151
|
-
response = self.http_client.get(f"baseline-profiles/{self.profile_id}")
|
152
|
-
|
153
|
-
if response.get("success"):
|
154
|
-
profile_data = response.get("result", {})
|
155
|
-
# Use Pydantic parsing with proper field aliasing
|
156
|
-
return BaselineProfile.model_validate(profile_data)
|
157
|
-
|
158
|
-
raise Exception(f"Baseline profile not found: {self.profile_id}")
|
159
|
-
|
160
|
-
|
161
|
-
class GetBaselineSchedulesQuery(Query[List[BaselineSchedule]]):
|
162
|
-
"""Query to get baseline schedules."""
|
163
|
-
|
164
|
-
def __init__(self, http_client: HTTPClient, baseline_id: Optional[str] = None, organization_ids: Optional[List[int]] = None):
|
165
|
-
self.http_client = http_client
|
166
|
-
self.baseline_id = baseline_id
|
167
|
-
self.organization_ids = organization_ids or [0]
|
168
|
-
|
169
|
-
def execute(self) -> List[BaselineSchedule]:
|
170
|
-
"""Execute the query to get baseline schedules."""
|
171
|
-
params = {
|
172
|
-
"filter[organizationIds]": ",".join(map(str, self.organization_ids))
|
173
|
-
}
|
174
|
-
|
175
|
-
if self.baseline_id:
|
176
|
-
params["baselineId"] = self.baseline_id
|
177
|
-
|
178
|
-
response = self.http_client.get("baseline-schedules", params=params)
|
179
|
-
|
180
|
-
if response.get("success"):
|
181
|
-
schedules_data = response.get("result", {}).get("entities", [])
|
182
|
-
# Use Pydantic parsing with proper field aliasing
|
183
|
-
return [BaselineSchedule.model_validate(schedule_data) for schedule_data in schedules_data]
|
184
|
-
|
185
|
-
return []
|
1
|
+
"""
|
2
|
+
Baseline-related queries for the Binalyze AIR SDK.
|
3
|
+
"""
|
4
|
+
|
5
|
+
from typing import Dict, Any
|
6
|
+
|
7
|
+
from ..base import Query
|
8
|
+
from ..http_client import HTTPClient
|
9
|
+
|
10
|
+
|
11
|
+
class GetBaselineComparisonReportQuery(Query[Dict[str, Any]]):
|
12
|
+
"""Query to get baseline comparison report by endpoint ID and task ID."""
|
13
|
+
|
14
|
+
def __init__(self, http_client: HTTPClient, endpoint_id: str, task_id: str):
|
15
|
+
self.http_client = http_client
|
16
|
+
self.endpoint_id = endpoint_id
|
17
|
+
self.task_id = task_id
|
18
|
+
|
19
|
+
def execute(self) -> Dict[str, Any]:
|
20
|
+
"""Execute the query to get baseline comparison report."""
|
21
|
+
return self.http_client.get(f"baseline/comparison/report/{self.endpoint_id}/{self.task_id}")
|