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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: polyswarm-api
3
- Version: 3.7.0
3
+ Version: 3.8.0
4
4
  Summary: Client library to simplify interacting with the PolySwarm consumer API
5
5
  Home-page: https://github.com/polyswarm/polyswarm-api
6
6
  Author: PolySwarm Developers
@@ -9,7 +9,7 @@ with open('README.md', 'r') as readme:
9
9
 
10
10
  setup(
11
11
  name='polyswarm-api',
12
- version='3.7.0',
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',
@@ -1,5 +1,5 @@
1
1
  # https://www.python.org/dev/peps/pep-0008/#module-level-dunder-names
2
- __version__ = '3.7.0'
2
+ __version__ = '3.8.0'
3
3
  __release_url__ = 'https://api.github.com/repos/polyswarm/polyswarm-api/releases/latest'
4
4
 
5
5
  from . import api
@@ -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(self, artifact, artifact_type=resources.ArtifactType.FILE, artifact_name=None, scan_config=None):
215
- """
216
- Submit artifacts to polyswarm and return UUIDs
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(self,
243
- artifact_name=artifact.artifact_name,
244
- artifact_type=artifact.artifact_type.name,
245
- scan_config=scan_config,
246
- community=self.community).result()
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(self, artifact, provider_slug, vm_slug, artifact_type=resources.ArtifactType.FILE, artifact_name=None, network_enabled=True):
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(self,
712
- artifact_name=artifact.artifact_name,
713
- artifact_type=artifact.artifact_type.name,
714
- community=self.community,
715
- provider_slug=provider_slug,
716
- vm_slug=vm_slug,
717
- network_enabled=network_enabled).result()
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, **kwargs):
827
- return resources.ReportTask.create(self, **kwargs).result()
828
-
829
- def report_get(self, **kwargs):
830
- return resources.ReportTask.get(self, **kwargs).result()
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, **kwargs):
855
- return resources.ReportTemplate.create(self, **kwargs).result()
856
-
857
- def report_template_update(self, template_id, **kwargs):
858
- return resources.ReportTemplate.update(self, id=template_id, **kwargs).result()
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
- params = {}
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
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: polyswarm-api
3
- Version: 3.7.0
3
+ Version: 3.8.0
4
4
  Summary: Client library to simplify interacting with the PolySwarm consumer API
5
5
  Home-page: https://github.com/polyswarm/polyswarm-api
6
6
  Author: PolySwarm Developers
File without changes
File without changes
File without changes
File without changes