33import logging
44from typing import TYPE_CHECKING , Any , Sequence , cast
55
6- from sift .common .type .v1 .resource_identifier_pb2 import ResourceIdentifier , ResourceIdentifiers
6+ from sift .common .type .v1 .resource_identifier_pb2 import (
7+ NamedResources ,
8+ Names ,
9+ ResourceIdentifier ,
10+ ResourceIdentifiers ,
11+ )
712from sift .rule_evaluation .v1 .rule_evaluation_pb2 import (
813 AssetsTimeRange ,
14+ EvaluateRulesAnnotationOptions ,
15+ EvaluateRulesFromCurrentRuleVersions ,
16+ EvaluateRulesFromReportTemplate ,
17+ EvaluateRulesFromRuleVersions ,
918 EvaluateRulesRequest ,
1019 EvaluateRulesResponse ,
1120 RunTimeRange ,
1524 ArchiveRuleRequest ,
1625 BatchArchiveRulesRequest ,
1726 BatchGetRulesRequest ,
27+ BatchGetRuleVersionsRequest ,
28+ BatchGetRuleVersionsResponse ,
1829 BatchUnarchiveRulesRequest ,
1930 BatchUpdateRulesRequest ,
2031 BatchUpdateRulesResponse ,
2435 CreateRuleResponse ,
2536 GetRuleRequest ,
2637 GetRuleResponse ,
38+ GetRuleVersionRequest ,
39+ GetRuleVersionResponse ,
2740 ListRulesRequest ,
41+ ListRuleVersionsRequest ,
42+ ListRuleVersionsResponse ,
2843 RuleAssetConfiguration ,
2944 RuleConditionExpression ,
3045 UnarchiveRuleRequest ,
4560 Rule ,
4661 RuleCreate ,
4762 RuleUpdate ,
63+ RuleVersion ,
4864)
4965from sift_client .sift_types .tag import Tag
5066from sift_client .transport import GrpcClient , WithGrpcClient
@@ -506,6 +522,57 @@ async def list_all_rules(
506522 max_results = max_results ,
507523 )
508524
525+ async def list_rule_versions (
526+ self ,
527+ rule_id : str ,
528+ * ,
529+ filter_query : str | None = None ,
530+ order_by : str | None = None ,
531+ page_size : int | None = None ,
532+ page_token : str | None = None ,
533+ ) -> tuple [list [RuleVersion ], str ]:
534+ """List rule versions for a rule.
535+
536+ Args:
537+ rule_id: The rule ID to list versions for.
538+ filter_query: Optional CEL filter (fields: rule_version_id, user_notes, change_message).
539+ order_by: Unused, for _handle_pagination compatibility.
540+ page_size: Maximum number of versions per page.
541+ page_token: Token for the next page.
542+
543+ Returns:
544+ Tuple of (list of RuleVersions, next page token or empty string).
545+ """
546+ _ = order_by
547+ request_kwargs : dict [str , Any ] = {
548+ "rule_id" : rule_id ,
549+ "page_size" : page_size or DEFAULT_PAGE_SIZE ,
550+ "page_token" : page_token or "" ,
551+ }
552+ if filter_query :
553+ request_kwargs ["filter" ] = filter_query
554+ request = ListRuleVersionsRequest (** request_kwargs )
555+ response = await self ._grpc_client .get_stub (RuleServiceStub ).ListRuleVersions (request )
556+ response = cast ("ListRuleVersionsResponse" , response )
557+ versions = [RuleVersion ._from_proto (p ) for p in response .rule_versions ]
558+ return versions , response .next_page_token or ""
559+
560+ async def list_all_rule_versions (
561+ self ,
562+ rule_id : str ,
563+ * ,
564+ filter_query : str | None = None ,
565+ max_results : int | None = None ,
566+ page_size : int | None = DEFAULT_PAGE_SIZE ,
567+ ) -> list [RuleVersion ]:
568+ """List all rule versions for a rule, with optional CEL filter."""
569+ return await self ._handle_pagination (
570+ self .list_rule_versions ,
571+ kwargs = {"rule_id" : rule_id , "filter_query" : filter_query },
572+ page_size = page_size ,
573+ max_results = max_results ,
574+ )
575+
509576 async def evaluate_rules (
510577 self ,
511578 * ,
@@ -571,13 +638,22 @@ async def evaluate_rules(
571638 if all_applicable_rules :
572639 kwargs ["all_applicable_rules" ] = all_applicable_rules
573640 if rule_ids :
574- kwargs ["rules" ] = {"rules" : ResourceIdentifiers (ids = {"ids" : rule_ids })} # type: ignore
641+ kwargs ["rules" ] = EvaluateRulesFromCurrentRuleVersions (
642+ rules = ResourceIdentifiers (ids = {"ids" : rule_ids }) # type: ignore[arg-type]
643+ )
575644 if rule_version_ids :
576- kwargs ["rule_versions" ] = rule_version_ids
645+ kwargs ["rule_versions" ] = EvaluateRulesFromRuleVersions (
646+ rule_version_ids = rule_version_ids
647+ )
577648 if report_template_id :
578- kwargs ["report_template" ] = report_template_id
649+ kwargs ["report_template" ] = EvaluateRulesFromReportTemplate (
650+ report_template = ResourceIdentifier (id = report_template_id )
651+ )
579652 if tags :
580- kwargs ["tags" ] = [tag .name if isinstance (tag , Tag ) else tag for tag in tags ]
653+ tag_names = [tag .name if isinstance (tag , Tag ) else tag for tag in tags ]
654+ kwargs ["annotation_options" ] = EvaluateRulesAnnotationOptions (
655+ tags = NamedResources (names = Names (names = tag_names )) # type: ignore[arg-type]
656+ )
581657 if report_name :
582658 kwargs ["report_name" ] = report_name
583659 if organization_id :
@@ -595,3 +671,31 @@ async def evaluate_rules(
595671 report = await ReportsLowLevelClient (self ._grpc_client ).get_report (report_id = report_id )
596672 return created_annotation_count , report , job_id
597673 return created_annotation_count , None , job_id
674+
675+ async def get_rule_version (self , rule_version_id : str ) -> Rule :
676+ """Get a rule at a specific version by rule_version_id.
677+
678+ Args:
679+ rule_version_id: The rule version ID to get.
680+
681+ Returns:
682+ The Rule at that version.
683+ """
684+ request = GetRuleVersionRequest (rule_version_id = rule_version_id )
685+ response = await self ._grpc_client .get_stub (RuleServiceStub ).GetRuleVersion (request )
686+ grpc_rule = cast ("GetRuleVersionResponse" , response ).rule
687+ return Rule ._from_proto (grpc_rule )
688+
689+ async def batch_get_rule_versions (self , rule_version_ids : list [str ]) -> list [Rule ]:
690+ """Get multiple rules at specific versions by rule_version_ids.
691+
692+ Args:
693+ rule_version_ids: The rule version IDs to get.
694+
695+ Returns:
696+ List of Rules at those versions (order may match request order).
697+ """
698+ request = BatchGetRuleVersionsRequest (rule_version_ids = rule_version_ids )
699+ response = await self ._grpc_client .get_stub (RuleServiceStub ).BatchGetRuleVersions (request )
700+ response = cast ("BatchGetRuleVersionsResponse" , response )
701+ return [Rule ._from_proto (r ) for r in response .rules ]
0 commit comments