FazBrowse GitHub Viewer
|
Trending
|
URL:
|
Home
Tools:
[Download Repo ZIP]
[View Raw Code]
[Original HTTPS Page]
feast/sdk/python/feast/permissions/decision.py at pytorch-template · feast-dev/feast · GitHub
Uh oh!
There was an error while loading.
Please reload this page
.
feast-dev
/
feast
Public
Notifications
You must be signed in to change notification settings
Fork
1.4k
Star
7.2k
Code
Issues
218
Pull requests
191
Discussions
Actions
Security and quality
1
Insights
Additional navigation options
Code
Issues
Pull requests
Discussions
Actions
Security and quality
Insights
Expand file tree
Breadcrumbs
feast
/
sdk
/
python
/
feast
/
permissions
/
decision.py
Copy path
More file actions
More file actions
Latest commit
History
History
History
114 lines (96 loc) · 4.13 KB
Breadcrumbs
feast
/
sdk
/
python
/
feast
/
permissions
/
decision.py
Copy path
File metadata and controls
114 lines (96 loc) · 4.13 KB
Raw
Copy raw file
Download raw file
Open symbols panel
Edit and raw actions
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
import
enum
import
logging
from
typing
import
Optional
logger
=
logging
.
getLogger
(
__name__
)
class
DecisionStrategy
(
enum
.
Enum
):
"""
The strategy to be adopted in case multiple permissions match an execution request.
"""
UNANIMOUS
=
"unanimous"
# All policies must evaluate to a positive decision for the final decision to be also positive.
AFFIRMATIVE
=
(
"affirmative"
# At least one policy must evaluate to a positive decision
)
# The number of positive decisions must be greater than the number of negative decisions.
# If the number of positive and negative decisions is the same, the final decision will be negative.
CONSENSUS
=
"consensus"
class
DecisionEvaluator
:
"""
A class to implement the decision logic, according to the selected strategy.
Args:
decision_strategy: The associated `DecisionStrategy`.
num_of_voters: The expected number of votes to complete the decision.
Examples:
Create the instance and specify the strategy and number of decisions:
`evaluator = DecisionEvaluator(DecisionStrategy.UNANIMOUS, 3)
For each vote that you receivem, add a decision grant: `evaluator.add_grant(vote, message)`
and check if the decision process ended: `if evaluator.is_decided():`
Once decided, get the result and the failure explanations using:
`grant, explanations = evaluator.grant()`
"""
def
__init__
(
self
,
num_of_voters
:
int
,
):
# Only AFFIRMATIVE strategy is managed available
decision_strategy
=
DecisionStrategy
.
AFFIRMATIVE
self
.
num_of_voters
=
num_of_voters
self
.
grant_count
=
0
self
.
deny_count
=
0
self
.
grant_quorum
=
(
1
if
decision_strategy
==
DecisionStrategy
.
AFFIRMATIVE
else
num_of_voters
if
decision_strategy
==
DecisionStrategy
.
UNANIMOUS
else
num_of_voters
//
2
+
1
)
self
.
deny_quorum
=
(
num_of_voters
if
decision_strategy
==
DecisionStrategy
.
AFFIRMATIVE
else
1
if
decision_strategy
==
DecisionStrategy
.
UNANIMOUS
else
num_of_voters
//
2
+
(
num_of_voters
%
2
)
)
self
.
grant_decision
:
Optional
[
bool
]
=
None
self
.
explanations
:
list
[
str
]
=
[]
logger
.
info
(
f"Decision evaluation started with grant_quorum=
{
self
.
grant_quorum
}
, deny_quorum=
{
self
.
deny_quorum
}
"
)
def
is_decided
(
self
)
->
bool
:
"""
Returns:
bool: `True` when the decision process completed (e.g. we added as many votes as specified in the `num_of_voters` creation argument).
"""
return
self
.
grant_decision
is
not
None
def
grant
(
self
)
->
tuple
[
bool
,
list
[
str
]]:
"""
Returns:
tuple[bool, list[str]]: The tuple of decision computation: a `bool` with the computation decision and a `list[str]` with the
denial explanations (possibly empty).
"""
logger
.
info
(
f"Decided grant is
{
self
.
grant_decision
}
, explanations=
{
self
.
explanations
}
"
)
return
bool
(
self
.
grant_decision
),
self
.
explanations
def
add_grant
(
self
,
grant
:
bool
,
explanation
:
str
):
"""
Add a single vote to the decision computation, with a possible denial reason.
If the evaluation process already ended, additional votes are discarded.
Args:
grant: `True` is the decision is accepted, `False` otherwise.
explanation: Denial reason (not considered when `vote` is `True`).
"""
if
self
.
is_decided
():
logger
.
warning
(
"Grant decision already decided, discarding vote"
)
return
if
grant
:
self
.
grant_count
+=
1
else
:
self
.
deny_count
+=
1
self
.
explanations
.
append
(
explanation
)
if
self
.
grant_count
>=
self
.
grant_quorum
:
self
.
grant_decision
=
True
if
self
.
deny_count
>=
self
.
deny_quorum
:
self
.
grant_decision
=
False
logger
.
debug
(
f"After new grant: grants=
{
self
.
grant_count
}
, deny_count=
{
self
.
deny_count
}
, grant_decision=
{
self
.
grant_decision
}
"
)
Back
|
FazBrowse Home
|
New Git URL