Skip to content

Commit 0ad8966

Browse files
committed
update rules create pattern
1 parent de9221f commit 0ad8966

3 files changed

Lines changed: 85 additions & 116 deletions

File tree

python/lib/sift_client/_internal/low_level_wrappers/rules.py

Lines changed: 16 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
ArchiveRuleRequest,
88
BatchArchiveRulesRequest,
99
BatchGetRulesRequest,
10-
BatchGetRulesResponse,
1110
BatchUnarchiveRulesRequest,
1211
BatchUpdateRulesRequest,
1312
BatchUpdateRulesResponse,
@@ -33,7 +32,7 @@
3332
from sift_client._internal.low_level_wrappers.base import LowLevelClientBase
3433
from sift_client.sift_types.rule import (
3534
Rule,
36-
RuleAction,
35+
RuleCreate,
3736
RuleUpdate,
3837
)
3938
from sift_client.transport import GrpcClient, WithGrpcClient
@@ -109,66 +108,50 @@ async def batch_get_rules(
109108

110109
request = BatchGetRulesRequest(**request_kwargs)
111110
response = await self._grpc_client.get_stub(RuleServiceStub).BatchGetRules(request)
112-
response = cast("BatchGetRulesResponse", response)
113111
return [Rule._from_proto(rule) for rule in response.rules]
114112

115113
async def create_rule(
116114
self,
117115
*,
118-
name: str,
119-
description: str,
120-
organization_id: str | None = None,
121-
client_key: str | None = None,
122-
asset_ids: list[str] | None = None,
123-
tag_ids: list[str] | None = None,
124-
contextual_channels: list[str] | None = None,
125-
is_external: bool,
126-
expression: str,
127-
channel_references: list[ChannelReference],
128-
action: RuleAction,
116+
create: RuleCreate,
129117
) -> Rule:
130118
"""Create a new rule.
131119
132120
Args:
133-
name: The name of the rule.
134-
description: The description of the rule.
135-
organization_id: The organization ID of the rule.
136-
client_key: The client key of the rule.
137-
asset_ids: The asset IDs of the rule.
138-
contextual_channels: Optional contextual channels of the rule.
121+
create: The RuleCreate model with the rule configuration.
139122
140123
Returns:
141-
The rule ID of the created rule.
124+
The created Rule.
142125
"""
143126
# Convert rule to UpdateRuleRequest
144127
expression_proto = RuleConditionExpression(
145128
calculated_channel=CalculatedChannelConfig(
146-
expression=expression,
129+
expression=create.expression,
147130
channel_references={
148131
c.channel_reference: ChannelReferenceProto(name=c.channel_identifier)
149-
for c in channel_references
132+
for c in create.channel_references
150133
},
151134
)
152135
)
153136
conditions_request = [
154137
UpdateConditionRequest(
155-
expression=expression_proto, actions=[action._to_update_request()]
138+
expression=expression_proto, actions=[create.action._to_update_request()]
156139
)
157140
]
158141
update_request = UpdateRuleRequest(
159-
name=name,
160-
description=description,
142+
name=create.name,
143+
description=create.description,
161144
is_enabled=True,
162-
organization_id=organization_id or "",
163-
client_key=client_key,
164-
is_external=is_external,
145+
organization_id=create.organization_id or "",
146+
client_key=create.client_key,
147+
is_external=create.is_external,
165148
conditions=conditions_request,
166149
asset_configuration=RuleAssetConfiguration(
167-
asset_ids=asset_ids or [],
168-
tag_ids=tag_ids or [],
150+
asset_ids=create.asset_ids or [],
151+
tag_ids=create.asset_tag_ids or [],
169152
),
170153
contextual_channels=ContextualChannels(
171-
channels=[ChannelReferenceProto(name=c) for c in contextual_channels or []]
154+
channels=[ChannelReferenceProto(name=c) for c in create.contextual_channels or []]
172155
), # type: ignore
173156
)
174157

@@ -177,7 +160,7 @@ async def create_rule(
177160
"CreateRuleResponse",
178161
await self._grpc_client.get_stub(RuleServiceStub).CreateRule(request),
179162
)
180-
return await self.get_rule(rule_id=created_rule.rule_id, client_key=client_key)
163+
return await self.get_rule(rule_id=created_rule.rule_id, client_key=create.client_key)
181164

182165
def _update_rule_request_from_update(
183166
self, rule: Rule, update: RuleUpdate, version_notes: str | None = None

python/lib/sift_client/resources/rules.py

Lines changed: 37 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,13 @@
44

55
from sift_client._internal.low_level_wrappers.rules import RulesLowLevelClient
66
from sift_client.resources._base import ResourceBase
7-
from sift_client.sift_types.rule import Rule, RuleAction, RuleUpdate
7+
from sift_client.sift_types.rule import Rule, RuleCreate, RuleUpdate
88
from sift_client.util import cel_utils as cel
99

1010
if TYPE_CHECKING:
1111
import re
1212

1313
from sift_client.client import SiftClient
14-
from sift_client.sift_types.channel import ChannelReference
1514

1615

1716
class RulesAPIAsync(ResourceBase):
@@ -124,34 +123,28 @@ async def find(self, **kwargs) -> Rule | None:
124123

125124
async def create(
126125
self,
127-
name: str,
128-
description: str,
129-
expression: str,
130-
channel_references: list[ChannelReference],
131-
action: RuleAction,
132-
organization_id: str | None = None,
133-
client_key: str | None = None,
134-
asset_ids: list[str] | None = None,
135-
contextual_channels: list[str] | None = None,
136-
is_external: bool = False,
126+
create: RuleCreate | dict,
137127
) -> Rule:
138-
"""Create a new rule."""
139-
created_rule = await self._low_level_client.create_rule(
140-
name=name,
141-
description=description,
142-
organization_id=organization_id,
143-
expression=expression,
144-
action=action,
145-
channel_references=channel_references,
146-
client_key=client_key,
147-
asset_ids=asset_ids,
148-
contextual_channels=contextual_channels,
149-
is_external=is_external,
150-
)
128+
"""Create a new rule.
129+
130+
Args:
131+
create: A RuleCreate object or dictionary with configuration for the new rule.
132+
133+
Returns:
134+
The created Rule.
135+
"""
136+
if isinstance(create, dict):
137+
create = RuleCreate.model_validate(create)
138+
139+
created_rule = await self._low_level_client.create_rule(create=create)
151140
return self._apply_client_to_instance(created_rule)
152141

153142
async def update(
154-
self, rule: str | Rule, update: RuleUpdate | dict, version_notes: str | None = None
143+
self,
144+
rule: Rule | str,
145+
update: RuleUpdate | dict,
146+
*,
147+
version_notes: str | None = None,
155148
) -> Rule:
156149
"""Update a Rule.
157150
@@ -172,63 +165,27 @@ async def update(
172165
updated_rule = await self._low_level_client.update_rule(rule, update, version_notes)
173166
return self._apply_client_to_instance(updated_rule)
174167

175-
async def archive(
176-
self,
177-
*,
178-
rule: str | Rule | None = None,
179-
client_key: str | None = None,
180-
rules: list[Rule] | None = None,
181-
rule_ids: list[str] | None = None,
182-
client_keys: list[str] | None = None,
183-
) -> None:
184-
"""Archive a rule or multiple.
168+
async def archive(self, rule: str | Rule) -> Rule:
169+
"""Archive a rule.
185170
186171
Args:
187-
rule: The Rule to archive.
188-
client_key: The client key or the Rule to archive.
189-
rules: The Rules to archive.
190-
rule_ids: The rule IDs to archive.
191-
client_keys: The client keys of the Rules tp archive.
172+
rule: The id or Rule object of the rule to archive.
173+
174+
Returns:
175+
The archived Rule.
192176
"""
193-
if rule or client_key:
194-
rule_id = rule._id_or_error if isinstance(rule, Rule) else rule
195-
return await self._low_level_client.archive_rule(rule_id=rule_id, client_key=client_key)
196-
elif rules or rule_ids or client_keys:
197-
rule_ids = rule_ids or [rule._id_or_error for rule in rules]
198-
return await self._low_level_client.batch_archive_rules(
199-
rule_ids=rule_ids, client_keys=client_keys
200-
)
201-
else:
202-
raise ValueError("Either rule or rules must be provided")
203-
204-
async def unarchive(
205-
self,
206-
*,
207-
rule: str | Rule | None = None,
208-
client_key: str | None = None,
209-
rules: list[Rule] | None = None,
210-
rule_ids: list[str] | None = None,
211-
client_keys: list[str] | None = None,
212-
) -> None:
213-
"""Unarchive a Rule or multiple.
214-
215-
Args:
216-
rule: The Rule to restore.
217-
client_key: The client key of the Rule to restore.
218-
rules: The Rules to restore.
219-
rule_ids: The rule IDs to restore.
220-
client_keys: The client keys of the Rules to restore.
221-
"""
222-
if rule or client_key:
223-
rule_id = rule._id_or_error if isinstance(rule, Rule) else rule
224-
return await self._low_level_client.unarchive_rule(rule_id=rule_id, client_key=client_key)
225-
elif rules or rule_ids or client_keys:
226-
rule_ids = rule_ids or [rule._id_or_error for rule in rules]
227-
return await self._low_level_client.batch_unarchive_rules(
228-
rule_ids=rule_ids, client_keys=client_keys
229-
)
230-
else:
231-
raise ValueError("Either rule or rules must be provided")
177+
return await self.update(rule=rule, update=RuleUpdate(is_archived=True))
178+
179+
async def unarchive(self, rule: str | Rule) -> Rule:
180+
"""Unarchive a rule.
181+
182+
Args:
183+
rule: The id or Rule object of the rule to unarchive.
184+
185+
Returns:
186+
The unarchived Rule.
187+
"""
188+
return await self.update(rule=rule, update=RuleUpdate(is_archived=False))
232189

233190

234191

python/lib/sift_client/sift_types/rule.py

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@
1515
ChannelReferencesEntry = CalculatedChannelConfig.ChannelReferencesEntry
1616
del CalculatedChannelConfig
1717

18+
from sift.rules.v1.rules_pb2 import (
19+
CreateRuleRequest,
20+
)
1821
from sift.rules.v1.rules_pb2 import (
1922
Rule as RuleProto,
2023
)
@@ -25,7 +28,7 @@
2528
RuleVersion as RuleVersionProto,
2629
)
2730

28-
from sift_client.sift_types._base import BaseType, ModelUpdate
31+
from sift_client.sift_types._base import BaseType, ModelCreate, ModelUpdate
2932
from sift_client.sift_types.channel import ChannelReference
3033

3134
if TYPE_CHECKING:
@@ -101,9 +104,11 @@ def update(self, update: RuleUpdate | dict, version_notes: str | None = None) ->
101104
self._update(updated_rule)
102105
return self
103106

104-
def archive(self) -> None:
107+
def archive(self) -> Rule:
105108
"""Archive the rule."""
106-
self.client.rules.archive(rule=self)
109+
updated_rule = self.client.rules.archive(rule=self)
110+
self._update(updated_rule)
111+
return self
107112

108113
@classmethod
109114
def _from_proto(cls, proto: RuleProto, sift_client: SiftClient | None = None) -> Rule:
@@ -145,6 +150,30 @@ def _from_proto(cls, proto: RuleProto, sift_client: SiftClient | None = None) ->
145150
)
146151

147152

153+
class RuleCreate(ModelCreate[CreateRuleRequest]):
154+
"""Model for creating a new Rule.
155+
156+
Note:
157+
- asset_ids applies this rule to those assets.
158+
- asset_tag_ids applies this rule to assets with those tags.
159+
"""
160+
161+
name: str
162+
description: str
163+
expression: str
164+
channel_references: list[ChannelReference]
165+
action: RuleAction
166+
organization_id: str | None = None
167+
client_key: str | None = None
168+
asset_ids: list[str] | None = None
169+
asset_tag_ids: list[str] | None = None
170+
contextual_channels: list[str] | None = None
171+
is_external: bool = False
172+
173+
def _get_proto_class(self) -> type[CreateRuleRequest]:
174+
return CreateRuleRequest
175+
176+
148177
class RuleUpdate(ModelUpdate[RuleProto]):
149178
"""Model of the Rule fields that can be updated.
150179

0 commit comments

Comments
 (0)