polyswarm-api 3.7.0__tar.gz → 3.8.0__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.
- {polyswarm-api-3.7.0/src/polyswarm_api.egg-info → polyswarm-api-3.8.0}/PKG-INFO +1 -1
- {polyswarm-api-3.7.0 → polyswarm-api-3.8.0}/setup.py +1 -1
- {polyswarm-api-3.7.0 → polyswarm-api-3.8.0}/src/polyswarm_api/__init__.py +1 -1
- {polyswarm-api-3.7.0 → polyswarm-api-3.8.0}/src/polyswarm_api/api.py +141 -31
- {polyswarm-api-3.7.0 → polyswarm-api-3.8.0}/src/polyswarm_api/settings.py +1 -0
- {polyswarm-api-3.7.0 → polyswarm-api-3.8.0/src/polyswarm_api.egg-info}/PKG-INFO +1 -1
- {polyswarm-api-3.7.0 → polyswarm-api-3.8.0}/LICENSE +0 -0
- {polyswarm-api-3.7.0 → polyswarm-api-3.8.0}/MANIFEST.in +0 -0
- {polyswarm-api-3.7.0 → polyswarm-api-3.8.0}/README.md +0 -0
- {polyswarm-api-3.7.0 → polyswarm-api-3.8.0}/requirements.txt +0 -0
- {polyswarm-api-3.7.0 → polyswarm-api-3.8.0}/setup.cfg +0 -0
- {polyswarm-api-3.7.0 → polyswarm-api-3.8.0}/src/polyswarm_api/core.py +0 -0
- {polyswarm-api-3.7.0 → polyswarm-api-3.8.0}/src/polyswarm_api/exceptions.py +0 -0
- {polyswarm-api-3.7.0 → polyswarm-api-3.8.0}/src/polyswarm_api/resources.py +0 -0
- {polyswarm-api-3.7.0 → polyswarm-api-3.8.0}/src/polyswarm_api.egg-info/SOURCES.txt +0 -0
- {polyswarm-api-3.7.0 → polyswarm-api-3.8.0}/src/polyswarm_api.egg-info/dependency_links.txt +0 -0
- {polyswarm-api-3.7.0 → polyswarm-api-3.8.0}/src/polyswarm_api.egg-info/requires.txt +0 -0
- {polyswarm-api-3.7.0 → polyswarm-api-3.8.0}/src/polyswarm_api.egg-info/top_level.txt +0 -0
|
@@ -9,7 +9,7 @@ with open('README.md', 'r') as readme:
|
|
|
9
9
|
|
|
10
10
|
setup(
|
|
11
11
|
name='polyswarm-api',
|
|
12
|
-
version='3.
|
|
12
|
+
version='3.8.0',
|
|
13
13
|
description='Client library to simplify interacting with the PolySwarm consumer API',
|
|
14
14
|
long_description=long_description,
|
|
15
15
|
long_description_content_type='text/markdown',
|
|
@@ -211,14 +211,26 @@ class PolyswarmAPI:
|
|
|
211
211
|
logger.info('Deleting known good ioc %s', id)
|
|
212
212
|
return resources.IOC.delete_known_good(self, id).result()
|
|
213
213
|
|
|
214
|
-
def submit(
|
|
215
|
-
|
|
216
|
-
|
|
214
|
+
def submit(
|
|
215
|
+
self,
|
|
216
|
+
artifact,
|
|
217
|
+
artifact_type=resources.ArtifactType.FILE,
|
|
218
|
+
artifact_name=None,
|
|
219
|
+
scan_config=None,
|
|
220
|
+
is_zip=False,
|
|
221
|
+
zip_password=None,
|
|
222
|
+
):
|
|
223
|
+
"""
|
|
224
|
+
Submit artifacts to polyswarm
|
|
217
225
|
|
|
218
226
|
:param artifact: A file-like, path to file, url or LocalArtifact instance
|
|
219
227
|
:param artifact_type: The ArtifactType or strings containing "file" or "url"
|
|
220
228
|
:param artifact_name: An appropriate filename for the Artifact
|
|
221
229
|
:param scan_config: The scan configuration to be used, e.g.: "default", "more-time", "most-time"
|
|
230
|
+
:param is_zip: If this flag is set, will handle the file as a zip
|
|
231
|
+
in the server and decompress before processing.
|
|
232
|
+
:param zip_password: Will use this password to decompress the zip file.
|
|
233
|
+
If provided, will handle the file as a zip.
|
|
222
234
|
:return: An ArtifactInstance resource
|
|
223
235
|
"""
|
|
224
236
|
logger.info('Submitting artifact of type %s', artifact_type)
|
|
@@ -239,11 +251,15 @@ class PolyswarmAPI:
|
|
|
239
251
|
if artifact_type == resources.ArtifactType.URL:
|
|
240
252
|
scan_config = scan_config or 'more-time'
|
|
241
253
|
if isinstance(artifact, resources.LocalArtifact):
|
|
242
|
-
instance = resources.ArtifactInstance.create(
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
254
|
+
instance = resources.ArtifactInstance.create(
|
|
255
|
+
self,
|
|
256
|
+
artifact_name=artifact.artifact_name,
|
|
257
|
+
artifact_type=artifact.artifact_type.name,
|
|
258
|
+
scan_config=scan_config,
|
|
259
|
+
community=self.community,
|
|
260
|
+
is_zip=is_zip,
|
|
261
|
+
zip_password=zip_password,
|
|
262
|
+
).result()
|
|
247
263
|
instance.upload_file(artifact)
|
|
248
264
|
return resources.ArtifactInstance.update(self, id=instance.id, community=self.community).result()
|
|
249
265
|
else:
|
|
@@ -690,7 +706,17 @@ class PolyswarmAPI:
|
|
|
690
706
|
return resources.SandboxTask.create(self, artifact_id=instance_id, provider_slug=provider_slug, vm_slug=vm_slug,
|
|
691
707
|
network_enabled=network_enabled).result()
|
|
692
708
|
|
|
693
|
-
def sandbox_file(
|
|
709
|
+
def sandbox_file(
|
|
710
|
+
self,
|
|
711
|
+
artifact,
|
|
712
|
+
provider_slug,
|
|
713
|
+
vm_slug,
|
|
714
|
+
artifact_type=resources.ArtifactType.FILE,
|
|
715
|
+
artifact_name=None,
|
|
716
|
+
network_enabled=True,
|
|
717
|
+
is_zip=False,
|
|
718
|
+
zip_password=None,
|
|
719
|
+
):
|
|
694
720
|
logger.info('Sandboxing file in provider %s vm %s', provider_slug, vm_slug)
|
|
695
721
|
artifact_type = resources.ArtifactType.parse(artifact_type)
|
|
696
722
|
# TODO This is a python 2.7 check if artifact is a file-like instance, consider changing
|
|
@@ -708,13 +734,17 @@ class PolyswarmAPI:
|
|
|
708
734
|
artifact_name=artifact_name or artifact,
|
|
709
735
|
artifact_type=artifact_type)
|
|
710
736
|
if isinstance(artifact, resources.LocalArtifact):
|
|
711
|
-
task = resources.SandboxTask.create_file(
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
737
|
+
task = resources.SandboxTask.create_file(
|
|
738
|
+
self,
|
|
739
|
+
artifact_name=artifact.artifact_name,
|
|
740
|
+
artifact_type=artifact.artifact_type.name,
|
|
741
|
+
community=self.community,
|
|
742
|
+
provider_slug=provider_slug,
|
|
743
|
+
vm_slug=vm_slug,
|
|
744
|
+
network_enabled=network_enabled,
|
|
745
|
+
is_zip=is_zip,
|
|
746
|
+
zip_password=zip_password,
|
|
747
|
+
).result()
|
|
718
748
|
task.upload_file(artifact)
|
|
719
749
|
return resources.SandboxTask.update_file(self, id=task.id, community=self.community).result()
|
|
720
750
|
else:
|
|
@@ -823,18 +853,62 @@ class PolyswarmAPI:
|
|
|
823
853
|
logger.info('List events')
|
|
824
854
|
return resources.Events.list(self, **kwargs).result()
|
|
825
855
|
|
|
826
|
-
def report_create(self,
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
856
|
+
def report_create(self,
|
|
857
|
+
type,
|
|
858
|
+
format,
|
|
859
|
+
instance_id=None,
|
|
860
|
+
sandbox_task_id=None,
|
|
861
|
+
template_id=None,
|
|
862
|
+
template_metadata=None,
|
|
863
|
+
**kwargs):
|
|
864
|
+
"""
|
|
865
|
+
Create a report, either 'pdf' or 'html' (format argument).
|
|
866
|
+
Regarding the type argument, either instance_id (type='scan')
|
|
867
|
+
or sandbox_task_id (type='sandbox') has to be provided.
|
|
868
|
+
"""
|
|
869
|
+
report = resources.ReportTask.create(self,
|
|
870
|
+
type=type,
|
|
871
|
+
format=format,
|
|
872
|
+
instance_id=instance_id,
|
|
873
|
+
sandbox_task_id=sandbox_task_id,
|
|
874
|
+
template_id=template_id,
|
|
875
|
+
template_metadata=template_metadata,
|
|
876
|
+
**kwargs).result()
|
|
877
|
+
return report
|
|
878
|
+
|
|
879
|
+
def report_get(self, id, **kwargs):
|
|
880
|
+
return resources.ReportTask.get(self, id=id, **kwargs).result()
|
|
831
881
|
|
|
832
882
|
def report_download(self, report_id, folder):
|
|
833
883
|
report = resources.ReportTask.get(self, id=report_id).result()
|
|
884
|
+
if report.state == 'PENDING':
|
|
885
|
+
raise exceptions.InvalidValueException('Report is in PENDING state, wait for completion first')
|
|
886
|
+
if report.state == 'FAILED':
|
|
887
|
+
raise exceptions.InvalidValueException("Report is in FAILED state, won't be generated")
|
|
834
888
|
result = report.download_report(folder=folder).result()
|
|
835
889
|
result.handle.close()
|
|
836
890
|
return result
|
|
837
891
|
|
|
892
|
+
def report_wait_for(self, report_id, timeout=settings.DEFAULT_REPORT_TIMEOUT):
|
|
893
|
+
"""
|
|
894
|
+
Wait for a Report to finish successfully.
|
|
895
|
+
|
|
896
|
+
:param report_id: Report id to wait for
|
|
897
|
+
:param timeout: Maximum time in seconds to wait before raising a TimeoutException
|
|
898
|
+
:return: The ReportTask resource waited on, either in 'SUCCEEDED' or 'FAILED' state
|
|
899
|
+
"""
|
|
900
|
+
logger.info('Waiting for report %s', report_id)
|
|
901
|
+
start = time.time()
|
|
902
|
+
while True:
|
|
903
|
+
report_result = self.report_get(id=report_id)
|
|
904
|
+
if report_result.state != 'PENDING':
|
|
905
|
+
return report_result
|
|
906
|
+
elif -1 < timeout < time.time() - start:
|
|
907
|
+
raise exceptions.TimeoutException(
|
|
908
|
+
f'Timed out waiting for report {report_id} to finish. Please try again.')
|
|
909
|
+
else:
|
|
910
|
+
time.sleep(settings.POLL_FREQUENCY)
|
|
911
|
+
|
|
838
912
|
def report_template_logo_download(self, template_id, folder):
|
|
839
913
|
report = resources.ReportTemplate.get(self, id=template_id).result()
|
|
840
914
|
result = report.download_logo(folder).result()
|
|
@@ -851,11 +925,50 @@ class PolyswarmAPI:
|
|
|
851
925
|
result = report.upload_logo(logo_file, content_tpe).result()
|
|
852
926
|
return result
|
|
853
927
|
|
|
854
|
-
def report_template_create(self,
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
928
|
+
def report_template_create(self,
|
|
929
|
+
template_name,
|
|
930
|
+
is_default=False,
|
|
931
|
+
primary_color=None,
|
|
932
|
+
footer_text=None,
|
|
933
|
+
last_page_text=None,
|
|
934
|
+
includes=None,
|
|
935
|
+
**kwargs):
|
|
936
|
+
"""
|
|
937
|
+
Create a template for reports.
|
|
938
|
+
A team account can have multiple templates, and setting is_default=True
|
|
939
|
+
makes it the default when a report is created without specifying template_id
|
|
940
|
+
(see report_create method).
|
|
941
|
+
The includes argument can be a list with sections to be included
|
|
942
|
+
in the reports. The list can include any of the following section names:
|
|
943
|
+
summary, detections, fileMetadata, network, droppedFiles, extractedConfig, analysis.
|
|
944
|
+
"""
|
|
945
|
+
return resources.ReportTemplate.create(self,
|
|
946
|
+
template_name=template_name,
|
|
947
|
+
is_default=is_default,
|
|
948
|
+
primary_color=primary_color,
|
|
949
|
+
footer_text=footer_text,
|
|
950
|
+
last_page_text=last_page_text,
|
|
951
|
+
includes=includes,
|
|
952
|
+
**kwargs).result()
|
|
953
|
+
|
|
954
|
+
def report_template_update(self,
|
|
955
|
+
template_id,
|
|
956
|
+
template_name=None,
|
|
957
|
+
is_default=None,
|
|
958
|
+
primary_color=None,
|
|
959
|
+
footer_text=None,
|
|
960
|
+
last_page_text=None,
|
|
961
|
+
includes=None,
|
|
962
|
+
**kwargs):
|
|
963
|
+
return resources.ReportTemplate.update(self,
|
|
964
|
+
id=template_id,
|
|
965
|
+
template_name=template_name,
|
|
966
|
+
is_default=is_default,
|
|
967
|
+
primary_color=primary_color,
|
|
968
|
+
footer_text=footer_text,
|
|
969
|
+
last_page_text=last_page_text,
|
|
970
|
+
includes=includes,
|
|
971
|
+
**kwargs).result()
|
|
859
972
|
|
|
860
973
|
def report_template_get(self, template_id):
|
|
861
974
|
return resources.ReportTemplate.get(self, id=template_id).result()
|
|
@@ -863,8 +976,5 @@ class PolyswarmAPI:
|
|
|
863
976
|
def report_template_delete(self, template_id):
|
|
864
977
|
return resources.ReportTemplate.delete(self, id=template_id).result()
|
|
865
978
|
|
|
866
|
-
def report_template_list(self, is_default=None):
|
|
867
|
-
|
|
868
|
-
if is_default is not None:
|
|
869
|
-
params['is_default'] = is_default
|
|
870
|
-
return resources.ReportTemplate.list(self, **params).result()
|
|
979
|
+
def report_template_list(self, is_default=None, **kwargs):
|
|
980
|
+
return resources.ReportTemplate.list(self, is_default=is_default, **kwargs).result()
|
|
@@ -7,6 +7,7 @@ DEFAULT_GLOBAL_API = 'https://api.polyswarm.network/v3'
|
|
|
7
7
|
DEFAULT_PERMALINK_BASE = os.getenv('POLYSWARM_PORTAL_URI', 'https://polyswarm.network/scan/results/file')
|
|
8
8
|
DEFAULT_COMMUNITY = 'default'
|
|
9
9
|
DEFAULT_SCAN_TIMEOUT = 60*15
|
|
10
|
+
DEFAULT_REPORT_TIMEOUT = 30
|
|
10
11
|
RESULT_CHUNK_SIZE = 100
|
|
11
12
|
POLL_FREQUENCY = 1
|
|
12
13
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|