corvic-engine 0.3.0rc77__cp38-abi3-win_amd64.whl → 0.3.0rc79__cp38-abi3-win_amd64.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.
- corvic/engine/_native.pyd +0 -0
- corvic/eorm/__init__.py +404 -0
- corvic/model/_base_model.py +24 -24
- corvic/model/_completion_model.py +9 -9
- corvic/model/_defaults.py +5 -5
- corvic/model/_feature_view.py +17 -17
- corvic/model/_pipeline.py +12 -12
- corvic/model/_proto_orm_convert.py +102 -100
- corvic/model/_resource.py +24 -24
- corvic/model/_room.py +10 -14
- corvic/model/_source.py +18 -18
- corvic/model/_space.py +21 -21
- corvic/op_graph/_schema.py +3 -3
- corvic/op_graph/feature_types.py +4 -4
- corvic/op_graph/ops.py +2 -2
- corvic/orm/__init__.py +202 -307
- corvic/orm/_soft_delete.py +218 -0
- corvic/orm/ids.py +0 -69
- corvic/system/__init__.py +0 -2
- corvic/system/_embedder.py +2 -2
- corvic/system/in_memory_executor.py +0 -13
- corvic/system/op_graph_executor.py +2 -2
- corvic/system/storage.py +10 -8
- corvic/system_sqlite/client.py +10 -10
- corvic/table/table.py +3 -3
- {corvic_engine-0.3.0rc77.dist-info → corvic_engine-0.3.0rc79.dist-info}/METADATA +1 -1
- {corvic_engine-0.3.0rc77.dist-info → corvic_engine-0.3.0rc79.dist-info}/RECORD +29 -29
- corvic/orm/base.py +0 -256
- corvic/orm/mixins.py +0 -480
- {corvic_engine-0.3.0rc77.dist-info → corvic_engine-0.3.0rc79.dist-info}/WHEEL +0 -0
- {corvic_engine-0.3.0rc77.dist-info → corvic_engine-0.3.0rc79.dist-info}/licenses/LICENSE +0 -0
corvic/orm/__init__.py
CHANGED
@@ -1,38 +1,36 @@
|
|
1
|
-
"""
|
1
|
+
"""Object-Relational Mappings."""
|
2
2
|
|
3
3
|
from __future__ import annotations
|
4
4
|
|
5
|
-
from
|
5
|
+
from collections.abc import Callable
|
6
|
+
from datetime import UTC, datetime
|
7
|
+
from typing import Any, ClassVar, cast
|
6
8
|
|
7
9
|
import sqlalchemy as sa
|
10
|
+
from sqlalchemy import event as sa_event
|
8
11
|
from sqlalchemy import orm as sa_orm
|
12
|
+
from sqlalchemy.ext import hybrid
|
9
13
|
|
14
|
+
import corvic.context
|
10
15
|
from corvic.orm._proto_columns import ProtoMessageDecorator
|
11
|
-
from corvic.orm.
|
16
|
+
from corvic.orm._soft_delete import (
|
17
|
+
BadDeleteError,
|
18
|
+
Session,
|
19
|
+
SoftDeleteMixin,
|
20
|
+
live_unique_constraint,
|
21
|
+
)
|
12
22
|
from corvic.orm.errors import (
|
13
23
|
DeletedObjectError,
|
14
24
|
InvalidORMIdentifierError,
|
15
25
|
RequestedObjectsForNobodyError,
|
16
26
|
)
|
27
|
+
from corvic.orm.func import utc_now
|
17
28
|
from corvic.orm.ids import (
|
18
|
-
AgentID,
|
19
|
-
AgentMessageID,
|
20
29
|
BaseID,
|
21
30
|
BaseIDFromInt,
|
22
|
-
|
23
|
-
FeatureViewID,
|
24
|
-
FeatureViewSourceID,
|
31
|
+
BaseIDFromStr,
|
25
32
|
IntIDDecorator,
|
26
|
-
|
27
|
-
OrgID,
|
28
|
-
PipelineID,
|
29
|
-
ResourceID,
|
30
|
-
RoomID,
|
31
|
-
SourceID,
|
32
|
-
SpaceID,
|
33
|
-
SpaceParametersID,
|
34
|
-
SpaceRunID,
|
35
|
-
UserMessageID,
|
33
|
+
StrIDDecorator,
|
36
34
|
)
|
37
35
|
from corvic.orm.keys import (
|
38
36
|
INT_PK_TYPE,
|
@@ -41,346 +39,243 @@ from corvic.orm.keys import (
|
|
41
39
|
primary_key_identity_column,
|
42
40
|
primary_key_uuid_column,
|
43
41
|
)
|
44
|
-
from corvic.
|
45
|
-
BelongsToOrgMixin,
|
46
|
-
Session,
|
47
|
-
SoftDeleteMixin,
|
48
|
-
live_unique_constraint,
|
49
|
-
)
|
50
|
-
from corvic_generated.orm.v1 import (
|
51
|
-
common_pb2,
|
52
|
-
completion_model_pb2,
|
53
|
-
feature_view_pb2,
|
54
|
-
pipeline_pb2,
|
55
|
-
space_pb2,
|
56
|
-
table_pb2,
|
57
|
-
)
|
58
|
-
from corvic_generated.status.v1 import event_pb2
|
59
|
-
|
60
|
-
# NOTE: The only safe use of "sa_orm.relationship" uses the args:
|
61
|
-
# `viewonly=True` and `init=False`. Writes quickly become
|
62
|
-
# a complex mess when implementers of commit need to reason about
|
63
|
-
# which sub-object should be updated.
|
64
|
-
#
|
65
|
-
# Rather, classes in corvic.model define their own commit protocols,
|
66
|
-
# and if sub-orm-model updates are required they are explicit.
|
67
|
-
|
42
|
+
from corvic.result import InvalidArgumentError
|
68
43
|
|
69
|
-
class Org(SoftDeleteMixin, OrgBase, kw_only=True):
|
70
|
-
"""An organization it a top level grouping of resources."""
|
71
44
|
|
72
|
-
|
73
|
-
|
74
|
-
"""A Room is a logical collection of Documents."""
|
75
|
-
|
76
|
-
__tablename__ = "room"
|
77
|
-
__table_args__ = (live_unique_constraint("name", "org_id"),)
|
78
|
-
|
79
|
-
name: sa_orm.Mapped[str] = sa_orm.mapped_column(sa.Text, default=None)
|
80
|
-
id: sa_orm.Mapped[RoomID | None] = primary_key_identity_column()
|
45
|
+
class OrgID(BaseIDFromStr):
|
46
|
+
"""A unique identifier for an organization."""
|
81
47
|
|
82
48
|
@property
|
83
|
-
def
|
84
|
-
return self.
|
85
|
-
|
86
|
-
|
87
|
-
class BelongsToRoomMixin(sa_orm.MappedAsDataclass):
|
88
|
-
room_id: sa_orm.Mapped[RoomID | None] = sa_orm.mapped_column(
|
89
|
-
ForeignKey(Room).make(ondelete="CASCADE"),
|
90
|
-
nullable=True,
|
91
|
-
default=None,
|
92
|
-
)
|
93
|
-
|
94
|
-
|
95
|
-
class DefaultObjects(Base, kw_only=True):
|
96
|
-
"""Holds the identifiers for default objects."""
|
97
|
-
|
98
|
-
__tablename__ = "default_objects"
|
99
|
-
default_org: sa_orm.Mapped[OrgID | None] = sa_orm.mapped_column(
|
100
|
-
ForeignKey(Org).make(ondelete="CASCADE"),
|
101
|
-
nullable=False,
|
102
|
-
)
|
103
|
-
default_room: sa_orm.Mapped[RoomID | None] = sa_orm.mapped_column(
|
104
|
-
ForeignKey(Room).make(ondelete="CASCADE"), nullable=True, default=None
|
105
|
-
)
|
106
|
-
version: sa_orm.Mapped[int | None] = primary_key_identity_column(type_=INT_PK_TYPE)
|
107
|
-
|
108
|
-
|
109
|
-
class Resource(BelongsToOrgMixin, BelongsToRoomMixin, Base, kw_only=True):
|
110
|
-
"""A Resource is a reference to some durably stored file.
|
111
|
-
|
112
|
-
E.g., a document could be a PDF file, an image, or a text transcript of a
|
113
|
-
conversation
|
114
|
-
"""
|
115
|
-
|
116
|
-
__tablename__ = "resource"
|
117
|
-
|
118
|
-
name: sa_orm.Mapped[str] = sa_orm.mapped_column(sa.Text)
|
119
|
-
mime_type: sa_orm.Mapped[str] = sa_orm.mapped_column(sa.Text)
|
120
|
-
url: sa_orm.Mapped[str] = sa_orm.mapped_column(sa.Text)
|
121
|
-
md5: sa_orm.Mapped[str] = sa_orm.mapped_column(sa.CHAR(32), nullable=True)
|
122
|
-
size: sa_orm.Mapped[int] = sa_orm.mapped_column(nullable=True)
|
123
|
-
original_path: sa_orm.Mapped[str] = sa_orm.mapped_column(nullable=True)
|
124
|
-
description: sa_orm.Mapped[str] = sa_orm.mapped_column(nullable=True)
|
125
|
-
id: sa_orm.Mapped[ResourceID | None] = primary_key_identity_column()
|
126
|
-
latest_event: sa_orm.Mapped[event_pb2.Event | None] = sa_orm.mapped_column(
|
127
|
-
default=None, nullable=True
|
128
|
-
)
|
129
|
-
is_terminal: sa_orm.Mapped[bool | None] = sa_orm.mapped_column(
|
130
|
-
default=None, nullable=True
|
131
|
-
)
|
132
|
-
pipeline_ref: sa_orm.Mapped[PipelineInput | None] = sa_orm.relationship(
|
133
|
-
init=False, viewonly=True
|
134
|
-
)
|
135
|
-
|
136
|
-
|
137
|
-
class Source(BelongsToOrgMixin, BelongsToRoomMixin, Base, kw_only=True):
|
138
|
-
"""A source."""
|
139
|
-
|
140
|
-
__tablename__ = "source"
|
141
|
-
__table_args__ = (sa.UniqueConstraint("name", "room_id"),)
|
142
|
-
|
143
|
-
name: sa_orm.Mapped[str] = sa_orm.mapped_column(sa.Text)
|
144
|
-
# protobuf describing the operations required to construct a table
|
145
|
-
table_op_graph: sa_orm.Mapped[table_pb2.TableComputeOp] = sa_orm.mapped_column()
|
146
|
-
id: sa_orm.Mapped[SourceID | None] = primary_key_identity_column()
|
147
|
-
|
148
|
-
source_files: sa_orm.Mapped[common_pb2.BlobUrlList | None] = sa_orm.mapped_column(
|
149
|
-
default=None
|
150
|
-
)
|
151
|
-
pipeline_ref: sa_orm.Mapped[PipelineOutput | None] = sa_orm.relationship(
|
152
|
-
init=False, viewonly=True
|
153
|
-
)
|
49
|
+
def is_super_user(self):
|
50
|
+
return self._value == corvic.context.SUPERUSER_ORG_ID
|
154
51
|
|
155
52
|
@property
|
156
|
-
def
|
157
|
-
return self.
|
53
|
+
def is_nobody(self):
|
54
|
+
return self._value == corvic.context.NOBODY_ORG_ID
|
158
55
|
|
159
56
|
|
160
|
-
|
161
|
-
|
57
|
+
# A quick primer on SQLAlchemy (sa) hybrid methods:
|
58
|
+
#
|
59
|
+
# Hybrid just means functionality that is different at the class-level versus
|
60
|
+
# the instance-level, and in the sa documentation, the authors really
|
61
|
+
# want to stress that class-versus-instance (decorators) is orthgonal to an
|
62
|
+
# ORM.
|
63
|
+
#
|
64
|
+
# However, this distinction is not particularly helpful for users of sa.
|
65
|
+
# It is best to have a working model of instance-level means Python-world and
|
66
|
+
# class-level means SQL-world. So, a hybrid method is something that has
|
67
|
+
# a different Python representation from its SQL representation.
|
68
|
+
#
|
69
|
+
# Since sa already handles conversions like "Python str" to "SQL text",
|
70
|
+
# certain representation differences between Python and SQL are already handled
|
71
|
+
# (not considered differences at all).
|
72
|
+
#
|
73
|
+
# Hybrid methods are for cases where we want to do non-trivial transformations
|
74
|
+
# between SQL and Python representations.
|
75
|
+
#
|
76
|
+
# The recipe is:
|
77
|
+
#
|
78
|
+
# 1. Define a hybrid_method / hybrid_property (wlog property) that produces the Python
|
79
|
+
# object you want.
|
80
|
+
# 2. If the property doesn't need to be used in any sa query again, you are done.
|
81
|
+
# 3. If the property is simple enough for sa to also use it to produce the SQL
|
82
|
+
# representation, you are also done. E.g., comparisons and bitwise operations
|
83
|
+
# on columns.
|
84
|
+
# 4. Otherwise, you need to define a class-level function, hybrid_property.expression,
|
85
|
+
# which gives the SQL representation of your property when it is passed to
|
86
|
+
# a sa query.
|
87
|
+
# 5. Because of how redefining decorators is supposed to work in Python [1], you
|
88
|
+
# should use @<property_method_name>.inplace.expression to define your
|
89
|
+
# class-level function that describes how the property should be represented
|
90
|
+
# in SQL.
|
91
|
+
#
|
92
|
+
# [1] https://docs.sqlalchemy.org/en/20/orm/extensions/hybrid.html#using-inplace-to-create-pep-484-compliant-hybrid-properties
|
162
93
|
|
163
|
-
__tablename__ = "pipeline"
|
164
|
-
__table_args__ = (sa.UniqueConstraint("name", "room_id"),)
|
165
94
|
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
95
|
+
class Base(sa_orm.MappedAsDataclass, sa_orm.DeclarativeBase):
|
96
|
+
"""Base class for all DB mapped classes."""
|
97
|
+
|
98
|
+
type_annotation_map: ClassVar = {
|
99
|
+
OrgID: StrIDDecorator(OrgID()),
|
100
|
+
}
|
172
101
|
|
173
|
-
|
174
|
-
|
102
|
+
_created_at: sa_orm.Mapped[datetime] = sa_orm.mapped_column(
|
103
|
+
"created_at",
|
104
|
+
sa.DateTime(timezone=True),
|
105
|
+
server_default=utc_now(),
|
175
106
|
init=False,
|
176
|
-
|
107
|
+
index=True,
|
177
108
|
)
|
178
109
|
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
resource: sa_orm.Mapped[Resource] = sa_orm.relationship(viewonly=True, init=False)
|
187
|
-
name: sa_orm.Mapped[str]
|
188
|
-
"""A name the pipeline uses to refer to this input."""
|
189
|
-
|
190
|
-
pipeline_id: sa_orm.Mapped[PipelineID] = primary_key_foreign_column(
|
191
|
-
ForeignKey(Pipeline).make(ondelete="CASCADE")
|
192
|
-
)
|
193
|
-
resource_id: sa_orm.Mapped[ResourceID] = primary_key_foreign_column(
|
194
|
-
ForeignKey(Resource).make(ondelete="CASCADE")
|
110
|
+
_updated_at: sa_orm.Mapped[datetime] = sa_orm.mapped_column(
|
111
|
+
"updated_at",
|
112
|
+
sa.DateTime(timezone=True),
|
113
|
+
onupdate=utc_now(),
|
114
|
+
server_default=utc_now(),
|
115
|
+
init=False,
|
116
|
+
nullable=True,
|
195
117
|
)
|
196
118
|
|
119
|
+
@hybrid.hybrid_property
|
120
|
+
def created_at(self) -> datetime | None:
|
121
|
+
if not self._created_at:
|
122
|
+
return None
|
123
|
+
return self._created_at.replace(tzinfo=UTC)
|
197
124
|
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
__table_args__ = (sa.UniqueConstraint("name", "pipeline_id"),)
|
125
|
+
@created_at.inplace.expression
|
126
|
+
@classmethod
|
127
|
+
def _created_at_expression(cls):
|
128
|
+
return cls._created_at
|
203
129
|
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
ForeignKey(Pipeline).make(ondelete="CASCADE")
|
210
|
-
)
|
211
|
-
source_id: sa_orm.Mapped[SourceID] = primary_key_foreign_column(
|
212
|
-
ForeignKey(Source).make(ondelete="CASCADE")
|
213
|
-
)
|
130
|
+
@hybrid.hybrid_property
|
131
|
+
def updated_at(self) -> datetime | None:
|
132
|
+
if not self._updated_at:
|
133
|
+
return None
|
134
|
+
return self._updated_at.replace(tzinfo=UTC)
|
214
135
|
|
136
|
+
@updated_at.inplace.expression
|
137
|
+
@classmethod
|
138
|
+
def _updated_at_expression(cls):
|
139
|
+
return cls._updated_at
|
215
140
|
|
216
|
-
class FeatureView(
|
217
|
-
SoftDeleteMixin, BelongsToOrgMixin, BelongsToRoomMixin, Base, kw_only=True
|
218
|
-
):
|
219
|
-
"""A FeatureView is a logical collection of sources used by various spaces."""
|
220
141
|
|
221
|
-
|
222
|
-
|
142
|
+
class Org(SoftDeleteMixin, Base, kw_only=True):
|
143
|
+
"""An organization is a top-level grouping of resources."""
|
223
144
|
|
224
|
-
|
225
|
-
name: sa_orm.Mapped[str] = sa_orm.mapped_column(sa.Text, default=None)
|
226
|
-
description: sa_orm.Mapped[str] = sa_orm.mapped_column(sa.Text, default="")
|
145
|
+
__tablename__ = "org"
|
227
146
|
|
228
|
-
|
229
|
-
sa_orm.mapped_column(default_factory=feature_view_pb2.FeatureViewOutput)
|
230
|
-
)
|
147
|
+
id: sa_orm.Mapped[OrgID | None] = primary_key_uuid_column()
|
231
148
|
|
232
149
|
@property
|
233
|
-
def
|
234
|
-
return self.
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
150
|
+
def name(self) -> str:
|
151
|
+
return str(self.id)
|
152
|
+
|
153
|
+
|
154
|
+
def _filter_org_objects(orm_execute_state: sa_orm.ORMExecuteState):
|
155
|
+
if all(
|
156
|
+
not issubclass(mapper.class_, BelongsToOrgMixin | Org)
|
157
|
+
for mapper in orm_execute_state.all_mappers
|
158
|
+
):
|
159
|
+
# operation has nothing to do with models owned by org
|
160
|
+
return
|
161
|
+
if orm_execute_state.is_select:
|
162
|
+
requester = corvic.context.get_requester()
|
163
|
+
org_id = OrgID(requester.org_id)
|
164
|
+
if org_id.is_super_user:
|
165
|
+
return
|
166
|
+
|
167
|
+
if org_id.is_nobody:
|
168
|
+
raise RequestedObjectsForNobodyError(
|
169
|
+
"requester org from context was nobody"
|
170
|
+
)
|
171
|
+
# we need the real value in in expression world and
|
172
|
+
# because of sqlalchemys weird runtime parsing of this it
|
173
|
+
# needs to be a real local with a name
|
174
|
+
db_id = org_id.to_db().unwrap_or_raise()
|
175
|
+
|
176
|
+
# this goofy syntax doesn't typecheck well, but is the documented way to apply
|
177
|
+
# these operations to all subclasses (recursive). Sqlalchemy is inspecting the
|
178
|
+
# lambda rather than just executing it so a function won't work.
|
179
|
+
# https://docs.sqlalchemy.org/en/20/orm/queryguide/api.html#sqlalchemy.orm.with_loader_criteria
|
180
|
+
check_org_id_lambda: Callable[ # noqa: E731
|
181
|
+
[type[BelongsToOrgMixin]], sa.ColumnElement[bool]
|
182
|
+
] = lambda cls: cls.org_id == db_id
|
183
|
+
orm_execute_state.statement = orm_execute_state.statement.options(
|
184
|
+
sa_orm.with_loader_criteria(
|
185
|
+
BelongsToOrgMixin,
|
186
|
+
cast(Any, check_org_id_lambda),
|
187
|
+
include_aliases=True,
|
188
|
+
track_closure_variables=False,
|
189
|
+
),
|
190
|
+
sa_orm.with_loader_criteria(
|
191
|
+
Org,
|
192
|
+
Org.id == org_id,
|
193
|
+
include_aliases=True,
|
194
|
+
track_closure_variables=False,
|
195
|
+
),
|
196
|
+
)
|
197
|
+
|
198
|
+
|
199
|
+
class BelongsToOrgMixin(sa_orm.MappedAsDataclass):
|
200
|
+
"""Mark models that should be subject to org level access control."""
|
201
|
+
|
202
|
+
@staticmethod
|
203
|
+
def _current_org_id_from_context():
|
204
|
+
requester = corvic.context.get_requester()
|
205
|
+
return OrgID(requester.org_id)
|
206
|
+
|
207
|
+
@staticmethod
|
208
|
+
def _make_org_id_default() -> OrgID | None:
|
209
|
+
org_id = BelongsToOrgMixin._current_org_id_from_context()
|
210
|
+
|
211
|
+
if org_id.is_nobody:
|
212
|
+
raise RequestedObjectsForNobodyError(
|
213
|
+
"the nobody org cannot change orm objects"
|
214
|
+
)
|
215
|
+
|
216
|
+
if org_id.is_super_user:
|
217
|
+
return None
|
218
|
+
|
219
|
+
return org_id
|
220
|
+
|
221
|
+
org_id: sa_orm.Mapped[OrgID | None] = sa_orm.mapped_column(
|
222
|
+
ForeignKey(Org).make(ondelete="CASCADE"),
|
259
223
|
nullable=False,
|
260
|
-
|
261
|
-
|
262
|
-
source: sa_orm.Mapped[Source] = sa_orm.relationship(
|
263
|
-
init=True, viewonly=True, default=None
|
224
|
+
default_factory=_make_org_id_default,
|
225
|
+
init=False,
|
264
226
|
)
|
265
227
|
|
228
|
+
@sa_orm.validates("org_id")
|
229
|
+
def validate_org_id(self, _key: str, orm_id: OrgID | None):
|
230
|
+
expected_org_id = self._current_org_id_from_context()
|
231
|
+
if expected_org_id.is_nobody:
|
232
|
+
raise RequestedObjectsForNobodyError(
|
233
|
+
"the nobody org cannot change orm objects"
|
234
|
+
)
|
266
235
|
|
267
|
-
|
268
|
-
|
236
|
+
if expected_org_id.is_super_user:
|
237
|
+
return orm_id
|
269
238
|
|
270
|
-
|
271
|
-
|
239
|
+
if orm_id != expected_org_id:
|
240
|
+
raise InvalidArgumentError(
|
241
|
+
"provided org_id must match the current org",
|
242
|
+
provided=orm_id,
|
243
|
+
expected=expected_org_id,
|
244
|
+
)
|
272
245
|
|
273
|
-
|
274
|
-
name: sa_orm.Mapped[str] = sa_orm.mapped_column(sa.Text, default=None)
|
275
|
-
description: sa_orm.Mapped[str] = sa_orm.mapped_column(sa.Text, default="")
|
246
|
+
return orm_id
|
276
247
|
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
default=None,
|
281
|
-
)
|
282
|
-
parameters: sa_orm.Mapped[space_pb2.SpaceParameters | None] = sa_orm.mapped_column(
|
283
|
-
default=None
|
284
|
-
)
|
285
|
-
auto_sync: sa_orm.Mapped[bool | None] = sa_orm.mapped_column(default=None)
|
286
|
-
feature_view: sa_orm.Mapped[FeatureView] = sa_orm.relationship(
|
287
|
-
init=False,
|
288
|
-
default=None,
|
289
|
-
viewonly=True,
|
290
|
-
)
|
248
|
+
@staticmethod
|
249
|
+
def register_session_event_listeners(session: type[sa_orm.Session]):
|
250
|
+
sa_event.listen(session, "do_orm_execute", _filter_org_objects)
|
291
251
|
|
292
|
-
@property
|
293
|
-
def space_key(self):
|
294
|
-
return self.name
|
295
252
|
|
253
|
+
BelongsToOrgMixin.register_session_event_listeners(Session)
|
296
254
|
|
297
|
-
class CompletionModel(SoftDeleteMixin, BelongsToOrgMixin, Base, kw_only=True):
|
298
|
-
"""A customer's custom completion model definition."""
|
299
255
|
|
300
|
-
|
301
|
-
__table_args__ = (live_unique_constraint("name", "org_id"),)
|
302
|
-
|
303
|
-
id: sa_orm.Mapped[CompletionModelID | None] = primary_key_identity_column()
|
304
|
-
name: sa_orm.Mapped[str] = sa_orm.mapped_column(sa.Text, default=None)
|
305
|
-
description: sa_orm.Mapped[str] = sa_orm.mapped_column(sa.Text, default=None)
|
306
|
-
parameters: sa_orm.Mapped[completion_model_pb2.CompletionModelParameters | None] = (
|
307
|
-
sa_orm.mapped_column(default=None)
|
308
|
-
)
|
309
|
-
secret_api_key: sa_orm.Mapped[str] = sa_orm.mapped_column(sa.Text, default=None)
|
310
|
-
last_validation_time: sa_orm.Mapped[datetime | None] = sa_orm.mapped_column(
|
311
|
-
sa.DateTime(timezone=True),
|
312
|
-
server_default=None,
|
313
|
-
default=None,
|
314
|
-
)
|
315
|
-
last_successful_validation: sa_orm.Mapped[datetime | None] = sa_orm.mapped_column(
|
316
|
-
sa.DateTime(timezone=True),
|
317
|
-
server_default=None,
|
318
|
-
default=None,
|
319
|
-
)
|
320
|
-
|
321
|
-
@property
|
322
|
-
def model_key(self):
|
323
|
-
return self.name
|
324
|
-
|
325
|
-
|
326
|
-
ID = (
|
327
|
-
AgentID
|
328
|
-
| AgentMessageID
|
329
|
-
| CompletionModelID
|
330
|
-
| FeatureViewID
|
331
|
-
| FeatureViewSourceID
|
332
|
-
| MessageEntryID
|
333
|
-
| OrgID
|
334
|
-
| PipelineID
|
335
|
-
| ResourceID
|
336
|
-
| RoomID
|
337
|
-
| SourceID
|
338
|
-
| SpaceID
|
339
|
-
| SpaceParametersID
|
340
|
-
| SpaceRunID
|
341
|
-
| UserMessageID
|
342
|
-
)
|
256
|
+
ID = OrgID
|
343
257
|
|
344
258
|
|
345
259
|
__all__ = [
|
346
|
-
"
|
347
|
-
"AgentMessageID",
|
260
|
+
"BadDeleteError",
|
348
261
|
"Base",
|
349
262
|
"BaseID",
|
350
263
|
"BaseIDFromInt",
|
351
264
|
"BelongsToOrgMixin",
|
352
|
-
"CompletionModel",
|
353
|
-
"CompletionModelID",
|
354
|
-
"DefaultObjects",
|
355
265
|
"DeletedObjectError",
|
356
|
-
"
|
357
|
-
"FeatureViewID",
|
358
|
-
"FeatureViewSource",
|
359
|
-
"FeatureViewSourceID",
|
266
|
+
"ForeignKey",
|
360
267
|
"ID",
|
268
|
+
"INT_PK_TYPE",
|
269
|
+
"IntIDDecorator",
|
361
270
|
"InvalidORMIdentifierError",
|
362
|
-
"MessageEntryID",
|
363
271
|
"Org",
|
364
272
|
"OrgID",
|
365
|
-
"
|
366
|
-
"PipelineInput",
|
367
|
-
"PipelineOutput",
|
273
|
+
"ProtoMessageDecorator",
|
368
274
|
"RequestedObjectsForNobodyError",
|
369
|
-
"Resource",
|
370
|
-
"ResourceID",
|
371
|
-
"Room",
|
372
|
-
"RoomID",
|
373
275
|
"Session",
|
374
|
-
"
|
375
|
-
"
|
376
|
-
"Space",
|
377
|
-
"SpaceID",
|
378
|
-
"SpaceParametersID",
|
379
|
-
"SpaceRunID",
|
380
|
-
"UserMessageID",
|
276
|
+
"SoftDeleteMixin",
|
277
|
+
"live_unique_constraint",
|
381
278
|
"primary_key_foreign_column",
|
382
279
|
"primary_key_identity_column",
|
383
280
|
"primary_key_uuid_column",
|
384
|
-
"ProtoMessageDecorator",
|
385
|
-
"IntIDDecorator",
|
386
281
|
]
|