openmeter 1.0.0b53__py3-none-any.whl → 2.0.0__py3-none-any.whl

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.

Potentially problematic release.


This version of openmeter might be problematic. Click here for more details.

Files changed (132) hide show
  1. openmeter/__init__.py +89 -15
  2. openmeter/_base_client.py +2041 -0
  3. openmeter/_client.py +518 -70
  4. openmeter/_compat.py +221 -0
  5. openmeter/_constants.py +14 -0
  6. openmeter/_exceptions.py +108 -0
  7. openmeter/_files.py +127 -0
  8. openmeter/_models.py +777 -0
  9. openmeter/_qs.py +150 -0
  10. openmeter/_resource.py +43 -0
  11. openmeter/_response.py +820 -0
  12. openmeter/_streaming.py +333 -0
  13. openmeter/_types.py +222 -0
  14. openmeter/_utils/__init__.py +56 -0
  15. openmeter/_utils/_logs.py +25 -0
  16. openmeter/_utils/_proxy.py +63 -0
  17. openmeter/_utils/_reflection.py +42 -0
  18. openmeter/_utils/_streams.py +12 -0
  19. openmeter/_utils/_sync.py +81 -0
  20. openmeter/_utils/_transform.py +387 -0
  21. openmeter/_utils/_typing.py +120 -0
  22. openmeter/_utils/_utils.py +419 -0
  23. openmeter/_version.py +4 -0
  24. openmeter/lib/.keep +4 -0
  25. openmeter/py.typed +0 -1
  26. openmeter/resources/__init__.py +103 -0
  27. openmeter/resources/debug/__init__.py +33 -0
  28. openmeter/resources/debug/debug.py +102 -0
  29. openmeter/resources/debug/metrics.py +146 -0
  30. openmeter/resources/entitlements/__init__.py +47 -0
  31. openmeter/resources/entitlements/entitlements.py +450 -0
  32. openmeter/resources/entitlements/features.py +578 -0
  33. openmeter/resources/entitlements/grants.py +389 -0
  34. openmeter/resources/events.py +442 -0
  35. openmeter/resources/meters/__init__.py +33 -0
  36. openmeter/resources/meters/meters.py +666 -0
  37. openmeter/resources/meters/subjects.py +163 -0
  38. openmeter/resources/notifications/__init__.py +75 -0
  39. openmeter/resources/notifications/channels.py +686 -0
  40. openmeter/resources/notifications/events.py +365 -0
  41. openmeter/resources/notifications/notifications.py +198 -0
  42. openmeter/resources/notifications/rules.py +781 -0
  43. openmeter/resources/notifications/webhook.py +208 -0
  44. openmeter/resources/portal/__init__.py +47 -0
  45. openmeter/resources/portal/meters.py +230 -0
  46. openmeter/resources/portal/portal.py +112 -0
  47. openmeter/resources/portal/tokens.py +359 -0
  48. openmeter/resources/subjects/entitlements/__init__.py +33 -0
  49. openmeter/resources/subjects/entitlements/entitlements.py +1881 -0
  50. openmeter/resources/subjects/entitlements/grants.py +453 -0
  51. openmeter/resources/subjects.py +419 -0
  52. openmeter/types/__init__.py +21 -0
  53. openmeter/types/debug/__init__.py +5 -0
  54. openmeter/types/debug/metric_list_response.py +7 -0
  55. openmeter/types/entitlement.py +238 -0
  56. openmeter/types/entitlements/__init__.py +11 -0
  57. openmeter/types/entitlements/feature.py +61 -0
  58. openmeter/types/entitlements/feature_create_params.py +43 -0
  59. openmeter/types/entitlements/feature_list_params.py +23 -0
  60. openmeter/types/entitlements/grant_list_params.py +57 -0
  61. openmeter/types/entitlements/grant_list_response.py +11 -0
  62. openmeter/types/entitlements/grant_paginated_response.py +24 -0
  63. openmeter/types/entitlements/list_features_result.py +28 -0
  64. openmeter/types/event_ingest_params.py +46 -0
  65. openmeter/types/event_ingest_response.py +43 -0
  66. openmeter/types/event_list_params.py +22 -0
  67. openmeter/types/event_list_response.py +9 -0
  68. openmeter/types/ingested_event.py +59 -0
  69. openmeter/types/list_entitlements_result.py +28 -0
  70. openmeter/types/meter.py +53 -0
  71. openmeter/types/meter_create_params.py +50 -0
  72. openmeter/types/meter_list_response.py +9 -0
  73. openmeter/types/meter_query_params.py +50 -0
  74. openmeter/types/meter_query_result.py +35 -0
  75. openmeter/types/meters/__init__.py +5 -0
  76. openmeter/types/meters/subject_list_response.py +8 -0
  77. openmeter/types/notifications/__init__.py +18 -0
  78. openmeter/types/notifications/channel_create_params.py +34 -0
  79. openmeter/types/notifications/channel_list_params.py +41 -0
  80. openmeter/types/notifications/channel_list_response.py +24 -0
  81. openmeter/types/notifications/channel_update_params.py +34 -0
  82. openmeter/types/notifications/event_list_params.py +61 -0
  83. openmeter/types/notifications/event_list_response.py +24 -0
  84. openmeter/types/notifications/notification_channel.py +47 -0
  85. openmeter/types/notifications/notification_event.py +215 -0
  86. openmeter/types/notifications/notification_rule.py +70 -0
  87. openmeter/types/notifications/rule_create_params.py +39 -0
  88. openmeter/types/notifications/rule_list_params.py +54 -0
  89. openmeter/types/notifications/rule_list_response.py +24 -0
  90. openmeter/types/notifications/rule_update_params.py +39 -0
  91. openmeter/types/notifications/webhook_svix_params.py +26 -0
  92. openmeter/types/portal/__init__.py +10 -0
  93. openmeter/types/portal/meter_query_params.py +44 -0
  94. openmeter/types/portal/portal_token.py +28 -0
  95. openmeter/types/portal/token_create_params.py +17 -0
  96. openmeter/types/portal/token_invalidate_params.py +15 -0
  97. openmeter/types/portal/token_list_params.py +12 -0
  98. openmeter/types/portal/token_list_response.py +9 -0
  99. openmeter/types/shared/__init__.py +3 -0
  100. openmeter/types/subject.py +37 -0
  101. openmeter/types/subject_list_response.py +9 -0
  102. openmeter/types/subject_param.py +27 -0
  103. openmeter/types/subject_upsert_params.py +39 -0
  104. openmeter/types/subject_upsert_response.py +10 -0
  105. openmeter/types/subjects/__init__.py +13 -0
  106. openmeter/types/subjects/entitlement_history_params.py +35 -0
  107. openmeter/types/subjects/entitlement_history_response.py +98 -0
  108. openmeter/types/subjects/entitlement_list_response.py +10 -0
  109. openmeter/types/subjects/entitlements/__init__.py +8 -0
  110. openmeter/types/subjects/entitlements/entitlement_grant.py +103 -0
  111. openmeter/types/subjects/entitlements/grant_list_response.py +10 -0
  112. openmeter-2.0.0.dist-info/METADATA +396 -0
  113. openmeter-2.0.0.dist-info/RECORD +115 -0
  114. {openmeter-1.0.0b53.dist-info → openmeter-2.0.0.dist-info}/WHEEL +1 -1
  115. openmeter-2.0.0.dist-info/licenses/LICENSE +201 -0
  116. openmeter/_configuration.py +0 -36
  117. openmeter/_operations/__init__.py +0 -17
  118. openmeter/_operations/_operations.py +0 -2098
  119. openmeter/_operations/_patch.py +0 -20
  120. openmeter/_patch.py +0 -20
  121. openmeter/_serialization.py +0 -2008
  122. openmeter/_vendor.py +0 -24
  123. openmeter/aio/__init__.py +0 -21
  124. openmeter/aio/_client.py +0 -83
  125. openmeter/aio/_configuration.py +0 -36
  126. openmeter/aio/_operations/__init__.py +0 -17
  127. openmeter/aio/_operations/_operations.py +0 -1771
  128. openmeter/aio/_operations/_patch.py +0 -20
  129. openmeter/aio/_patch.py +0 -20
  130. openmeter/aio/_vendor.py +0 -24
  131. openmeter-1.0.0b53.dist-info/METADATA +0 -92
  132. openmeter-1.0.0b53.dist-info/RECORD +0 -21
@@ -0,0 +1,35 @@
1
+ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2
+
3
+ from typing import Dict, List, Optional
4
+ from datetime import datetime
5
+ from typing_extensions import Literal
6
+
7
+ from pydantic import Field as FieldInfo
8
+
9
+ from .._models import BaseModel
10
+
11
+ __all__ = ["MeterQueryResult", "Data"]
12
+
13
+
14
+ class Data(BaseModel):
15
+ value: float
16
+
17
+ window_end: datetime = FieldInfo(alias="windowEnd")
18
+
19
+ window_start: datetime = FieldInfo(alias="windowStart")
20
+
21
+ group_by: Optional[Dict[str, str]] = FieldInfo(alias="groupBy", default=None)
22
+
23
+ subject: Optional[str] = None
24
+ """The subject of the meter value."""
25
+
26
+
27
+ class MeterQueryResult(BaseModel):
28
+ data: List[Data]
29
+
30
+ from_: Optional[datetime] = FieldInfo(alias="from", default=None)
31
+
32
+ to: Optional[datetime] = None
33
+
34
+ window_size: Optional[Literal["MINUTE", "HOUR", "DAY"]] = FieldInfo(alias="windowSize", default=None)
35
+ """Aggregation window size."""
@@ -0,0 +1,5 @@
1
+ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2
+
3
+ from __future__ import annotations
4
+
5
+ from .subject_list_response import SubjectListResponse as SubjectListResponse
@@ -0,0 +1,8 @@
1
+ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2
+
3
+ from typing import List
4
+ from typing_extensions import TypeAlias
5
+
6
+ __all__ = ["SubjectListResponse"]
7
+
8
+ SubjectListResponse: TypeAlias = List[str]
@@ -0,0 +1,18 @@
1
+ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2
+
3
+ from __future__ import annotations
4
+
5
+ from .rule_list_params import RuleListParams as RuleListParams
6
+ from .event_list_params import EventListParams as EventListParams
7
+ from .notification_rule import NotificationRule as NotificationRule
8
+ from .notification_event import NotificationEvent as NotificationEvent
9
+ from .rule_create_params import RuleCreateParams as RuleCreateParams
10
+ from .rule_list_response import RuleListResponse as RuleListResponse
11
+ from .rule_update_params import RuleUpdateParams as RuleUpdateParams
12
+ from .channel_list_params import ChannelListParams as ChannelListParams
13
+ from .event_list_response import EventListResponse as EventListResponse
14
+ from .webhook_svix_params import WebhookSvixParams as WebhookSvixParams
15
+ from .notification_channel import NotificationChannel as NotificationChannel
16
+ from .channel_create_params import ChannelCreateParams as ChannelCreateParams
17
+ from .channel_list_response import ChannelListResponse as ChannelListResponse
18
+ from .channel_update_params import ChannelUpdateParams as ChannelUpdateParams
@@ -0,0 +1,34 @@
1
+ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Dict
6
+ from typing_extensions import Literal, Required, Annotated, TypedDict
7
+
8
+ from ..._utils import PropertyInfo
9
+
10
+ __all__ = ["ChannelCreateParams"]
11
+
12
+
13
+ class ChannelCreateParams(TypedDict, total=False):
14
+ name: Required[str]
15
+ """User friendly name of the channel."""
16
+
17
+ type: Required[Literal["WEBHOOK"]]
18
+ """Notification channel type."""
19
+
20
+ url: Required[str]
21
+ """Webhook URL where the notification is sent."""
22
+
23
+ custom_headers: Annotated[Dict[str, str], PropertyInfo(alias="customHeaders")]
24
+ """Custom HTTP headers sent as part of the webhook request."""
25
+
26
+ disabled: bool
27
+ """Whether the channel is disabled or not."""
28
+
29
+ signing_secret: Annotated[str, PropertyInfo(alias="signingSecret")]
30
+ """Signing secret used for webhook request validation on the receiving end.
31
+
32
+ Format: `base64` encoded random bytes optionally prefixed with `whsec_`.
33
+ Recommended size: 24
34
+ """
@@ -0,0 +1,41 @@
1
+ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing_extensions import Literal, Annotated, TypedDict
6
+
7
+ from ..._utils import PropertyInfo
8
+
9
+ __all__ = ["ChannelListParams"]
10
+
11
+
12
+ class ChannelListParams(TypedDict, total=False):
13
+ include_deleted: Annotated[bool, PropertyInfo(alias="includeDeleted")]
14
+ """Include deleted notification channels in response.
15
+
16
+ Usage: `?includeDeleted=true`
17
+ """
18
+
19
+ include_disabled: Annotated[bool, PropertyInfo(alias="includeDisabled")]
20
+ """Include disabled notification channels in response.
21
+
22
+ Usage: `?includeDisabled=false`
23
+ """
24
+
25
+ order: Literal["ASC", "DESC"]
26
+ """The order direction."""
27
+
28
+ order_by: Annotated[Literal["id", "type", "createdAt", "updatedAt"], PropertyInfo(alias="orderBy")]
29
+ """The order by field."""
30
+
31
+ page: int
32
+ """Start date-time in RFC 3339 format.
33
+
34
+ Inclusive.
35
+ """
36
+
37
+ page_size: Annotated[int, PropertyInfo(alias="pageSize")]
38
+ """Number of items per page.
39
+
40
+ Default is 100.
41
+ """
@@ -0,0 +1,24 @@
1
+ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2
+
3
+ from typing import List
4
+
5
+ from pydantic import Field as FieldInfo
6
+
7
+ from ..._models import BaseModel
8
+ from .notification_channel import NotificationChannel
9
+
10
+ __all__ = ["ChannelListResponse"]
11
+
12
+
13
+ class ChannelListResponse(BaseModel):
14
+ items: List[NotificationChannel]
15
+ """The items in the current page."""
16
+
17
+ page: int
18
+ """The items in the current page."""
19
+
20
+ page_size: int = FieldInfo(alias="pageSize")
21
+ """The items in the current page."""
22
+
23
+ total_count: int = FieldInfo(alias="totalCount")
24
+ """The items in the current page."""
@@ -0,0 +1,34 @@
1
+ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Dict
6
+ from typing_extensions import Literal, Required, Annotated, TypedDict
7
+
8
+ from ..._utils import PropertyInfo
9
+
10
+ __all__ = ["ChannelUpdateParams"]
11
+
12
+
13
+ class ChannelUpdateParams(TypedDict, total=False):
14
+ name: Required[str]
15
+ """User friendly name of the channel."""
16
+
17
+ type: Required[Literal["WEBHOOK"]]
18
+ """Notification channel type."""
19
+
20
+ url: Required[str]
21
+ """Webhook URL where the notification is sent."""
22
+
23
+ custom_headers: Annotated[Dict[str, str], PropertyInfo(alias="customHeaders")]
24
+ """Custom HTTP headers sent as part of the webhook request."""
25
+
26
+ disabled: bool
27
+ """Whether the channel is disabled or not."""
28
+
29
+ signing_secret: Annotated[str, PropertyInfo(alias="signingSecret")]
30
+ """Signing secret used for webhook request validation on the receiving end.
31
+
32
+ Format: `base64` encoded random bytes optionally prefixed with `whsec_`.
33
+ Recommended size: 24
34
+ """
@@ -0,0 +1,61 @@
1
+ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import List, Union
6
+ from datetime import datetime
7
+ from typing_extensions import Literal, Annotated, TypedDict
8
+
9
+ from ..._utils import PropertyInfo
10
+
11
+ __all__ = ["EventListParams"]
12
+
13
+
14
+ class EventListParams(TypedDict, total=False):
15
+ channel: List[str]
16
+ """Filtering by multiple channel ids.
17
+
18
+ Usage: `?channel=01J8J4RXH778XB056JS088PCYT&channel=01J8J4S1R1G9EVN62RG23A9M6J`
19
+ """
20
+
21
+ feature: List[str]
22
+ """Filtering by multiple feature ids or keys.
23
+
24
+ Usage: `?feature=feature-1&feature=feature-2`
25
+ """
26
+
27
+ from_: Annotated[Union[str, datetime], PropertyInfo(alias="from", format="iso8601")]
28
+ """Start date-time in RFC 3339 format. Inclusive."""
29
+
30
+ order: Literal["ASC", "DESC"]
31
+ """The order direction."""
32
+
33
+ order_by: Annotated[Literal["id", "createdAt"], PropertyInfo(alias="orderBy")]
34
+ """The order by field."""
35
+
36
+ page: int
37
+ """Start date-time in RFC 3339 format.
38
+
39
+ Inclusive.
40
+ """
41
+
42
+ page_size: Annotated[int, PropertyInfo(alias="pageSize")]
43
+ """Number of items per page.
44
+
45
+ Default is 100.
46
+ """
47
+
48
+ rule: List[str]
49
+ """Filtering by multiple rule ids.
50
+
51
+ Usage: `?rule=01J8J2XYZ2N5WBYK09EDZFBSZM&rule=01J8J4R4VZH180KRKQ63NB2VA5`
52
+ """
53
+
54
+ subject: List[str]
55
+ """Filtering by multiple subject ids or keys.
56
+
57
+ Usage: `?subject=subject-1&subject=subject-2`
58
+ """
59
+
60
+ to: Annotated[Union[str, datetime], PropertyInfo(format="iso8601")]
61
+ """End date-time in RFC 3339 format. Inclusive."""
@@ -0,0 +1,24 @@
1
+ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2
+
3
+ from typing import List
4
+
5
+ from pydantic import Field as FieldInfo
6
+
7
+ from ..._models import BaseModel
8
+ from .notification_event import NotificationEvent
9
+
10
+ __all__ = ["EventListResponse"]
11
+
12
+
13
+ class EventListResponse(BaseModel):
14
+ items: List[NotificationEvent]
15
+ """The items in the current page."""
16
+
17
+ page: int
18
+ """The items in the current page."""
19
+
20
+ page_size: int = FieldInfo(alias="pageSize")
21
+ """The items in the current page."""
22
+
23
+ total_count: int = FieldInfo(alias="totalCount")
24
+ """The items in the current page."""
@@ -0,0 +1,47 @@
1
+ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2
+
3
+ from typing import Dict, Optional
4
+ from datetime import datetime
5
+ from typing_extensions import Literal
6
+
7
+ from pydantic import Field as FieldInfo
8
+
9
+ from ..._models import BaseModel
10
+
11
+ __all__ = ["NotificationChannel"]
12
+
13
+
14
+ class NotificationChannel(BaseModel):
15
+ id: str
16
+ """Identifies the notification channel."""
17
+
18
+ created_at: datetime = FieldInfo(alias="createdAt")
19
+ """Timestamp of when the resource was created."""
20
+
21
+ name: str
22
+ """User friendly name of the channel."""
23
+
24
+ type: Literal["WEBHOOK"]
25
+ """Notification channel type."""
26
+
27
+ updated_at: datetime = FieldInfo(alias="updatedAt")
28
+ """Timestamp of when the resource was last updated."""
29
+
30
+ url: str
31
+ """Webhook URL where the notification is sent."""
32
+
33
+ custom_headers: Optional[Dict[str, str]] = FieldInfo(alias="customHeaders", default=None)
34
+ """Custom HTTP headers sent as part of the webhook request."""
35
+
36
+ deleted_at: Optional[datetime] = FieldInfo(alias="deletedAt", default=None)
37
+ """Timestamp of when the resource was permanently deleted."""
38
+
39
+ disabled: Optional[bool] = None
40
+ """Whether the channel is disabled or not."""
41
+
42
+ signing_secret: Optional[str] = FieldInfo(alias="signingSecret", default=None)
43
+ """Signing secret used for webhook request validation on the receiving end.
44
+
45
+ Format: `base64` encoded random bytes optionally prefixed with `whsec_`.
46
+ Recommended size: 24
47
+ """
@@ -0,0 +1,215 @@
1
+ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2
+
3
+ from typing import Dict, List, Optional
4
+ from datetime import datetime
5
+ from typing_extensions import Literal
6
+
7
+ from pydantic import Field as FieldInfo
8
+
9
+ from ..subject import Subject
10
+ from ..._models import BaseModel
11
+ from .notification_rule import NotificationRule
12
+ from ..entitlements.feature import Feature
13
+ from ..subjects.entitlement_value import EntitlementValue
14
+
15
+ __all__ = [
16
+ "NotificationEvent",
17
+ "DeliveryStatus",
18
+ "DeliveryStatusChannel",
19
+ "Payload",
20
+ "PayloadData",
21
+ "PayloadDataEntitlement",
22
+ "PayloadDataEntitlementCurrentUsagePeriod",
23
+ "PayloadDataEntitlementUsagePeriod",
24
+ "PayloadDataThreshold",
25
+ ]
26
+
27
+
28
+ class DeliveryStatusChannel(BaseModel):
29
+ id: str
30
+ """Identifies the notification channel."""
31
+
32
+ type: Literal["WEBHOOK"]
33
+ """Type of the notification channel."""
34
+
35
+
36
+ class DeliveryStatus(BaseModel):
37
+ channel: DeliveryStatusChannel
38
+ """Metadata only fields of a notification channel."""
39
+
40
+ reason: str
41
+ """The reason of the last deliverry state update."""
42
+
43
+ state: Literal["SUCCESS", "FAILED", "SENDING", "PENDING"]
44
+ """The delivery state of the notification event to the channel."""
45
+
46
+ updated_at: datetime = FieldInfo(alias="updatedAt")
47
+ """Timestamp of when the status was last updated in RFC 3339 format."""
48
+
49
+
50
+ class PayloadDataEntitlementCurrentUsagePeriod(BaseModel):
51
+ from_: datetime = FieldInfo(alias="from")
52
+ """Period start time."""
53
+
54
+ to: datetime
55
+ """Period end time."""
56
+
57
+
58
+ class PayloadDataEntitlementUsagePeriod(BaseModel):
59
+ anchor: datetime
60
+ """A date-time anchor to base the recurring period on."""
61
+
62
+ interval: Literal["DAY", "WEEK", "MONTH", "YEAR"]
63
+ """The unit of time for the interval. One of: `day`, `week`, `month`, or `year`."""
64
+
65
+
66
+ class PayloadDataEntitlement(BaseModel):
67
+ id: str
68
+ """Readonly unique ULID identifier."""
69
+
70
+ created_at: datetime = FieldInfo(alias="createdAt")
71
+ """Timestamp of when the resource was created."""
72
+
73
+ current_usage_period: PayloadDataEntitlementCurrentUsagePeriod = FieldInfo(alias="currentUsagePeriod")
74
+ """A period with a start and end time."""
75
+
76
+ feature_id: str = FieldInfo(alias="featureId")
77
+ """The feature the subject is entitled to use."""
78
+
79
+ feature_key: str = FieldInfo(alias="featureKey")
80
+ """The feature the subject is entitled to use."""
81
+
82
+ last_reset: datetime = FieldInfo(alias="lastReset")
83
+ """The time the last reset happened."""
84
+
85
+ measure_usage_from: datetime = FieldInfo(alias="measureUsageFrom")
86
+ """The time from which usage is measured.
87
+
88
+ If not specified on creation, defaults to entitlement creation time.
89
+ """
90
+
91
+ subject_key: str = FieldInfo(alias="subjectKey")
92
+ """The identifier key unique to the subject"""
93
+
94
+ type: Literal["metered"]
95
+
96
+ updated_at: datetime = FieldInfo(alias="updatedAt")
97
+ """Timestamp of when the resource was last updated."""
98
+
99
+ usage_period: PayloadDataEntitlementUsagePeriod = FieldInfo(alias="usagePeriod")
100
+ """Recurring period with an interval and an anchor."""
101
+
102
+ deleted_at: Optional[datetime] = FieldInfo(alias="deletedAt", default=None)
103
+ """Timestamp of when the resource was permanently deleted."""
104
+
105
+ is_soft_limit: Optional[bool] = FieldInfo(alias="isSoftLimit", default=None)
106
+ """
107
+ If softLimit=true the subject can use the feature even if the entitlement is
108
+ exhausted, hasAccess will always be true.
109
+ """
110
+
111
+ issue_after_reset: Optional[float] = FieldInfo(alias="issueAfterReset", default=None)
112
+ """
113
+ You can grant usage automatically alongside the entitlement, the example
114
+ scenario would be creating a starting balance. If an amount is specified here, a
115
+ grant will be created alongside the entitlement with the specified amount. That
116
+ grant will have it's rollover settings configured in a way that after each reset
117
+ operation, the balance will return the original amount specified here. Manually
118
+ creating such a grant would mean having the "amount", "minRolloverAmount", and
119
+ "maxRolloverAmount" fields all be the same.
120
+ """
121
+
122
+ issue_after_reset_priority: Optional[int] = FieldInfo(alias="issueAfterResetPriority", default=None)
123
+ """Defines the grant priority for the default grant."""
124
+
125
+ is_unlimited: Optional[bool] = FieldInfo(alias="isUnlimited", default=None)
126
+ """Deprecated, ignored by the backend.
127
+
128
+ Please use isSoftLimit instead; this field will be removed in the future.
129
+ """
130
+
131
+ metadata: Optional[Dict[str, str]] = None
132
+ """
133
+ Set of key-value pairs. Metadata can be used to store additional information
134
+ about a resource.
135
+ """
136
+
137
+ preserve_overage_at_reset: Optional[bool] = FieldInfo(alias="preserveOverageAtReset", default=None)
138
+ """If true, the overage is preserved at reset. If false, the usage is reset to 0."""
139
+
140
+
141
+ class PayloadDataThreshold(BaseModel):
142
+ type: Literal["PERCENT", "NUMBER"]
143
+ """Type of the rule in the balance threshold specification."""
144
+
145
+ value: float
146
+ """Value of the threshold."""
147
+
148
+
149
+ class PayloadData(BaseModel):
150
+ entitlement: PayloadDataEntitlement
151
+ """
152
+ Metered entitlements are useful for many different use cases, from setting up
153
+ usage based access to implementing complex credit systems. Access is determined
154
+ based on feature usage using a balance calculation (the "usage allowance"
155
+ provided by the issued grants is "burnt down" by the usage).
156
+ """
157
+
158
+ feature: Feature
159
+ """
160
+ Represents a feature that can be enabled or disabled for a plan. Used both for
161
+ product catalog and entitlements.
162
+ """
163
+
164
+ subject: Subject
165
+ """A subject is a unique identifier for a user or entity."""
166
+
167
+ threshold: PayloadDataThreshold
168
+ """Threshold value with multiple supported types."""
169
+
170
+ value: EntitlementValue
171
+ """Entitlements are the core of OpenMeter access management.
172
+
173
+ They define access to features for subjects. Entitlements can be metered,
174
+ boolean, or static.
175
+ """
176
+
177
+
178
+ class Payload(BaseModel):
179
+ id: str
180
+ """A unique identifier for the notification event the payload belongs to."""
181
+
182
+ data: PayloadData
183
+ """
184
+ Data of the payload for notification event with `entitlements.balance.threshold`
185
+ type.
186
+ """
187
+
188
+ timestamp: datetime
189
+ """Timestamp when the notification event was created in RFC 3339 format."""
190
+
191
+ type: Literal["entitlements.balance.threshold"]
192
+ """Type of the notification event."""
193
+
194
+
195
+ class NotificationEvent(BaseModel):
196
+ id: str
197
+ """A unique identifier of the notification event."""
198
+
199
+ created_at: datetime = FieldInfo(alias="createdAt")
200
+ """Timestamp when the notification event was created in RFC 3339 format."""
201
+
202
+ delivery_status: List[DeliveryStatus] = FieldInfo(alias="deliveryStatus")
203
+ """The delivery status of the notification event."""
204
+
205
+ payload: Payload
206
+ """Payload for notification event with `entitlements.balance.threshold` type."""
207
+
208
+ rule: NotificationRule
209
+ """Notification rule with entitlements.balance.threshold type."""
210
+
211
+ type: Literal["entitlements.balance.threshold"]
212
+ """Type of the notification event."""
213
+
214
+ annotations: Optional[Dict[str, object]] = None
215
+ """Set of key-value pairs managed by the system. Cannot be modified by user."""
@@ -0,0 +1,70 @@
1
+ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2
+
3
+ from typing import List, Optional
4
+ from datetime import datetime
5
+ from typing_extensions import Literal
6
+
7
+ from pydantic import Field as FieldInfo
8
+
9
+ from ..._models import BaseModel
10
+
11
+ __all__ = ["NotificationRule", "Channel", "Threshold", "Feature"]
12
+
13
+
14
+ class Channel(BaseModel):
15
+ id: str
16
+ """Identifies the notification channel."""
17
+
18
+ type: Literal["WEBHOOK"]
19
+ """Type of the notification channel."""
20
+
21
+
22
+ class Threshold(BaseModel):
23
+ type: Literal["PERCENT", "NUMBER"]
24
+ """Type of the rule in the balance threshold specification."""
25
+
26
+ value: float
27
+ """Value of the threshold."""
28
+
29
+
30
+ class Feature(BaseModel):
31
+ id: str
32
+ """Unique identifier of a feature."""
33
+
34
+ key: str
35
+ """
36
+ The key is an immutable unique identifier of the feature used throughout the
37
+ API, for example when interacting with a subject's entitlements.
38
+ """
39
+
40
+
41
+ class NotificationRule(BaseModel):
42
+ id: str
43
+ """Identifies the notification rule."""
44
+
45
+ channels: List[Channel]
46
+ """List of notification channels the rule applies to."""
47
+
48
+ created_at: datetime = FieldInfo(alias="createdAt")
49
+ """Timestamp of when the resource was created."""
50
+
51
+ name: str
52
+ """The user friendly name of the notification rule."""
53
+
54
+ thresholds: List[Threshold]
55
+ """List of thresholds the rule suppose to be triggered."""
56
+
57
+ type: Literal["entitlements.balance.threshold"]
58
+ """Notification rule type."""
59
+
60
+ updated_at: datetime = FieldInfo(alias="updatedAt")
61
+ """Timestamp of when the resource was last updated."""
62
+
63
+ deleted_at: Optional[datetime] = FieldInfo(alias="deletedAt", default=None)
64
+ """Timestamp of when the resource was permanently deleted."""
65
+
66
+ disabled: Optional[bool] = None
67
+ """Whether the rule is disabled or not."""
68
+
69
+ features: Optional[List[Feature]] = None
70
+ """Optional field containing list of features the rule applies to."""
@@ -0,0 +1,39 @@
1
+ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import List, Iterable
6
+ from typing_extensions import Literal, Required, TypedDict
7
+
8
+ __all__ = ["RuleCreateParams", "Threshold"]
9
+
10
+
11
+ class RuleCreateParams(TypedDict, total=False):
12
+ channels: Required[List[str]]
13
+ """List of notification channels the rule is applied to."""
14
+
15
+ name: Required[str]
16
+ """The user friendly name of the notification rule."""
17
+
18
+ thresholds: Required[Iterable[Threshold]]
19
+ """List of thresholds the rule suppose to be triggered."""
20
+
21
+ type: Required[Literal["entitlements.balance.threshold"]]
22
+ """Notification rule type."""
23
+
24
+ disabled: bool
25
+ """Whether the rule is disabled or not."""
26
+
27
+ features: List[str]
28
+ """Optional field for defining the scope of notification by feature.
29
+
30
+ It may contain features by id or key.
31
+ """
32
+
33
+
34
+ class Threshold(TypedDict, total=False):
35
+ type: Required[Literal["PERCENT", "NUMBER"]]
36
+ """Type of the rule in the balance threshold specification."""
37
+
38
+ value: Required[float]
39
+ """Value of the threshold."""