polyswarm-api 4.4.0__tar.gz → 4.5.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.
Files changed (20) hide show
  1. {polyswarm_api-4.4.0/src/polyswarm_api.egg-info → polyswarm_api-4.5.0}/PKG-INFO +1 -1
  2. {polyswarm_api-4.4.0 → polyswarm_api-4.5.0}/pyproject.toml +2 -2
  3. {polyswarm_api-4.4.0 → polyswarm_api-4.5.0}/src/polyswarm_api/__init__.py +1 -1
  4. {polyswarm_api-4.4.0 → polyswarm_api-4.5.0}/src/polyswarm_api/aio/api.py +39 -2
  5. {polyswarm_api-4.4.0 → polyswarm_api-4.5.0}/src/polyswarm_api/api.py +43 -1
  6. {polyswarm_api-4.4.0 → polyswarm_api-4.5.0}/src/polyswarm_api/resources.py +10 -0
  7. {polyswarm_api-4.4.0 → polyswarm_api-4.5.0/src/polyswarm_api.egg-info}/PKG-INFO +1 -1
  8. {polyswarm_api-4.4.0 → polyswarm_api-4.5.0}/LICENSE +0 -0
  9. {polyswarm_api-4.4.0 → polyswarm_api-4.5.0}/README.md +0 -0
  10. {polyswarm_api-4.4.0 → polyswarm_api-4.5.0}/setup.cfg +0 -0
  11. {polyswarm_api-4.4.0 → polyswarm_api-4.5.0}/src/polyswarm_api/aio/__init__.py +0 -0
  12. {polyswarm_api-4.4.0 → polyswarm_api-4.5.0}/src/polyswarm_api/aio/session.py +0 -0
  13. {polyswarm_api-4.4.0 → polyswarm_api-4.5.0}/src/polyswarm_api/core.py +0 -0
  14. {polyswarm_api-4.4.0 → polyswarm_api-4.5.0}/src/polyswarm_api/exceptions.py +0 -0
  15. {polyswarm_api-4.4.0 → polyswarm_api-4.5.0}/src/polyswarm_api/session.py +0 -0
  16. {polyswarm_api-4.4.0 → polyswarm_api-4.5.0}/src/polyswarm_api/settings.py +0 -0
  17. {polyswarm_api-4.4.0 → polyswarm_api-4.5.0}/src/polyswarm_api.egg-info/SOURCES.txt +0 -0
  18. {polyswarm_api-4.4.0 → polyswarm_api-4.5.0}/src/polyswarm_api.egg-info/dependency_links.txt +0 -0
  19. {polyswarm_api-4.4.0 → polyswarm_api-4.5.0}/src/polyswarm_api.egg-info/requires.txt +0 -0
  20. {polyswarm_api-4.4.0 → polyswarm_api-4.5.0}/src/polyswarm_api.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: polyswarm_api
3
- Version: 4.4.0
3
+ Version: 4.5.0
4
4
  Summary: Client library to simplify interacting with the PolySwarm consumer API
5
5
  Author-email: PolySwarm Developers <info@polyswarm.io>
6
6
  License: MIT
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "polyswarm_api"
7
- version = "4.4.0"
7
+ version = "4.5.0"
8
8
  description = "Client library to simplify interacting with the PolySwarm consumer API"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10,<4"
@@ -55,7 +55,7 @@ package-dir = { "" = "src" }
55
55
  where = ["src"]
56
56
 
57
57
  [tool.bumpversion]
58
- current_version = "4.4.0"
58
+ current_version = "4.5.0"
59
59
  commit = true
60
60
  tag = false
61
61
  sign_tags = true
@@ -1,5 +1,5 @@
1
1
  # https://www.python.org/dev/peps/pep-0008/#module-level-dunder-names
2
- __version__ = '4.4.0'
2
+ __version__ = '4.5.0'
3
3
  __release_url__ = 'https://api.github.com/repos/polyswarm/polyswarm-api/releases/latest'
4
4
 
5
5
  from . import api
@@ -697,7 +697,8 @@ class PolySwarmAsyncAPI:
697
697
  return await self._single(resources.YaraRuleset.delete(self, id=ruleset_id, community=self.community))
698
698
 
699
699
  async def ruleset_list(self, name=None, status=None, favorites_only=None,
700
- has_new_results=None):
700
+ has_new_results=None, sort=None,
701
+ exclude_favorites=None):
701
702
  """
702
703
  List all YaraRulesets for the current account.
703
704
 
@@ -706,17 +707,53 @@ class PolySwarmAsyncAPI:
706
707
  :param status: 'active' returns only rulesets whose live hunt is
707
708
  currently running.
708
709
  :param favorites_only: True returns only favorited rulesets.
710
+ :param exclude_favorites: True returns only the rulesets that are NOT
711
+ favorited — the inverse of ``favorites_only``, and refused together
712
+ with it (a contradiction, answered with an error rather than an
713
+ empty list). It exists for clients that render the favorites as
714
+ their own list: the favorites are a separate, unpaginated fetch
715
+ bounded by the account's budget, so leaving them in the paginated
716
+ list too makes a page either repeat a row or come back short.
717
+ Appended to the signature rather than placed beside
718
+ ``favorites_only`` so a positional caller keeps working.
709
719
  :param has_new_results: True returns only rulesets whose stored
710
720
  new-results counter is positive. The counter (and its window) is
711
721
  maintained server-side by a scheduled refresh; rows carry it as
712
722
  ``new_results_count`` with ``new_results_counted_at`` marking when
713
723
  it was last refreshed. There is no per-request window parameter.
724
+ :param sort: ``'active_first'`` returns the rulesets that carry a live
725
+ hunt link first, newest first within each block. Default (None) is
726
+ newest first. "Newest first" is the server's own insertion key, NOT
727
+ the ``id`` on the rows you get back — that one is unique but
728
+ unordered, so dedupe with it and never resume or bound a walk with
729
+ it. Applied SERVER-side, across pages — the list is
730
+ keyset-paginated, so a client-side sort would only ever reorder one
731
+ page; the SDK never re-orders rows. Reuse a page's ``offset`` only
732
+ with the same ``sort``: the server refuses a cursor minted under
733
+ the other order.
734
+
735
+ Two server-side properties of that key, neither of them SDK
736
+ behaviour. It ranks on the stored link, which is a WIDER predicate
737
+ than the one ``livescan_id`` is rendered under: a legacy row whose
738
+ hunt was stopped without clearing the link ranks in the leading
739
+ block while still serializing ``livescan_id`` as ``None``. Read the
740
+ field to decide whether a ruleset is running; never the position.
741
+
742
+ And the key is MUTABLE, unlike that default: a ruleset whose
743
+ live hunt stops mid-walk falls back into the idle block below the
744
+ cursor and is yielded twice, and one started mid-walk moves above
745
+ the cursor and is skipped for the rest of that walk. That is a
746
+ property of the walk, so starting fresh from the first page does
747
+ not avoid it. This generator streams pages and does not dedupe —
748
+ dedupe by ``id`` if you consume more than one page.
714
749
  :return: A generator of YaraRuleset resources
715
750
  """
716
751
  logger.info('List rulesets')
717
752
  async for item in self._paginate(resources.YaraRuleset.list(
718
753
  self, name=name, status=status, favorites_only=favorites_only,
719
- has_new_results=has_new_results, community=self.community)):
754
+ has_new_results=has_new_results, sort=sort,
755
+ exclude_favorites=exclude_favorites,
756
+ community=self.community)):
720
757
  yield item
721
758
 
722
759
  async def ruleset_favorite(self, ruleset_id, favorite=True):
@@ -837,7 +837,13 @@ class PolyswarmAPI:
837
837
  )
838
838
 
839
839
  def ruleset_list(
840
- self, name=None, status=None, favorites_only=None, has_new_results=None
840
+ self,
841
+ name=None,
842
+ status=None,
843
+ favorites_only=None,
844
+ has_new_results=None,
845
+ sort=None,
846
+ exclude_favorites=None,
841
847
  ):
842
848
  """
843
849
  List all YaraRulesets for the current account.
@@ -847,11 +853,45 @@ class PolyswarmAPI:
847
853
  :param status: 'active' returns only rulesets whose live hunt is
848
854
  currently running.
849
855
  :param favorites_only: True returns only favorited rulesets.
856
+ :param exclude_favorites: True returns only the rulesets that are NOT
857
+ favorited — the inverse of ``favorites_only``, and refused together
858
+ with it (a contradiction, answered with an error rather than an
859
+ empty list). It exists for clients that render the favorites as
860
+ their own list: the favorites are a separate, unpaginated fetch
861
+ bounded by the account's budget, so leaving them in the paginated
862
+ list too makes a page either repeat a row or come back short.
863
+ Appended to the signature rather than placed beside
864
+ ``favorites_only`` so a positional caller keeps working.
850
865
  :param has_new_results: True returns only rulesets whose stored
851
866
  new-results counter is positive. The counter (and its window) is
852
867
  maintained server-side by a scheduled refresh; rows carry it as
853
868
  ``new_results_count`` with ``new_results_counted_at`` marking when
854
869
  it was last refreshed. There is no per-request window parameter.
870
+ :param sort: ``'active_first'`` returns the rulesets that carry a live
871
+ hunt link first, newest first within each block. Default (None) is
872
+ newest first. "Newest first" is the server's own insertion key, NOT
873
+ the ``id`` on the rows you get back — that one is unique but
874
+ unordered, so dedupe with it and never resume or bound a walk with
875
+ it. Applied SERVER-side, across pages — the list is
876
+ keyset-paginated, so a client-side sort would only ever reorder one
877
+ page; the SDK never re-orders rows. Reuse a page's ``offset`` only
878
+ with the same ``sort``: the server refuses a cursor minted under
879
+ the other order.
880
+
881
+ Two server-side properties of that key, neither of them SDK
882
+ behaviour. It ranks on the stored link, which is a WIDER predicate
883
+ than the one ``livescan_id`` is rendered under: a legacy row whose
884
+ hunt was stopped without clearing the link ranks in the leading
885
+ block while still serializing ``livescan_id`` as ``None``. Read the
886
+ field to decide whether a ruleset is running; never the position.
887
+
888
+ And the key is MUTABLE, unlike that default: a ruleset whose
889
+ live hunt stops mid-walk falls back into the idle block below the
890
+ cursor and is yielded twice, and one started mid-walk moves above
891
+ the cursor and is skipped for the rest of that walk. That is a
892
+ property of the walk, so starting fresh from the first page does
893
+ not avoid it. This generator streams pages and does not dedupe —
894
+ dedupe by ``id`` if you consume more than one page.
855
895
  :return: A generator of YaraRuleset resources
856
896
  """
857
897
  logger.info("List rulesets")
@@ -862,6 +902,8 @@ class PolyswarmAPI:
862
902
  status=status,
863
903
  favorites_only=favorites_only,
864
904
  has_new_results=has_new_results,
905
+ sort=sort,
906
+ exclude_favorites=exclude_favorites,
865
907
  community=self.community,
866
908
  )
867
909
  ):
@@ -805,6 +805,11 @@ class LiveHuntResult(core.BaseJsonResource):
805
805
  self.sha1 = content.get('sha1')
806
806
  self.rule_name = content['rule_name']
807
807
  self.tags = content['tags']
808
+ # `.get()`, not a subscript -- both keys are additive, so an older server omits
809
+ # them. None is AMBIGUOUS on both (four causes) and is never a claim that the
810
+ # evidence is complete. Contract: specs/05-downstream-contract.md.
811
+ self.matched_strings = content.get('matched_strings')
812
+ self.matched_strings_dropped = content.get('matched_strings_dropped')
808
813
  self.polyscore = content['polyscore']
809
814
  self.malware_family = content['malware_family']
810
815
  self.detections = content['detections']
@@ -863,6 +868,11 @@ class HistoricalHuntResult(core.BaseJsonResource):
863
868
  self.created = core.parse_isoformat(content['created'])
864
869
  self.rule_name = content['rule_name']
865
870
  self.tags = content['tags']
871
+ # `.get()`, not a subscript -- both keys are additive, so an older server omits
872
+ # them. None is AMBIGUOUS on both (four causes) and is never a claim that the
873
+ # evidence is complete. Contract: specs/05-downstream-contract.md.
874
+ self.matched_strings = content.get('matched_strings')
875
+ self.matched_strings_dropped = content.get('matched_strings_dropped')
866
876
  self.polyscore = content['polyscore']
867
877
  self.malware_family = content['malware_family']
868
878
  self.detections = content['detections']
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: polyswarm_api
3
- Version: 4.4.0
3
+ Version: 4.5.0
4
4
  Summary: Client library to simplify interacting with the PolySwarm consumer API
5
5
  Author-email: PolySwarm Developers <info@polyswarm.io>
6
6
  License: MIT
File without changes
File without changes
File without changes