openrouter 0.1.2__py3-none-any.whl → 0.6.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.
Files changed (84) hide show
  1. openrouter/_version.py +2 -2
  2. openrouter/analytics.py +28 -2
  3. openrouter/api_keys.py +210 -14
  4. openrouter/chat.py +192 -200
  5. openrouter/components/__init__.py +229 -285
  6. openrouter/components/_schema10.py +39 -0
  7. openrouter/components/_schema14.py +11 -0
  8. openrouter/components/_schema17.py +154 -0
  9. openrouter/components/{_schema3.py → _schema19.py} +28 -22
  10. openrouter/components/{_schema0.py → _schema5.py} +7 -5
  11. openrouter/components/assistantmessage.py +32 -1
  12. openrouter/components/chatgenerationparams.py +57 -343
  13. openrouter/components/chatmessagecontentitemimage.py +4 -4
  14. openrouter/components/chatresponsechoice.py +1 -6
  15. openrouter/components/chatstreamingmessagechunk.py +3 -3
  16. openrouter/components/developermessage.py +41 -0
  17. openrouter/components/message.py +6 -39
  18. openrouter/components/model.py +7 -1
  19. openrouter/components/openresponsesrequest.py +31 -39
  20. openrouter/components/outputmodality.py +1 -0
  21. openrouter/components/providername.py +2 -0
  22. openrouter/components/providerpreferences.py +2 -10
  23. openrouter/components/publicendpoint.py +8 -24
  24. openrouter/components/publicpricing.py +3 -24
  25. openrouter/credits.py +86 -14
  26. openrouter/embeddings.py +92 -20
  27. openrouter/endpoints.py +62 -2
  28. openrouter/generations.py +26 -0
  29. openrouter/guardrails.py +3367 -0
  30. openrouter/models_.py +120 -12
  31. openrouter/oauth.py +90 -22
  32. openrouter/operations/__init__.py +601 -30
  33. openrouter/operations/bulkassignkeystoguardrail.py +116 -0
  34. openrouter/operations/bulkassignmemberstoguardrail.py +116 -0
  35. openrouter/operations/bulkunassignkeysfromguardrail.py +116 -0
  36. openrouter/operations/bulkunassignmembersfromguardrail.py +116 -0
  37. openrouter/operations/createauthkeyscode.py +81 -3
  38. openrouter/operations/createcoinbasecharge.py +82 -2
  39. openrouter/operations/createembeddings.py +82 -3
  40. openrouter/operations/createguardrail.py +325 -0
  41. openrouter/operations/createkeys.py +81 -3
  42. openrouter/operations/createresponses.py +84 -3
  43. openrouter/operations/deleteguardrail.py +104 -0
  44. openrouter/operations/deletekeys.py +69 -3
  45. openrouter/operations/exchangeauthcodeforapikey.py +81 -3
  46. openrouter/operations/getcredits.py +70 -1
  47. openrouter/operations/getcurrentkey.py +81 -3
  48. openrouter/operations/getgeneration.py +248 -3
  49. openrouter/operations/getguardrail.py +228 -0
  50. openrouter/operations/getkey.py +64 -1
  51. openrouter/operations/getmodels.py +95 -5
  52. openrouter/operations/getuseractivity.py +62 -1
  53. openrouter/operations/list.py +63 -1
  54. openrouter/operations/listembeddingsmodels.py +74 -0
  55. openrouter/operations/listendpoints.py +65 -2
  56. openrouter/operations/listendpointszdr.py +70 -2
  57. openrouter/operations/listguardrailkeyassignments.py +192 -0
  58. openrouter/operations/listguardrailmemberassignments.py +187 -0
  59. openrouter/operations/listguardrails.py +238 -0
  60. openrouter/operations/listkeyassignments.py +180 -0
  61. openrouter/operations/listmemberassignments.py +175 -0
  62. openrouter/operations/listmodelscount.py +74 -0
  63. openrouter/operations/listmodelsuser.py +70 -2
  64. openrouter/operations/listproviders.py +70 -2
  65. openrouter/operations/sendchatcompletionrequest.py +87 -3
  66. openrouter/operations/updateguardrail.py +334 -0
  67. openrouter/operations/updatekeys.py +63 -0
  68. openrouter/providers.py +36 -2
  69. openrouter/responses.py +178 -148
  70. openrouter/sdk.py +5 -8
  71. openrouter/types/models.py +378 -0
  72. {openrouter-0.1.2.dist-info → openrouter-0.6.0.dist-info}/METADATA +5 -1
  73. {openrouter-0.1.2.dist-info → openrouter-0.6.0.dist-info}/RECORD +76 -63
  74. {openrouter-0.1.2.dist-info → openrouter-0.6.0.dist-info}/WHEEL +1 -1
  75. openrouter/completions.py +0 -361
  76. openrouter/components/completionchoice.py +0 -82
  77. openrouter/components/completioncreateparams.py +0 -277
  78. openrouter/components/completionlogprobs.py +0 -54
  79. openrouter/components/completionresponse.py +0 -46
  80. openrouter/components/completionusage.py +0 -19
  81. openrouter/operations/getparameters.py +0 -123
  82. openrouter/parameters.py +0 -237
  83. {openrouter-0.1.2.dist-info → openrouter-0.6.0.dist-info}/licenses/LICENSE +0 -0
  84. {openrouter-0.1.2.dist-info → openrouter-0.6.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,192 @@
1
+ """Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
2
+
3
+ from __future__ import annotations
4
+ from openrouter.types import BaseModel, Nullable, UNSET_SENTINEL
5
+ from openrouter.utils import (
6
+ FieldMetadata,
7
+ HeaderMetadata,
8
+ PathParamMetadata,
9
+ QueryParamMetadata,
10
+ )
11
+ import pydantic
12
+ from pydantic import model_serializer
13
+ from typing import List, Optional
14
+ from typing_extensions import Annotated, NotRequired, TypedDict
15
+
16
+
17
+ class ListGuardrailKeyAssignmentsGlobalsTypedDict(TypedDict):
18
+ http_referer: NotRequired[str]
19
+ r"""The app identifier should be your app's URL and is used as the primary identifier for rankings.
20
+ This is used to track API usage per application.
21
+
22
+ """
23
+ x_title: NotRequired[str]
24
+ r"""The app display name allows you to customize how your app appears in OpenRouter's dashboard.
25
+
26
+ """
27
+
28
+
29
+ class ListGuardrailKeyAssignmentsGlobals(BaseModel):
30
+ http_referer: Annotated[
31
+ Optional[str],
32
+ pydantic.Field(alias="HTTP-Referer"),
33
+ FieldMetadata(header=HeaderMetadata(style="simple", explode=False)),
34
+ ] = None
35
+ r"""The app identifier should be your app's URL and is used as the primary identifier for rankings.
36
+ This is used to track API usage per application.
37
+
38
+ """
39
+
40
+ x_title: Annotated[
41
+ Optional[str],
42
+ pydantic.Field(alias="X-Title"),
43
+ FieldMetadata(header=HeaderMetadata(style="simple", explode=False)),
44
+ ] = None
45
+ r"""The app display name allows you to customize how your app appears in OpenRouter's dashboard.
46
+
47
+ """
48
+
49
+
50
+ class ListGuardrailKeyAssignmentsRequestTypedDict(TypedDict):
51
+ id: str
52
+ r"""The unique identifier of the guardrail"""
53
+ http_referer: NotRequired[str]
54
+ r"""The app identifier should be your app's URL and is used as the primary identifier for rankings.
55
+ This is used to track API usage per application.
56
+
57
+ """
58
+ x_title: NotRequired[str]
59
+ r"""The app display name allows you to customize how your app appears in OpenRouter's dashboard.
60
+
61
+ """
62
+ offset: NotRequired[str]
63
+ r"""Number of records to skip for pagination"""
64
+ limit: NotRequired[str]
65
+ r"""Maximum number of records to return (max 100)"""
66
+
67
+
68
+ class ListGuardrailKeyAssignmentsRequest(BaseModel):
69
+ id: Annotated[
70
+ str, FieldMetadata(path=PathParamMetadata(style="simple", explode=False))
71
+ ]
72
+ r"""The unique identifier of the guardrail"""
73
+
74
+ http_referer: Annotated[
75
+ Optional[str],
76
+ pydantic.Field(alias="HTTP-Referer"),
77
+ FieldMetadata(header=HeaderMetadata(style="simple", explode=False)),
78
+ ] = None
79
+ r"""The app identifier should be your app's URL and is used as the primary identifier for rankings.
80
+ This is used to track API usage per application.
81
+
82
+ """
83
+
84
+ x_title: Annotated[
85
+ Optional[str],
86
+ pydantic.Field(alias="X-Title"),
87
+ FieldMetadata(header=HeaderMetadata(style="simple", explode=False)),
88
+ ] = None
89
+ r"""The app display name allows you to customize how your app appears in OpenRouter's dashboard.
90
+
91
+ """
92
+
93
+ offset: Annotated[
94
+ Optional[str],
95
+ FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
96
+ ] = None
97
+ r"""Number of records to skip for pagination"""
98
+
99
+ limit: Annotated[
100
+ Optional[str],
101
+ FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
102
+ ] = None
103
+ r"""Maximum number of records to return (max 100)"""
104
+
105
+
106
+ class ListGuardrailKeyAssignmentsDataTypedDict(TypedDict):
107
+ id: str
108
+ r"""Unique identifier for the assignment"""
109
+ key_hash: str
110
+ r"""Hash of the assigned API key"""
111
+ guardrail_id: str
112
+ r"""ID of the guardrail"""
113
+ key_name: str
114
+ r"""Name of the API key"""
115
+ key_label: str
116
+ r"""Label of the API key"""
117
+ assigned_by: Nullable[str]
118
+ r"""User ID of who made the assignment"""
119
+ created_at: str
120
+ r"""ISO 8601 timestamp of when the assignment was created"""
121
+
122
+
123
+ class ListGuardrailKeyAssignmentsData(BaseModel):
124
+ id: str
125
+ r"""Unique identifier for the assignment"""
126
+
127
+ key_hash: str
128
+ r"""Hash of the assigned API key"""
129
+
130
+ guardrail_id: str
131
+ r"""ID of the guardrail"""
132
+
133
+ key_name: str
134
+ r"""Name of the API key"""
135
+
136
+ key_label: str
137
+ r"""Label of the API key"""
138
+
139
+ assigned_by: Nullable[str]
140
+ r"""User ID of who made the assignment"""
141
+
142
+ created_at: str
143
+ r"""ISO 8601 timestamp of when the assignment was created"""
144
+
145
+ @model_serializer(mode="wrap")
146
+ def serialize_model(self, handler):
147
+ optional_fields = []
148
+ nullable_fields = ["assigned_by"]
149
+ null_default_fields = []
150
+
151
+ serialized = handler(self)
152
+
153
+ m = {}
154
+
155
+ for n, f in type(self).model_fields.items():
156
+ k = f.alias or n
157
+ val = serialized.get(k)
158
+ serialized.pop(k, None)
159
+
160
+ optional_nullable = k in optional_fields and k in nullable_fields
161
+ is_set = (
162
+ self.__pydantic_fields_set__.intersection({n})
163
+ or k in null_default_fields
164
+ ) # pylint: disable=no-member
165
+
166
+ if val is not None and val != UNSET_SENTINEL:
167
+ m[k] = val
168
+ elif val != UNSET_SENTINEL and (
169
+ not k in optional_fields or (optional_nullable and is_set)
170
+ ):
171
+ m[k] = val
172
+
173
+ return m
174
+
175
+
176
+ class ListGuardrailKeyAssignmentsResponseTypedDict(TypedDict):
177
+ r"""List of key assignments"""
178
+
179
+ data: List[ListGuardrailKeyAssignmentsDataTypedDict]
180
+ r"""List of key assignments"""
181
+ total_count: float
182
+ r"""Total number of key assignments for this guardrail"""
183
+
184
+
185
+ class ListGuardrailKeyAssignmentsResponse(BaseModel):
186
+ r"""List of key assignments"""
187
+
188
+ data: List[ListGuardrailKeyAssignmentsData]
189
+ r"""List of key assignments"""
190
+
191
+ total_count: float
192
+ r"""Total number of key assignments for this guardrail"""
@@ -0,0 +1,187 @@
1
+ """Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
2
+
3
+ from __future__ import annotations
4
+ from openrouter.types import BaseModel, Nullable, UNSET_SENTINEL
5
+ from openrouter.utils import (
6
+ FieldMetadata,
7
+ HeaderMetadata,
8
+ PathParamMetadata,
9
+ QueryParamMetadata,
10
+ )
11
+ import pydantic
12
+ from pydantic import model_serializer
13
+ from typing import List, Optional
14
+ from typing_extensions import Annotated, NotRequired, TypedDict
15
+
16
+
17
+ class ListGuardrailMemberAssignmentsGlobalsTypedDict(TypedDict):
18
+ http_referer: NotRequired[str]
19
+ r"""The app identifier should be your app's URL and is used as the primary identifier for rankings.
20
+ This is used to track API usage per application.
21
+
22
+ """
23
+ x_title: NotRequired[str]
24
+ r"""The app display name allows you to customize how your app appears in OpenRouter's dashboard.
25
+
26
+ """
27
+
28
+
29
+ class ListGuardrailMemberAssignmentsGlobals(BaseModel):
30
+ http_referer: Annotated[
31
+ Optional[str],
32
+ pydantic.Field(alias="HTTP-Referer"),
33
+ FieldMetadata(header=HeaderMetadata(style="simple", explode=False)),
34
+ ] = None
35
+ r"""The app identifier should be your app's URL and is used as the primary identifier for rankings.
36
+ This is used to track API usage per application.
37
+
38
+ """
39
+
40
+ x_title: Annotated[
41
+ Optional[str],
42
+ pydantic.Field(alias="X-Title"),
43
+ FieldMetadata(header=HeaderMetadata(style="simple", explode=False)),
44
+ ] = None
45
+ r"""The app display name allows you to customize how your app appears in OpenRouter's dashboard.
46
+
47
+ """
48
+
49
+
50
+ class ListGuardrailMemberAssignmentsRequestTypedDict(TypedDict):
51
+ id: str
52
+ r"""The unique identifier of the guardrail"""
53
+ http_referer: NotRequired[str]
54
+ r"""The app identifier should be your app's URL and is used as the primary identifier for rankings.
55
+ This is used to track API usage per application.
56
+
57
+ """
58
+ x_title: NotRequired[str]
59
+ r"""The app display name allows you to customize how your app appears in OpenRouter's dashboard.
60
+
61
+ """
62
+ offset: NotRequired[str]
63
+ r"""Number of records to skip for pagination"""
64
+ limit: NotRequired[str]
65
+ r"""Maximum number of records to return (max 100)"""
66
+
67
+
68
+ class ListGuardrailMemberAssignmentsRequest(BaseModel):
69
+ id: Annotated[
70
+ str, FieldMetadata(path=PathParamMetadata(style="simple", explode=False))
71
+ ]
72
+ r"""The unique identifier of the guardrail"""
73
+
74
+ http_referer: Annotated[
75
+ Optional[str],
76
+ pydantic.Field(alias="HTTP-Referer"),
77
+ FieldMetadata(header=HeaderMetadata(style="simple", explode=False)),
78
+ ] = None
79
+ r"""The app identifier should be your app's URL and is used as the primary identifier for rankings.
80
+ This is used to track API usage per application.
81
+
82
+ """
83
+
84
+ x_title: Annotated[
85
+ Optional[str],
86
+ pydantic.Field(alias="X-Title"),
87
+ FieldMetadata(header=HeaderMetadata(style="simple", explode=False)),
88
+ ] = None
89
+ r"""The app display name allows you to customize how your app appears in OpenRouter's dashboard.
90
+
91
+ """
92
+
93
+ offset: Annotated[
94
+ Optional[str],
95
+ FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
96
+ ] = None
97
+ r"""Number of records to skip for pagination"""
98
+
99
+ limit: Annotated[
100
+ Optional[str],
101
+ FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
102
+ ] = None
103
+ r"""Maximum number of records to return (max 100)"""
104
+
105
+
106
+ class ListGuardrailMemberAssignmentsDataTypedDict(TypedDict):
107
+ id: str
108
+ r"""Unique identifier for the assignment"""
109
+ user_id: str
110
+ r"""Clerk user ID of the assigned member"""
111
+ organization_id: str
112
+ r"""Organization ID"""
113
+ guardrail_id: str
114
+ r"""ID of the guardrail"""
115
+ assigned_by: Nullable[str]
116
+ r"""User ID of who made the assignment"""
117
+ created_at: str
118
+ r"""ISO 8601 timestamp of when the assignment was created"""
119
+
120
+
121
+ class ListGuardrailMemberAssignmentsData(BaseModel):
122
+ id: str
123
+ r"""Unique identifier for the assignment"""
124
+
125
+ user_id: str
126
+ r"""Clerk user ID of the assigned member"""
127
+
128
+ organization_id: str
129
+ r"""Organization ID"""
130
+
131
+ guardrail_id: str
132
+ r"""ID of the guardrail"""
133
+
134
+ assigned_by: Nullable[str]
135
+ r"""User ID of who made the assignment"""
136
+
137
+ created_at: str
138
+ r"""ISO 8601 timestamp of when the assignment was created"""
139
+
140
+ @model_serializer(mode="wrap")
141
+ def serialize_model(self, handler):
142
+ optional_fields = []
143
+ nullable_fields = ["assigned_by"]
144
+ null_default_fields = []
145
+
146
+ serialized = handler(self)
147
+
148
+ m = {}
149
+
150
+ for n, f in type(self).model_fields.items():
151
+ k = f.alias or n
152
+ val = serialized.get(k)
153
+ serialized.pop(k, None)
154
+
155
+ optional_nullable = k in optional_fields and k in nullable_fields
156
+ is_set = (
157
+ self.__pydantic_fields_set__.intersection({n})
158
+ or k in null_default_fields
159
+ ) # pylint: disable=no-member
160
+
161
+ if val is not None and val != UNSET_SENTINEL:
162
+ m[k] = val
163
+ elif val != UNSET_SENTINEL and (
164
+ not k in optional_fields or (optional_nullable and is_set)
165
+ ):
166
+ m[k] = val
167
+
168
+ return m
169
+
170
+
171
+ class ListGuardrailMemberAssignmentsResponseTypedDict(TypedDict):
172
+ r"""List of member assignments"""
173
+
174
+ data: List[ListGuardrailMemberAssignmentsDataTypedDict]
175
+ r"""List of member assignments"""
176
+ total_count: float
177
+ r"""Total number of member assignments"""
178
+
179
+
180
+ class ListGuardrailMemberAssignmentsResponse(BaseModel):
181
+ r"""List of member assignments"""
182
+
183
+ data: List[ListGuardrailMemberAssignmentsData]
184
+ r"""List of member assignments"""
185
+
186
+ total_count: float
187
+ r"""Total number of member assignments"""
@@ -0,0 +1,238 @@
1
+ """Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
2
+
3
+ from __future__ import annotations
4
+ from openrouter.types import (
5
+ BaseModel,
6
+ Nullable,
7
+ OptionalNullable,
8
+ UNSET,
9
+ UNSET_SENTINEL,
10
+ UnrecognizedStr,
11
+ )
12
+ from openrouter.utils import (
13
+ FieldMetadata,
14
+ HeaderMetadata,
15
+ QueryParamMetadata,
16
+ validate_open_enum,
17
+ )
18
+ import pydantic
19
+ from pydantic import model_serializer
20
+ from pydantic.functional_validators import PlainValidator
21
+ from typing import List, Literal, Optional, Union
22
+ from typing_extensions import Annotated, NotRequired, TypedDict
23
+
24
+
25
+ class ListGuardrailsGlobalsTypedDict(TypedDict):
26
+ http_referer: NotRequired[str]
27
+ r"""The app identifier should be your app's URL and is used as the primary identifier for rankings.
28
+ This is used to track API usage per application.
29
+
30
+ """
31
+ x_title: NotRequired[str]
32
+ r"""The app display name allows you to customize how your app appears in OpenRouter's dashboard.
33
+
34
+ """
35
+
36
+
37
+ class ListGuardrailsGlobals(BaseModel):
38
+ http_referer: Annotated[
39
+ Optional[str],
40
+ pydantic.Field(alias="HTTP-Referer"),
41
+ FieldMetadata(header=HeaderMetadata(style="simple", explode=False)),
42
+ ] = None
43
+ r"""The app identifier should be your app's URL and is used as the primary identifier for rankings.
44
+ This is used to track API usage per application.
45
+
46
+ """
47
+
48
+ x_title: Annotated[
49
+ Optional[str],
50
+ pydantic.Field(alias="X-Title"),
51
+ FieldMetadata(header=HeaderMetadata(style="simple", explode=False)),
52
+ ] = None
53
+ r"""The app display name allows you to customize how your app appears in OpenRouter's dashboard.
54
+
55
+ """
56
+
57
+
58
+ class ListGuardrailsRequestTypedDict(TypedDict):
59
+ http_referer: NotRequired[str]
60
+ r"""The app identifier should be your app's URL and is used as the primary identifier for rankings.
61
+ This is used to track API usage per application.
62
+
63
+ """
64
+ x_title: NotRequired[str]
65
+ r"""The app display name allows you to customize how your app appears in OpenRouter's dashboard.
66
+
67
+ """
68
+ offset: NotRequired[str]
69
+ r"""Number of records to skip for pagination"""
70
+ limit: NotRequired[str]
71
+ r"""Maximum number of records to return (max 100)"""
72
+
73
+
74
+ class ListGuardrailsRequest(BaseModel):
75
+ http_referer: Annotated[
76
+ Optional[str],
77
+ pydantic.Field(alias="HTTP-Referer"),
78
+ FieldMetadata(header=HeaderMetadata(style="simple", explode=False)),
79
+ ] = None
80
+ r"""The app identifier should be your app's URL and is used as the primary identifier for rankings.
81
+ This is used to track API usage per application.
82
+
83
+ """
84
+
85
+ x_title: Annotated[
86
+ Optional[str],
87
+ pydantic.Field(alias="X-Title"),
88
+ FieldMetadata(header=HeaderMetadata(style="simple", explode=False)),
89
+ ] = None
90
+ r"""The app display name allows you to customize how your app appears in OpenRouter's dashboard.
91
+
92
+ """
93
+
94
+ offset: Annotated[
95
+ Optional[str],
96
+ FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
97
+ ] = None
98
+ r"""Number of records to skip for pagination"""
99
+
100
+ limit: Annotated[
101
+ Optional[str],
102
+ FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
103
+ ] = None
104
+ r"""Maximum number of records to return (max 100)"""
105
+
106
+
107
+ ListGuardrailsResetInterval = Union[
108
+ Literal[
109
+ "daily",
110
+ "weekly",
111
+ "monthly",
112
+ ],
113
+ UnrecognizedStr,
114
+ ]
115
+ r"""Interval at which the limit resets (daily, weekly, monthly)"""
116
+
117
+
118
+ class ListGuardrailsDataTypedDict(TypedDict):
119
+ id: str
120
+ r"""Unique identifier for the guardrail"""
121
+ name: str
122
+ r"""Name of the guardrail"""
123
+ created_at: str
124
+ r"""ISO 8601 timestamp of when the guardrail was created"""
125
+ description: NotRequired[Nullable[str]]
126
+ r"""Description of the guardrail"""
127
+ limit_usd: NotRequired[Nullable[float]]
128
+ r"""Spending limit in USD"""
129
+ reset_interval: NotRequired[Nullable[ListGuardrailsResetInterval]]
130
+ r"""Interval at which the limit resets (daily, weekly, monthly)"""
131
+ allowed_providers: NotRequired[Nullable[List[str]]]
132
+ r"""List of allowed provider IDs"""
133
+ allowed_models: NotRequired[Nullable[List[str]]]
134
+ r"""Array of model canonical_slugs (immutable identifiers)"""
135
+ enforce_zdr: NotRequired[Nullable[bool]]
136
+ r"""Whether to enforce zero data retention"""
137
+ updated_at: NotRequired[Nullable[str]]
138
+ r"""ISO 8601 timestamp of when the guardrail was last updated"""
139
+
140
+
141
+ class ListGuardrailsData(BaseModel):
142
+ id: str
143
+ r"""Unique identifier for the guardrail"""
144
+
145
+ name: str
146
+ r"""Name of the guardrail"""
147
+
148
+ created_at: str
149
+ r"""ISO 8601 timestamp of when the guardrail was created"""
150
+
151
+ description: OptionalNullable[str] = UNSET
152
+ r"""Description of the guardrail"""
153
+
154
+ limit_usd: OptionalNullable[float] = UNSET
155
+ r"""Spending limit in USD"""
156
+
157
+ reset_interval: Annotated[
158
+ OptionalNullable[ListGuardrailsResetInterval],
159
+ PlainValidator(validate_open_enum(False)),
160
+ ] = UNSET
161
+ r"""Interval at which the limit resets (daily, weekly, monthly)"""
162
+
163
+ allowed_providers: OptionalNullable[List[str]] = UNSET
164
+ r"""List of allowed provider IDs"""
165
+
166
+ allowed_models: OptionalNullable[List[str]] = UNSET
167
+ r"""Array of model canonical_slugs (immutable identifiers)"""
168
+
169
+ enforce_zdr: OptionalNullable[bool] = UNSET
170
+ r"""Whether to enforce zero data retention"""
171
+
172
+ updated_at: OptionalNullable[str] = UNSET
173
+ r"""ISO 8601 timestamp of when the guardrail was last updated"""
174
+
175
+ @model_serializer(mode="wrap")
176
+ def serialize_model(self, handler):
177
+ optional_fields = [
178
+ "description",
179
+ "limit_usd",
180
+ "reset_interval",
181
+ "allowed_providers",
182
+ "allowed_models",
183
+ "enforce_zdr",
184
+ "updated_at",
185
+ ]
186
+ nullable_fields = [
187
+ "description",
188
+ "limit_usd",
189
+ "reset_interval",
190
+ "allowed_providers",
191
+ "allowed_models",
192
+ "enforce_zdr",
193
+ "updated_at",
194
+ ]
195
+ null_default_fields = []
196
+
197
+ serialized = handler(self)
198
+
199
+ m = {}
200
+
201
+ for n, f in type(self).model_fields.items():
202
+ k = f.alias or n
203
+ val = serialized.get(k)
204
+ serialized.pop(k, None)
205
+
206
+ optional_nullable = k in optional_fields and k in nullable_fields
207
+ is_set = (
208
+ self.__pydantic_fields_set__.intersection({n})
209
+ or k in null_default_fields
210
+ ) # pylint: disable=no-member
211
+
212
+ if val is not None and val != UNSET_SENTINEL:
213
+ m[k] = val
214
+ elif val != UNSET_SENTINEL and (
215
+ not k in optional_fields or (optional_nullable and is_set)
216
+ ):
217
+ m[k] = val
218
+
219
+ return m
220
+
221
+
222
+ class ListGuardrailsResponseTypedDict(TypedDict):
223
+ r"""List of guardrails"""
224
+
225
+ data: List[ListGuardrailsDataTypedDict]
226
+ r"""List of guardrails"""
227
+ total_count: float
228
+ r"""Total number of guardrails"""
229
+
230
+
231
+ class ListGuardrailsResponse(BaseModel):
232
+ r"""List of guardrails"""
233
+
234
+ data: List[ListGuardrailsData]
235
+ r"""List of guardrails"""
236
+
237
+ total_count: float
238
+ r"""Total number of guardrails"""