Skip to content

Commit 220aa2d

Browse files
Merge branch 'develop' into 'main'
2.9.0 See merge request integrations/sdk/reversinglabs-sdk-py3!24
2 parents fefcd76 + 13a7bfc commit 220aa2d

14 files changed

+685
-232
lines changed

CHANGELOG.md

+21-1
Original file line numberDiff line numberDiff line change
@@ -396,13 +396,33 @@ v2.5.1 (2024-04-02)
396396
- Added the Spectra Assure badge to the Readme file.
397397

398398

399-
### Reversinglabs SDK Cookbook changes
399+
### ReversingLabs SDK Cookbook changes
400400
#### Improvements
401401
- **Scenarios and Workflows** notebooks:
402402
- Added the `download_advanced_search_matches_a1000.ipynb`, `download_advanced_search_matches_titaniumcloud.ipynb`, `download_yara_retro_matches_a1000.ipynb` and `download_yara_retro_matches_titaniumcloud.ipynb` notebooks.
403403

404404
- **Command line tools and scripts**:
405405
- Added the `cyber_defense_alliance.py` command line tool.
406+
407+
408+
2.9.0 (2025-03-31)
409+
-------------------
410+
411+
#### Improvements
412+
- **advanced** module:
413+
- Created a new module called `advanced`. This module will hold various actions and scenarios that include multiple platforms and APIs.
414+
- The `AdvancedActions` class was moved from the `ticloud` module into `advanced`.
415+
- The `SpectraAssureScenarios` and `SpectraAssureClient` enable the user to perform actions that combine the **ReversingLabs Spectra Assure** platform with TitaniumCloud and A1000.
416+
417+
- The user agent string now also carries the class and method name.
418+
419+
### ReversingLabs SDK Cookbook changes
420+
#### Improvements
421+
- **TitaniumCloud** notebooks:
422+
- The `taxii_ransomware_feed.ipynb` notebook was replaced with `taxii_feed.ipynb`.
423+
424+
- **Scenarios and Workflows** notebooks:
425+
- Added the `advanced_search_using_network_indicators.ipynb` notebook.
406426

407427
Starting with ReversingLabs SDK version 2.8.0, the **ReversingLabs SDK Cookbook** project's release cycle and versioning are closely tied to this project.
408428
This changelog will also be keeping track of changes made to the ReversingLabs SDK Cookbook project.

LICENSE

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
Copyright (c) 2024 ReversingLabs
1+
Copyright (c) 2025 ReversingLabs
22

33
Permission is hereby granted, free of charge, to any person obtaining a copy
44
of this software and associated documentation files (the "Software"), to deal

ReversingLabs/SDK/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,4 @@
55
A Python SDK for communicating with ReversingLabs services.
66
"""
77

8-
__version__ = "2.8.3"
8+
__version__ = "2.9.0"

ReversingLabs/SDK/a1000.py

+35-14
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
"""
77

88
import datetime
9+
import inspect
910
import requests
1011
import time
1112
from urllib import parse
@@ -104,7 +105,6 @@ def __init__(self, host, username=None, password=None, token=None, fields_v2=__F
104105
token = self.__get_token(username, password)
105106

106107
self._headers = {
107-
"User-Agent": self._user_agent,
108108
"Authorization": "Token {token}".format(token=token)
109109
}
110110
self._fields_v2 = fields_v2
@@ -291,7 +291,7 @@ def submit_url_for_analysis(self, url_string, crawler=None, archive_password=Non
291291

292292
response = self.__post_request(
293293
url=url,
294-
data=data,
294+
data=data
295295
)
296296

297297
self.__raise_on_error(response)
@@ -489,7 +489,10 @@ def get_summary_report_v2(self, sample_hashes, retry=True, fields=None, include_
489489
"skip_reanalysis": str(skip_reanalysis).lower()
490490
}
491491

492-
response = self.__post_request(url=url, data=data)
492+
response = self.__post_request(
493+
url=url,
494+
data=data
495+
)
493496

494497
self.__raise_on_error(response)
495498

@@ -628,7 +631,10 @@ def get_detailed_report_v2(self, sample_hashes, retry=False, fields=None, skip_r
628631

629632
data["include_networkthreatintelligence"] = str(include_networkthreatintelligence).lower()
630633

631-
response = self.__post_request(url=url, data=data)
634+
response = self.__post_request(
635+
url=url,
636+
data=data
637+
)
632638
self.__raise_on_error(response)
633639

634640
return response
@@ -803,7 +809,10 @@ def reanalyze_samples_v2(self, hash_input, titanium_cloud=False, titanium_core=F
803809
"rl_cloud_sandbox_platform": rl_cloud_sandbox_platform
804810
}
805811

806-
response = self.__post_request(url=url, data=data)
812+
response = self.__post_request(
813+
url=url,
814+
data=data
815+
)
807816

808817
self.__raise_on_error(response)
809818

@@ -976,7 +985,10 @@ def delete_samples(self, hash_input):
976985

977986
data = {"hash_values": hash_input}
978987

979-
response = self.__post_request(url=url, data=data)
988+
response = self.__post_request(
989+
url=url,
990+
data=data
991+
)
980992

981993
else:
982994
raise WrongInputError("hash_input parameter must be a single hash string or "
@@ -1234,7 +1246,10 @@ def set_classification(self, sample_hash, classification, system, risk_score=Non
12341246

12351247
url = self._url.format(endpoint=endpoint)
12361248

1237-
response = self.__post_request(url=url, data=data)
1249+
response = self.__post_request(
1250+
url=url,
1251+
data=data
1252+
)
12381253

12391254
self.__raise_on_error(response)
12401255

@@ -1812,8 +1827,8 @@ def advanced_search_v3(self, query_string, ticloud=False, start_search_date=None
18121827
Query string example:
18131828
'av-count:5 available:TRUE'
18141829
1815-
:param query_string: query string
1816-
:type query_string: str
1830+
:param query_string: search query; can be a string or a dict
1831+
:type query_string: str or dict
18171832
:param ticloud: show only cloud results
18181833
:type ticloud: bool
18191834
:param start_search_date: the starting date for the search; this parameter represents the later
@@ -1834,9 +1849,6 @@ def advanced_search_v3(self, query_string, ticloud=False, start_search_date=None
18341849
:return: response
18351850
:rtype: requests.Response
18361851
"""
1837-
if not isinstance(query_string, str):
1838-
raise WrongInputError("The search query must be a string.")
1839-
18401852
if not isinstance(ticloud, bool):
18411853
raise WrongInputError("ticloud parameter must be boolean.")
18421854

@@ -1888,8 +1900,8 @@ def advanced_search_v3_aggregated(self, query_string, ticloud=False, start_searc
18881900
Query string example:
18891901
'av-count:5 available:TRUE'
18901902
1891-
:param query_string: query string
1892-
:type query_string: str
1903+
:param query_string: search query; can be a string or a dict
1904+
:type query_string: str or dict
18931905
:param ticloud: show only cloud results
18941906
:type ticloud: bool
18951907
:param start_search_date: the starting date for the search; this parameter represents the later
@@ -2472,6 +2484,9 @@ def __get_request(self, url, params=None):
24722484
:return: response
24732485
:rtype: requests.Response
24742486
"""
2487+
self._headers["User-Agent"] = (f"{self._user_agent}; {self.__class__.__name__} "
2488+
f"{inspect.currentframe().f_back.f_code.co_name}")
2489+
24752490
response = requests.get(
24762491
url=url,
24772492
verify=self._verify,
@@ -2494,6 +2509,9 @@ def __post_request(self, url, post_json=None, files=None, data=None, params=None
24942509
:return: response
24952510
:rtype: requests.Response
24962511
"""
2512+
self._headers["User-Agent"] = (f"{self._user_agent}; "
2513+
f"{self.__class__.__name__} {inspect.currentframe().f_back.f_code.co_name}")
2514+
24972515
response = requests.post(
24982516
url=url,
24992517
json=post_json,
@@ -2514,6 +2532,9 @@ def __delete_request(self, url, post_json=None):
25142532
:return: response
25152533
:rtype: requests.Response
25162534
"""
2535+
self._headers["User-Agent"] = (f"{self._user_agent}; {self.__class__.__name__} "
2536+
f"{inspect.currentframe().f_back.f_code.co_name}")
2537+
25172538
response = requests.delete(
25182539
url=url,
25192540
json=post_json,

0 commit comments

Comments
 (0)