polyswarm-api 3.7.0__tar.gz → 3.9.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.9.0}/PKG-INFO +1 -1
- {polyswarm-api-3.7.0 → polyswarm-api-3.9.0}/setup.py +1 -1
- {polyswarm-api-3.7.0 → polyswarm-api-3.9.0}/src/polyswarm_api/__init__.py +1 -1
- {polyswarm-api-3.7.0 → polyswarm-api-3.9.0}/src/polyswarm_api/api.py +238 -44
- {polyswarm-api-3.7.0 → polyswarm-api-3.9.0}/src/polyswarm_api/resources.py +47 -0
- {polyswarm-api-3.7.0 → polyswarm-api-3.9.0}/src/polyswarm_api/settings.py +1 -0
- {polyswarm-api-3.7.0 → polyswarm-api-3.9.0/src/polyswarm_api.egg-info}/PKG-INFO +1 -1
- {polyswarm-api-3.7.0 → polyswarm-api-3.9.0}/LICENSE +0 -0
- {polyswarm-api-3.7.0 → polyswarm-api-3.9.0}/MANIFEST.in +0 -0
- {polyswarm-api-3.7.0 → polyswarm-api-3.9.0}/README.md +0 -0
- {polyswarm-api-3.7.0 → polyswarm-api-3.9.0}/requirements.txt +0 -0
- {polyswarm-api-3.7.0 → polyswarm-api-3.9.0}/setup.cfg +0 -0
- {polyswarm-api-3.7.0 → polyswarm-api-3.9.0}/src/polyswarm_api/core.py +0 -0
- {polyswarm-api-3.7.0 → polyswarm-api-3.9.0}/src/polyswarm_api/exceptions.py +0 -0
- {polyswarm-api-3.7.0 → polyswarm-api-3.9.0}/src/polyswarm_api.egg-info/SOURCES.txt +0 -0
- {polyswarm-api-3.7.0 → polyswarm-api-3.9.0}/src/polyswarm_api.egg-info/dependency_links.txt +0 -0
- {polyswarm-api-3.7.0 → polyswarm-api-3.9.0}/src/polyswarm_api.egg-info/requires.txt +0 -0
- {polyswarm-api-3.7.0 → polyswarm-api-3.9.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.9.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,3 +1,4 @@
|
|
|
1
|
+
import io
|
|
1
2
|
import logging
|
|
2
3
|
import time
|
|
3
4
|
|
|
@@ -211,22 +212,33 @@ class PolyswarmAPI:
|
|
|
211
212
|
logger.info('Deleting known good ioc %s', id)
|
|
212
213
|
return resources.IOC.delete_known_good(self, id).result()
|
|
213
214
|
|
|
214
|
-
def submit(
|
|
215
|
+
def submit(
|
|
216
|
+
self,
|
|
217
|
+
artifact,
|
|
218
|
+
artifact_type=resources.ArtifactType.FILE,
|
|
219
|
+
artifact_name=None,
|
|
220
|
+
scan_config=None,
|
|
221
|
+
preprocessing=None,
|
|
222
|
+
):
|
|
215
223
|
"""
|
|
216
|
-
Submit artifacts to polyswarm
|
|
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 preprocessing: Preprocessing settings to be applied to the artifact, None means no preprocessing,
|
|
231
|
+
otherwise a dict with the following attributes can be passed:
|
|
232
|
+
- type (string): either "zip" or "qrcode", the first mean the file is a zip that
|
|
233
|
+
the server has to decompress to then scan the content (only one file inside allowed).
|
|
234
|
+
"qrcode" means the file is a QR Code image with a URL as payload, and you want
|
|
235
|
+
to scan the URL, not the actual file (artifact_type has to be "URL").
|
|
236
|
+
- password (string, optional): will use this password to decompress the zip file.
|
|
222
237
|
:return: An ArtifactInstance resource
|
|
223
238
|
"""
|
|
224
239
|
logger.info('Submitting artifact of type %s', artifact_type)
|
|
225
240
|
artifact_type = resources.ArtifactType.parse(artifact_type)
|
|
226
|
-
|
|
227
|
-
# to isinstance(artifact, io.IOBase) when deprecating 2.7 and implementing making LocalHandle
|
|
228
|
-
# inherit io.IOBase, although this will change the method delegation logic in the resource
|
|
229
|
-
if hasattr(artifact, 'read') and hasattr(artifact.read, '__call__'):
|
|
241
|
+
if isinstance(artifact, io.IOBase):
|
|
230
242
|
artifact = resources.LocalArtifact.from_handle(self, artifact, artifact_name=artifact_name or '',
|
|
231
243
|
artifact_type=artifact_type)
|
|
232
244
|
elif isinstance(artifact, str):
|
|
@@ -234,16 +246,27 @@ class PolyswarmAPI:
|
|
|
234
246
|
artifact = resources.LocalArtifact.from_path(self, artifact, artifact_type=artifact_type,
|
|
235
247
|
artifact_name=artifact_name)
|
|
236
248
|
elif artifact_type == resources.ArtifactType.URL:
|
|
237
|
-
|
|
238
|
-
|
|
249
|
+
if preprocessing and preprocessing['type'] == 'qrcode':
|
|
250
|
+
artifact = resources.LocalArtifact.from_path(self,
|
|
251
|
+
artifact,
|
|
252
|
+
artifact_type=artifact_type,
|
|
253
|
+
artifact_name=artifact_name)
|
|
254
|
+
else:
|
|
255
|
+
artifact = resources.LocalArtifact.from_content(self,
|
|
256
|
+
artifact,
|
|
257
|
+
artifact_name=artifact_name or artifact,
|
|
258
|
+
artifact_type=artifact_type)
|
|
239
259
|
if artifact_type == resources.ArtifactType.URL:
|
|
240
260
|
scan_config = scan_config or 'more-time'
|
|
241
261
|
if isinstance(artifact, resources.LocalArtifact):
|
|
242
|
-
instance = resources.ArtifactInstance.create(
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
262
|
+
instance = resources.ArtifactInstance.create(
|
|
263
|
+
self,
|
|
264
|
+
artifact_name=artifact.artifact_name,
|
|
265
|
+
artifact_type=artifact.artifact_type.name,
|
|
266
|
+
scan_config=scan_config,
|
|
267
|
+
community=self.community,
|
|
268
|
+
preprocessing=preprocessing,
|
|
269
|
+
).result()
|
|
247
270
|
instance.upload_file(artifact)
|
|
248
271
|
return resources.ArtifactInstance.update(self, id=instance.id, community=self.community).result()
|
|
249
272
|
else:
|
|
@@ -690,13 +713,43 @@ class PolyswarmAPI:
|
|
|
690
713
|
return resources.SandboxTask.create(self, artifact_id=instance_id, provider_slug=provider_slug, vm_slug=vm_slug,
|
|
691
714
|
network_enabled=network_enabled).result()
|
|
692
715
|
|
|
693
|
-
def sandbox_file(
|
|
694
|
-
|
|
716
|
+
def sandbox_file(
|
|
717
|
+
self,
|
|
718
|
+
artifact,
|
|
719
|
+
provider_slug,
|
|
720
|
+
vm_slug,
|
|
721
|
+
artifact_type=resources.ArtifactType.FILE,
|
|
722
|
+
artifact_name=None,
|
|
723
|
+
network_enabled=True,
|
|
724
|
+
preprocessing=None,
|
|
725
|
+
):
|
|
726
|
+
"""
|
|
727
|
+
Submit artifacts to Polyswarm Sandboxing system.
|
|
728
|
+
|
|
729
|
+
:param artifact: A file-like, path to file, url or LocalArtifact instance
|
|
730
|
+
:param artifact_name: An appropriate filename for the Artifact
|
|
731
|
+
:artifact_type: the type of artifact to be submitted, default FILE. Use URL type
|
|
732
|
+
with the preprocessing field to scan URLs inside QR Code images
|
|
733
|
+
:param network_enabled: Whether the VM has to have Internet connection enabled or not.
|
|
734
|
+
:param provider_slug: the slug of the provider that is going to execute the sandboxing, e.g.
|
|
735
|
+
'cape' or 'triage'.
|
|
736
|
+
Use `sandbox_providers()` to get the list of providers.
|
|
737
|
+
:param vm_slug: The slug of the virtual machine used for the sandboxing, depending on the
|
|
738
|
+
VM chosen is the OS and software that is going to host the sandboxing. Each
|
|
739
|
+
provider (provider_slug) support different VMs, so check with `sandbox_providers()`
|
|
740
|
+
the list of VMs available.
|
|
741
|
+
:param preprocessing: Preprocessing settings to be applied to the artifact, None means no preprocessing,
|
|
742
|
+
otherwise a dict with the following attributes can be passed:
|
|
743
|
+
- type (string): either "zip" or "qrcode", the first mean the file is a zip that
|
|
744
|
+
the server has to decompress to then scan the content (only one file inside allowed).
|
|
745
|
+
"qrcode" means the file is a QR Code image with a URL as payload, and you want
|
|
746
|
+
to scan the URL, not the actual file (artifact_type has to be "URL").
|
|
747
|
+
- password (string, optional): will use this password to decompress the zip file.
|
|
748
|
+
:return: An ArtifactInstance resource
|
|
749
|
+
"""
|
|
750
|
+
logger.info('Sandboxing %s in provider %s vm %s', artifact_type.name.lower(), provider_slug, vm_slug)
|
|
695
751
|
artifact_type = resources.ArtifactType.parse(artifact_type)
|
|
696
|
-
|
|
697
|
-
# to isinstance(artifact, io.IOBase) when deprecating 2.7 and implementing making LocalHandle
|
|
698
|
-
# inherit io.IOBase, although this will change the method delegation logic in the resource
|
|
699
|
-
if hasattr(artifact, 'read') and hasattr(artifact.read, '__call__'):
|
|
752
|
+
if isinstance(artifact, io.IOBase):
|
|
700
753
|
artifact = resources.LocalArtifact.from_handle(self, artifact, artifact_name=artifact_name or '',
|
|
701
754
|
artifact_type=artifact_type)
|
|
702
755
|
elif isinstance(artifact, str):
|
|
@@ -708,29 +761,84 @@ class PolyswarmAPI:
|
|
|
708
761
|
artifact_name=artifact_name or artifact,
|
|
709
762
|
artifact_type=artifact_type)
|
|
710
763
|
if isinstance(artifact, resources.LocalArtifact):
|
|
711
|
-
task = resources.SandboxTask.create_file(
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
764
|
+
task = resources.SandboxTask.create_file(
|
|
765
|
+
self,
|
|
766
|
+
artifact_name=artifact.artifact_name,
|
|
767
|
+
artifact_type=artifact.artifact_type.name,
|
|
768
|
+
community=self.community,
|
|
769
|
+
provider_slug=provider_slug,
|
|
770
|
+
vm_slug=vm_slug,
|
|
771
|
+
network_enabled=network_enabled,
|
|
772
|
+
preprocessing=preprocessing,
|
|
773
|
+
).result()
|
|
718
774
|
task.upload_file(artifact)
|
|
719
775
|
return resources.SandboxTask.update_file(self, id=task.id, community=self.community).result()
|
|
720
776
|
else:
|
|
721
777
|
raise exceptions.InvalidValueException(
|
|
722
778
|
'Artifacts should be a path to a file or a LocalArtifact instance')
|
|
723
779
|
|
|
724
|
-
def sandbox_url(self,
|
|
780
|
+
def sandbox_url(self,
|
|
781
|
+
url,
|
|
782
|
+
provider_slug,
|
|
783
|
+
vm_slug,
|
|
784
|
+
browser=None,
|
|
785
|
+
artifact=None,
|
|
786
|
+
artifact_name=None,
|
|
787
|
+
preprocessing=None):
|
|
788
|
+
"""
|
|
789
|
+
Submit URL to Polyswarm Sandboxing system.
|
|
790
|
+
:param url: A string with the URL to be submitted. Set to `None` if the URL is provided
|
|
791
|
+
through a QR Code image in the artifact param (see artifact and preprocessing params).
|
|
792
|
+
:param provider_slug: the slug of the provider that is going to execute the sandboxing, e.g.
|
|
793
|
+
'cape' or 'triage'.
|
|
794
|
+
Use `sandbox_providers()` to get the list of providers.
|
|
795
|
+
:param vm_slug: The slug of the virtual machine used for the sandboxing, depending on the
|
|
796
|
+
VM chosen is the OS and software that is going to host the sandboxing. Each
|
|
797
|
+
provider (provider_slug) support different VMs, so check with `sandbox_providers()`
|
|
798
|
+
the list of VMs available.
|
|
799
|
+
:param browser: browser name, e.g. 'edge' or 'firefox'.
|
|
800
|
+
:param artifact: A file-like, path to file, or LocalArtifact instance (default None). The url
|
|
801
|
+
param has to be None to use this param. For now QR Code image files
|
|
802
|
+
are supported
|
|
803
|
+
:param artifact_name: name of the artifact, if None (default) the URL string is used as a name,
|
|
804
|
+
or the file name if artifact is provided (QR Code image file).
|
|
805
|
+
:param preprocessing: Preprocessing settings to be applied to the artifact, None means no preprocessing,
|
|
806
|
+
otherwise a dict with the following attributes can be passed:
|
|
807
|
+
- type (string): only "qrcode" is supported for URL sandboxing:
|
|
808
|
+
the file is a QR Code image with a URL as payload, and you want
|
|
809
|
+
to scan the URL, not the actual file. This argument has to be used with the
|
|
810
|
+
`artifact` param, and `url` set to `None`.
|
|
811
|
+
"""
|
|
725
812
|
logger.info('Sandboxing url in provider %s vm %s', provider_slug, vm_slug)
|
|
726
|
-
artifact
|
|
813
|
+
if artifact and url:
|
|
814
|
+
raise exceptions.InvalidValueException("Cannot use artifact with url param")
|
|
815
|
+
if artifact:
|
|
816
|
+
if not preprocessing or preprocessing.get('type') != 'qrcode':
|
|
817
|
+
raise exceptions.InvalidValueException("Only artifact of type qrcode is supported")
|
|
818
|
+
if isinstance(artifact, str):
|
|
819
|
+
artifact = resources.LocalArtifact.from_path(self,
|
|
820
|
+
artifact,
|
|
821
|
+
artifact_type='URL',
|
|
822
|
+
artifact_name=artifact_name)
|
|
823
|
+
else:
|
|
824
|
+
artifact = resources.LocalArtifact.from_handle(self,
|
|
825
|
+
artifact,
|
|
826
|
+
artifact_name=artifact_name or '',
|
|
827
|
+
artifact_type='URL')
|
|
828
|
+
else:
|
|
829
|
+
artifact_name = url
|
|
830
|
+
artifact = resources.LocalArtifact.from_content(self,
|
|
831
|
+
url,
|
|
832
|
+
artifact_name=artifact_name,
|
|
833
|
+
artifact_type='URL')
|
|
727
834
|
task = resources.SandboxTask.create_file(self,
|
|
728
|
-
artifact_name=
|
|
835
|
+
artifact_name=artifact_name,
|
|
729
836
|
artifact_type="URL",
|
|
730
837
|
community=self.community,
|
|
731
838
|
provider_slug=provider_slug,
|
|
732
839
|
vm_slug=vm_slug,
|
|
733
840
|
browser=browser,
|
|
841
|
+
preprocessing=preprocessing,
|
|
734
842
|
network_enabled=True).result()
|
|
735
843
|
task.upload_file(artifact)
|
|
736
844
|
return resources.SandboxTask.update_file(self, id=task.id, community=self.community).result()
|
|
@@ -823,18 +931,62 @@ class PolyswarmAPI:
|
|
|
823
931
|
logger.info('List events')
|
|
824
932
|
return resources.Events.list(self, **kwargs).result()
|
|
825
933
|
|
|
826
|
-
def report_create(self,
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
934
|
+
def report_create(self,
|
|
935
|
+
type,
|
|
936
|
+
format,
|
|
937
|
+
instance_id=None,
|
|
938
|
+
sandbox_task_id=None,
|
|
939
|
+
template_id=None,
|
|
940
|
+
template_metadata=None,
|
|
941
|
+
**kwargs):
|
|
942
|
+
"""
|
|
943
|
+
Create a report, either 'pdf' or 'html' (format argument).
|
|
944
|
+
Regarding the type argument, either instance_id (type='scan')
|
|
945
|
+
or sandbox_task_id (type='sandbox') has to be provided.
|
|
946
|
+
"""
|
|
947
|
+
report = resources.ReportTask.create(self,
|
|
948
|
+
type=type,
|
|
949
|
+
format=format,
|
|
950
|
+
instance_id=instance_id,
|
|
951
|
+
sandbox_task_id=sandbox_task_id,
|
|
952
|
+
template_id=template_id,
|
|
953
|
+
template_metadata=template_metadata,
|
|
954
|
+
**kwargs).result()
|
|
955
|
+
return report
|
|
956
|
+
|
|
957
|
+
def report_get(self, id, **kwargs):
|
|
958
|
+
return resources.ReportTask.get(self, id=id, **kwargs).result()
|
|
831
959
|
|
|
832
960
|
def report_download(self, report_id, folder):
|
|
833
961
|
report = resources.ReportTask.get(self, id=report_id).result()
|
|
962
|
+
if report.state == 'PENDING':
|
|
963
|
+
raise exceptions.InvalidValueException('Report is in PENDING state, wait for completion first')
|
|
964
|
+
if report.state == 'FAILED':
|
|
965
|
+
raise exceptions.InvalidValueException("Report is in FAILED state, won't be generated")
|
|
834
966
|
result = report.download_report(folder=folder).result()
|
|
835
967
|
result.handle.close()
|
|
836
968
|
return result
|
|
837
969
|
|
|
970
|
+
def report_wait_for(self, report_id, timeout=settings.DEFAULT_REPORT_TIMEOUT):
|
|
971
|
+
"""
|
|
972
|
+
Wait for a Report to finish successfully.
|
|
973
|
+
|
|
974
|
+
:param report_id: Report id to wait for
|
|
975
|
+
:param timeout: Maximum time in seconds to wait before raising a TimeoutException
|
|
976
|
+
:return: The ReportTask resource waited on, either in 'SUCCEEDED' or 'FAILED' state
|
|
977
|
+
"""
|
|
978
|
+
logger.info('Waiting for report %s', report_id)
|
|
979
|
+
start = time.time()
|
|
980
|
+
while True:
|
|
981
|
+
report_result = self.report_get(id=report_id)
|
|
982
|
+
if report_result.state != 'PENDING':
|
|
983
|
+
return report_result
|
|
984
|
+
elif -1 < timeout < time.time() - start:
|
|
985
|
+
raise exceptions.TimeoutException(
|
|
986
|
+
f'Timed out waiting for report {report_id} to finish. Please try again.')
|
|
987
|
+
else:
|
|
988
|
+
time.sleep(settings.POLL_FREQUENCY)
|
|
989
|
+
|
|
838
990
|
def report_template_logo_download(self, template_id, folder):
|
|
839
991
|
report = resources.ReportTemplate.get(self, id=template_id).result()
|
|
840
992
|
result = report.download_logo(folder).result()
|
|
@@ -851,11 +1003,50 @@ class PolyswarmAPI:
|
|
|
851
1003
|
result = report.upload_logo(logo_file, content_tpe).result()
|
|
852
1004
|
return result
|
|
853
1005
|
|
|
854
|
-
def report_template_create(self,
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
1006
|
+
def report_template_create(self,
|
|
1007
|
+
template_name,
|
|
1008
|
+
is_default=False,
|
|
1009
|
+
primary_color=None,
|
|
1010
|
+
footer_text=None,
|
|
1011
|
+
last_page_text=None,
|
|
1012
|
+
includes=None,
|
|
1013
|
+
**kwargs):
|
|
1014
|
+
"""
|
|
1015
|
+
Create a template for reports.
|
|
1016
|
+
A team account can have multiple templates, and setting is_default=True
|
|
1017
|
+
makes it the default when a report is created without specifying template_id
|
|
1018
|
+
(see report_create method).
|
|
1019
|
+
The includes argument can be a list with sections to be included
|
|
1020
|
+
in the reports. The list can include any of the following section names:
|
|
1021
|
+
summary, detections, fileMetadata, network, droppedFiles, extractedConfig, analysis.
|
|
1022
|
+
"""
|
|
1023
|
+
return resources.ReportTemplate.create(self,
|
|
1024
|
+
template_name=template_name,
|
|
1025
|
+
is_default=is_default,
|
|
1026
|
+
primary_color=primary_color,
|
|
1027
|
+
footer_text=footer_text,
|
|
1028
|
+
last_page_text=last_page_text,
|
|
1029
|
+
includes=includes,
|
|
1030
|
+
**kwargs).result()
|
|
1031
|
+
|
|
1032
|
+
def report_template_update(self,
|
|
1033
|
+
template_id,
|
|
1034
|
+
template_name=None,
|
|
1035
|
+
is_default=None,
|
|
1036
|
+
primary_color=None,
|
|
1037
|
+
footer_text=None,
|
|
1038
|
+
last_page_text=None,
|
|
1039
|
+
includes=None,
|
|
1040
|
+
**kwargs):
|
|
1041
|
+
return resources.ReportTemplate.update(self,
|
|
1042
|
+
id=template_id,
|
|
1043
|
+
template_name=template_name,
|
|
1044
|
+
is_default=is_default,
|
|
1045
|
+
primary_color=primary_color,
|
|
1046
|
+
footer_text=footer_text,
|
|
1047
|
+
last_page_text=last_page_text,
|
|
1048
|
+
includes=includes,
|
|
1049
|
+
**kwargs).result()
|
|
859
1050
|
|
|
860
1051
|
def report_template_get(self, template_id):
|
|
861
1052
|
return resources.ReportTemplate.get(self, id=template_id).result()
|
|
@@ -863,8 +1054,11 @@ class PolyswarmAPI:
|
|
|
863
1054
|
def report_template_delete(self, template_id):
|
|
864
1055
|
return resources.ReportTemplate.delete(self, id=template_id).result()
|
|
865
1056
|
|
|
866
|
-
def report_template_list(self, is_default=None):
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
return resources.
|
|
1057
|
+
def report_template_list(self, is_default=None, **kwargs):
|
|
1058
|
+
return resources.ReportTemplate.list(self, is_default=is_default, **kwargs).result()
|
|
1059
|
+
|
|
1060
|
+
def account_whois(self, **kwargs):
|
|
1061
|
+
return resources.WhoIs.get(self, **kwargs).result()
|
|
1062
|
+
|
|
1063
|
+
def account_features(self, **kwargs):
|
|
1064
|
+
return resources.AccountFeatures.get(self, **kwargs).result()
|
|
@@ -1019,6 +1019,8 @@ class SandboxTask(core.BaseJsonResource):
|
|
|
1019
1019
|
self.sha256 = content['sha256']
|
|
1020
1020
|
self.report = content['report']
|
|
1021
1021
|
self.upload_url = content['upload_url']
|
|
1022
|
+
self.config = content['config']
|
|
1023
|
+
self.artifact = content['artifact']
|
|
1022
1024
|
self.sandbox_artifacts = [SandboxArtifact(a, api=api) for a in content.get('sandbox_artifacts', [])]
|
|
1023
1025
|
|
|
1024
1026
|
def upload_file(self, artifact, attempts=3, **kwargs):
|
|
@@ -1203,3 +1205,48 @@ class ReportTemplate(core.BaseJsonResource):
|
|
|
1203
1205
|
},
|
|
1204
1206
|
result_parser=self.__class__
|
|
1205
1207
|
).execute()
|
|
1208
|
+
|
|
1209
|
+
|
|
1210
|
+
class AccountFeatures(core.BaseJsonResource):
|
|
1211
|
+
RESOURCE_ENDPOINT = "/public/accounts"
|
|
1212
|
+
|
|
1213
|
+
def __init__(self, content, api=None):
|
|
1214
|
+
super().__init__(content, api=api)
|
|
1215
|
+
self.account_number = content['account_number']
|
|
1216
|
+
self.user_account_number = content.get('user_account_number')
|
|
1217
|
+
self.account_plan_name = content['account_plan_name']
|
|
1218
|
+
self.plan_period_start = content['plan_period_start']
|
|
1219
|
+
self.plan_period_end = content['plan_period_end']
|
|
1220
|
+
self.window_start = content['window_start']
|
|
1221
|
+
self.window_end = content['window_end']
|
|
1222
|
+
self.tenant = content.get('tenant')
|
|
1223
|
+
self.daily_api_limit = content['daily_api_limit']
|
|
1224
|
+
self.daily_api_remaining = content['daily_api_remaining']
|
|
1225
|
+
self.has_stream_access = content['has_stream_access']
|
|
1226
|
+
self.is_trial = content['is_trial']
|
|
1227
|
+
self.is_trial_expired = content['is_trial_expired']
|
|
1228
|
+
self.trial_started_at = content['trial_started_at']
|
|
1229
|
+
self.trial_ended_at = content['trial_ended_at']
|
|
1230
|
+
self.features = []
|
|
1231
|
+
for feature in content['features']:
|
|
1232
|
+
self.features.append({
|
|
1233
|
+
'base_uses': feature['base_uses'],
|
|
1234
|
+
'name': feature['name'],
|
|
1235
|
+
'overage': feature['overage'],
|
|
1236
|
+
'remaining_uses': feature['remaining_uses'],
|
|
1237
|
+
'tag': feature['tag'],
|
|
1238
|
+
'value': feature['value'],
|
|
1239
|
+
})
|
|
1240
|
+
|
|
1241
|
+
|
|
1242
|
+
class WhoIs(core.BaseJsonResource):
|
|
1243
|
+
RESOURCE_ENDPOINT = "/public/accounts/whois"
|
|
1244
|
+
|
|
1245
|
+
def __init__(self, content, api=None):
|
|
1246
|
+
super().__init__(content, api=api)
|
|
1247
|
+
self.account_number = content['account_number']
|
|
1248
|
+
self.user_account_number = content.get('user_account_number')
|
|
1249
|
+
self.account_name = content['account_name']
|
|
1250
|
+
self.account_type = content['account_type']
|
|
1251
|
+
self.communities = content['communities']
|
|
1252
|
+
self.tenant = content.get('tenant')
|
|
@@ -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
|