corvic-engine 0.3.0rc77__cp38-abi3-win_amd64.whl → 0.3.0rc78__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/_embedder.py +2 -2
- 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.0rc78.dist-info}/METADATA +1 -1
- {corvic_engine-0.3.0rc77.dist-info → corvic_engine-0.3.0rc78.dist-info}/RECORD +27 -27
- corvic/orm/base.py +0 -256
- corvic/orm/mixins.py +0 -480
- {corvic_engine-0.3.0rc77.dist-info → corvic_engine-0.3.0rc78.dist-info}/WHEEL +0 -0
- {corvic_engine-0.3.0rc77.dist-info → corvic_engine-0.3.0rc78.dist-info}/licenses/LICENSE +0 -0
corvic/engine/_native.pyd
CHANGED
Binary file
|
corvic/eorm/__init__.py
ADDED
@@ -0,0 +1,404 @@
|
|
1
|
+
"""Engine Object-Relational Mappings."""
|
2
|
+
|
3
|
+
from __future__ import annotations
|
4
|
+
|
5
|
+
from datetime import datetime
|
6
|
+
from typing import TypeAlias
|
7
|
+
|
8
|
+
import sqlalchemy as sa
|
9
|
+
from sqlalchemy import orm as sa_orm
|
10
|
+
|
11
|
+
from corvic import orm
|
12
|
+
from corvic_generated.orm.v1 import (
|
13
|
+
common_pb2,
|
14
|
+
completion_model_pb2,
|
15
|
+
feature_view_pb2,
|
16
|
+
pipeline_pb2,
|
17
|
+
space_pb2,
|
18
|
+
table_pb2,
|
19
|
+
)
|
20
|
+
from corvic_generated.status.v1 import event_pb2
|
21
|
+
|
22
|
+
OrgID: TypeAlias = orm.OrgID
|
23
|
+
|
24
|
+
|
25
|
+
class RoomID(orm.BaseIDFromInt):
|
26
|
+
"""A unique identifier for a room."""
|
27
|
+
|
28
|
+
|
29
|
+
class ResourceID(orm.BaseIDFromInt):
|
30
|
+
"""A unique identifier for a resource."""
|
31
|
+
|
32
|
+
|
33
|
+
class SourceID(orm.BaseIDFromInt):
|
34
|
+
"""A unique identifier for a source."""
|
35
|
+
|
36
|
+
|
37
|
+
class PipelineID(orm.BaseIDFromInt):
|
38
|
+
"""A unique identifier for a pipeline."""
|
39
|
+
|
40
|
+
|
41
|
+
class FeatureViewID(orm.BaseIDFromInt):
|
42
|
+
"""A unique identifier for a feature view."""
|
43
|
+
|
44
|
+
|
45
|
+
class FeatureViewSourceID(orm.BaseIDFromInt):
|
46
|
+
"""A unique identifier for a source in a feature view."""
|
47
|
+
|
48
|
+
|
49
|
+
class SpaceID(orm.BaseIDFromInt):
|
50
|
+
"""A unique identifier for a space."""
|
51
|
+
|
52
|
+
|
53
|
+
class CompletionModelID(orm.BaseIDFromInt):
|
54
|
+
"""A unique identifier for a completion model."""
|
55
|
+
|
56
|
+
|
57
|
+
orm.Base.registry.update_type_annotation_map(
|
58
|
+
{
|
59
|
+
# proto message column types
|
60
|
+
common_pb2.BlobUrlList: orm.ProtoMessageDecorator(common_pb2.BlobUrlList()),
|
61
|
+
feature_view_pb2.FeatureViewOutput: orm.ProtoMessageDecorator(
|
62
|
+
feature_view_pb2.FeatureViewOutput()
|
63
|
+
),
|
64
|
+
common_pb2.AgentMessageMetadata: orm.ProtoMessageDecorator(
|
65
|
+
common_pb2.AgentMessageMetadata()
|
66
|
+
),
|
67
|
+
space_pb2.SpaceParameters: orm.ProtoMessageDecorator(
|
68
|
+
space_pb2.SpaceParameters()
|
69
|
+
),
|
70
|
+
table_pb2.TableComputeOp: orm.ProtoMessageDecorator(table_pb2.TableComputeOp()),
|
71
|
+
table_pb2.NamedTables: orm.ProtoMessageDecorator(table_pb2.NamedTables()),
|
72
|
+
common_pb2.RetrievedEntities: orm.ProtoMessageDecorator(
|
73
|
+
common_pb2.RetrievedEntities()
|
74
|
+
),
|
75
|
+
pipeline_pb2.PipelineTransformation: orm.ProtoMessageDecorator(
|
76
|
+
pipeline_pb2.PipelineTransformation()
|
77
|
+
),
|
78
|
+
event_pb2.Event: orm.ProtoMessageDecorator(event_pb2.Event()),
|
79
|
+
completion_model_pb2.CompletionModelParameters: orm.ProtoMessageDecorator(
|
80
|
+
completion_model_pb2.CompletionModelParameters()
|
81
|
+
),
|
82
|
+
# ID types
|
83
|
+
RoomID: orm.IntIDDecorator(RoomID()),
|
84
|
+
ResourceID: orm.IntIDDecorator(ResourceID()),
|
85
|
+
SourceID: orm.IntIDDecorator(SourceID()),
|
86
|
+
PipelineID: orm.IntIDDecorator(PipelineID()),
|
87
|
+
FeatureViewID: orm.IntIDDecorator(FeatureViewID()),
|
88
|
+
FeatureViewSourceID: orm.IntIDDecorator(FeatureViewSourceID()),
|
89
|
+
SpaceID: orm.IntIDDecorator(SpaceID()),
|
90
|
+
CompletionModelID: orm.IntIDDecorator(CompletionModelID()),
|
91
|
+
}
|
92
|
+
)
|
93
|
+
|
94
|
+
|
95
|
+
class Room(orm.BelongsToOrgMixin, orm.SoftDeleteMixin, orm.Base, kw_only=True):
|
96
|
+
"""A Room is a logical collection of Documents."""
|
97
|
+
|
98
|
+
__tablename__ = "room"
|
99
|
+
__table_args__ = (orm.live_unique_constraint("name", "org_id"),)
|
100
|
+
|
101
|
+
name: sa_orm.Mapped[str] = sa_orm.mapped_column(sa.Text, default=None)
|
102
|
+
id: sa_orm.Mapped[RoomID | None] = orm.primary_key_identity_column()
|
103
|
+
|
104
|
+
@property
|
105
|
+
def room_key(self):
|
106
|
+
return self.name
|
107
|
+
|
108
|
+
|
109
|
+
class BelongsToRoomMixin(sa_orm.MappedAsDataclass):
|
110
|
+
room_id: sa_orm.Mapped[RoomID | None] = sa_orm.mapped_column(
|
111
|
+
orm.ForeignKey(Room).make(ondelete="CASCADE"),
|
112
|
+
nullable=True,
|
113
|
+
default=None,
|
114
|
+
)
|
115
|
+
|
116
|
+
|
117
|
+
class DefaultObjects(orm.Base, kw_only=True):
|
118
|
+
"""Holds the identifiers for default objects."""
|
119
|
+
|
120
|
+
__tablename__ = "default_objects"
|
121
|
+
default_org: sa_orm.Mapped[OrgID | None] = sa_orm.mapped_column(
|
122
|
+
orm.ForeignKey(orm.Org).make(ondelete="CASCADE"),
|
123
|
+
nullable=False,
|
124
|
+
)
|
125
|
+
default_room: sa_orm.Mapped[RoomID | None] = sa_orm.mapped_column(
|
126
|
+
orm.ForeignKey(Room).make(ondelete="CASCADE"), nullable=True, default=None
|
127
|
+
)
|
128
|
+
version: sa_orm.Mapped[int | None] = orm.primary_key_identity_column(
|
129
|
+
type_=orm.INT_PK_TYPE
|
130
|
+
)
|
131
|
+
|
132
|
+
|
133
|
+
class Resource(orm.BelongsToOrgMixin, BelongsToRoomMixin, orm.Base, kw_only=True):
|
134
|
+
"""A Resource is a reference to some durably stored file.
|
135
|
+
|
136
|
+
E.g., a document could be a PDF file, an image, or a text transcript of a
|
137
|
+
conversation
|
138
|
+
"""
|
139
|
+
|
140
|
+
__tablename__ = "resource"
|
141
|
+
|
142
|
+
name: sa_orm.Mapped[str] = sa_orm.mapped_column(sa.Text)
|
143
|
+
mime_type: sa_orm.Mapped[str] = sa_orm.mapped_column(sa.Text)
|
144
|
+
url: sa_orm.Mapped[str] = sa_orm.mapped_column(sa.Text)
|
145
|
+
md5: sa_orm.Mapped[str] = sa_orm.mapped_column(sa.CHAR(32), nullable=True)
|
146
|
+
size: sa_orm.Mapped[int] = sa_orm.mapped_column(nullable=True)
|
147
|
+
original_path: sa_orm.Mapped[str] = sa_orm.mapped_column(nullable=True)
|
148
|
+
description: sa_orm.Mapped[str] = sa_orm.mapped_column(nullable=True)
|
149
|
+
id: sa_orm.Mapped[ResourceID | None] = orm.primary_key_identity_column()
|
150
|
+
latest_event: sa_orm.Mapped[event_pb2.Event | None] = sa_orm.mapped_column(
|
151
|
+
default=None, nullable=True
|
152
|
+
)
|
153
|
+
is_terminal: sa_orm.Mapped[bool | None] = sa_orm.mapped_column(
|
154
|
+
default=None, nullable=True
|
155
|
+
)
|
156
|
+
pipeline_ref: sa_orm.Mapped[PipelineInput | None] = sa_orm.relationship(
|
157
|
+
init=False, viewonly=True
|
158
|
+
)
|
159
|
+
|
160
|
+
|
161
|
+
class Source(orm.BelongsToOrgMixin, BelongsToRoomMixin, orm.Base, kw_only=True):
|
162
|
+
"""A source."""
|
163
|
+
|
164
|
+
__tablename__ = "source"
|
165
|
+
__table_args__ = (sa.UniqueConstraint("name", "room_id"),)
|
166
|
+
|
167
|
+
name: sa_orm.Mapped[str] = sa_orm.mapped_column(sa.Text)
|
168
|
+
# protobuf describing the operations required to construct a table
|
169
|
+
table_op_graph: sa_orm.Mapped[table_pb2.TableComputeOp] = sa_orm.mapped_column()
|
170
|
+
id: sa_orm.Mapped[SourceID | None] = orm.primary_key_identity_column()
|
171
|
+
|
172
|
+
source_files: sa_orm.Mapped[common_pb2.BlobUrlList | None] = sa_orm.mapped_column(
|
173
|
+
default=None
|
174
|
+
)
|
175
|
+
pipeline_ref: sa_orm.Mapped[PipelineOutput | None] = sa_orm.relationship(
|
176
|
+
init=False, viewonly=True
|
177
|
+
)
|
178
|
+
|
179
|
+
@property
|
180
|
+
def source_key(self):
|
181
|
+
return self.name
|
182
|
+
|
183
|
+
|
184
|
+
class Pipeline(orm.BelongsToOrgMixin, BelongsToRoomMixin, orm.Base, kw_only=True):
|
185
|
+
"""A resource to source pipeline."""
|
186
|
+
|
187
|
+
__tablename__ = "pipeline"
|
188
|
+
__table_args__ = (sa.UniqueConstraint("name", "room_id"),)
|
189
|
+
|
190
|
+
transformation: sa_orm.Mapped[pipeline_pb2.PipelineTransformation] = (
|
191
|
+
sa_orm.mapped_column()
|
192
|
+
)
|
193
|
+
name: sa_orm.Mapped[str] = sa_orm.mapped_column()
|
194
|
+
description: sa_orm.Mapped[str | None] = sa_orm.mapped_column()
|
195
|
+
id: sa_orm.Mapped[PipelineID | None] = orm.primary_key_identity_column()
|
196
|
+
|
197
|
+
outputs: sa_orm.Mapped[list[PipelineOutput]] = sa_orm.relationship(
|
198
|
+
viewonly=True,
|
199
|
+
init=False,
|
200
|
+
default_factory=list,
|
201
|
+
)
|
202
|
+
|
203
|
+
|
204
|
+
class PipelineInput(orm.BelongsToOrgMixin, BelongsToRoomMixin, orm.Base, kw_only=True):
|
205
|
+
"""Pipeline input resources."""
|
206
|
+
|
207
|
+
__tablename__ = "pipeline_input"
|
208
|
+
__table_args__ = (sa.UniqueConstraint("name", "pipeline_id"),)
|
209
|
+
|
210
|
+
resource: sa_orm.Mapped[Resource] = sa_orm.relationship(viewonly=True, init=False)
|
211
|
+
name: sa_orm.Mapped[str]
|
212
|
+
"""A name the pipeline uses to refer to this input."""
|
213
|
+
|
214
|
+
pipeline_id: sa_orm.Mapped[PipelineID] = orm.primary_key_foreign_column(
|
215
|
+
orm.ForeignKey(Pipeline).make(ondelete="CASCADE")
|
216
|
+
)
|
217
|
+
resource_id: sa_orm.Mapped[ResourceID] = orm.primary_key_foreign_column(
|
218
|
+
orm.ForeignKey(Resource).make(ondelete="CASCADE")
|
219
|
+
)
|
220
|
+
|
221
|
+
|
222
|
+
class PipelineOutput(orm.BelongsToOrgMixin, BelongsToRoomMixin, orm.Base, kw_only=True):
|
223
|
+
"""Objects for tracking pipeline output sources."""
|
224
|
+
|
225
|
+
__tablename__ = "pipeline_output"
|
226
|
+
__table_args__ = (sa.UniqueConstraint("name", "pipeline_id"),)
|
227
|
+
|
228
|
+
source: sa_orm.Mapped[Source] = sa_orm.relationship(viewonly=True, init=False)
|
229
|
+
name: sa_orm.Mapped[str]
|
230
|
+
"""A name the pipeline uses to refer to this output."""
|
231
|
+
|
232
|
+
pipeline_id: sa_orm.Mapped[PipelineID] = orm.primary_key_foreign_column(
|
233
|
+
orm.ForeignKey(Pipeline).make(ondelete="CASCADE")
|
234
|
+
)
|
235
|
+
source_id: sa_orm.Mapped[SourceID] = orm.primary_key_foreign_column(
|
236
|
+
orm.ForeignKey(Source).make(ondelete="CASCADE")
|
237
|
+
)
|
238
|
+
|
239
|
+
|
240
|
+
class FeatureView(
|
241
|
+
orm.SoftDeleteMixin,
|
242
|
+
orm.BelongsToOrgMixin,
|
243
|
+
BelongsToRoomMixin,
|
244
|
+
orm.Base,
|
245
|
+
kw_only=True,
|
246
|
+
):
|
247
|
+
"""A FeatureView is a logical collection of sources used by various spaces."""
|
248
|
+
|
249
|
+
__tablename__ = "feature_view"
|
250
|
+
__table_args__ = (orm.live_unique_constraint("name", "room_id"),)
|
251
|
+
|
252
|
+
id: sa_orm.Mapped[FeatureViewID | None] = orm.primary_key_identity_column()
|
253
|
+
name: sa_orm.Mapped[str] = sa_orm.mapped_column(sa.Text, default=None)
|
254
|
+
description: sa_orm.Mapped[str] = sa_orm.mapped_column(sa.Text, default="")
|
255
|
+
|
256
|
+
feature_view_output: sa_orm.Mapped[feature_view_pb2.FeatureViewOutput | None] = (
|
257
|
+
sa_orm.mapped_column(default_factory=feature_view_pb2.FeatureViewOutput)
|
258
|
+
)
|
259
|
+
|
260
|
+
@property
|
261
|
+
def feature_view_key(self):
|
262
|
+
return self.name
|
263
|
+
|
264
|
+
feature_view_sources: sa_orm.Mapped[list[FeatureViewSource]] = sa_orm.relationship(
|
265
|
+
viewonly=True,
|
266
|
+
init=False,
|
267
|
+
default_factory=list,
|
268
|
+
)
|
269
|
+
|
270
|
+
|
271
|
+
class FeatureViewSource(
|
272
|
+
orm.BelongsToOrgMixin, BelongsToRoomMixin, orm.Base, kw_only=True
|
273
|
+
):
|
274
|
+
"""A source inside of a feature view."""
|
275
|
+
|
276
|
+
__tablename__ = "feature_view_source"
|
277
|
+
|
278
|
+
table_op_graph: sa_orm.Mapped[table_pb2.TableComputeOp] = sa_orm.mapped_column()
|
279
|
+
feature_view_id: sa_orm.Mapped[FeatureViewID] = sa_orm.mapped_column(
|
280
|
+
orm.ForeignKey(FeatureView).make(ondelete="CASCADE"),
|
281
|
+
nullable=False,
|
282
|
+
)
|
283
|
+
id: sa_orm.Mapped[FeatureViewSourceID | None] = orm.primary_key_identity_column()
|
284
|
+
drop_disconnected: sa_orm.Mapped[bool] = sa_orm.mapped_column(default=False)
|
285
|
+
# this should be legal but pyright complains that it makes Source depend
|
286
|
+
# on itself
|
287
|
+
source_id: sa_orm.Mapped[SourceID] = sa_orm.mapped_column(
|
288
|
+
orm.ForeignKey(Source).make(ondelete="CASCADE"),
|
289
|
+
nullable=False,
|
290
|
+
default=None,
|
291
|
+
)
|
292
|
+
source: sa_orm.Mapped[Source] = sa_orm.relationship(
|
293
|
+
init=True, viewonly=True, default=None
|
294
|
+
)
|
295
|
+
|
296
|
+
|
297
|
+
class Space(orm.BelongsToOrgMixin, BelongsToRoomMixin, orm.Base, kw_only=True):
|
298
|
+
"""A space is a named evaluation of space parameters."""
|
299
|
+
|
300
|
+
__tablename__ = "space"
|
301
|
+
__table_args__ = (sa.UniqueConstraint("name", "room_id"),)
|
302
|
+
|
303
|
+
id: sa_orm.Mapped[SpaceID | None] = orm.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="")
|
306
|
+
|
307
|
+
feature_view_id: sa_orm.Mapped[FeatureViewID] = sa_orm.mapped_column(
|
308
|
+
orm.ForeignKey(FeatureView).make(ondelete="CASCADE"),
|
309
|
+
nullable=False,
|
310
|
+
default=None,
|
311
|
+
)
|
312
|
+
parameters: sa_orm.Mapped[space_pb2.SpaceParameters | None] = sa_orm.mapped_column(
|
313
|
+
default=None
|
314
|
+
)
|
315
|
+
auto_sync: sa_orm.Mapped[bool | None] = sa_orm.mapped_column(default=None)
|
316
|
+
feature_view: sa_orm.Mapped[FeatureView] = sa_orm.relationship(
|
317
|
+
init=False,
|
318
|
+
default=None,
|
319
|
+
viewonly=True,
|
320
|
+
)
|
321
|
+
|
322
|
+
@property
|
323
|
+
def space_key(self):
|
324
|
+
return self.name
|
325
|
+
|
326
|
+
|
327
|
+
class CompletionModel(
|
328
|
+
orm.SoftDeleteMixin, orm.BelongsToOrgMixin, orm.Base, kw_only=True
|
329
|
+
):
|
330
|
+
"""A customer's custom completion model definition."""
|
331
|
+
|
332
|
+
__tablename__ = "completion_model"
|
333
|
+
__table_args__ = (orm.live_unique_constraint("name", "org_id"),)
|
334
|
+
|
335
|
+
id: sa_orm.Mapped[CompletionModelID | None] = orm.primary_key_identity_column()
|
336
|
+
name: sa_orm.Mapped[str] = sa_orm.mapped_column(sa.Text, default=None)
|
337
|
+
description: sa_orm.Mapped[str] = sa_orm.mapped_column(sa.Text, default=None)
|
338
|
+
parameters: sa_orm.Mapped[completion_model_pb2.CompletionModelParameters | None] = (
|
339
|
+
sa_orm.mapped_column(default=None)
|
340
|
+
)
|
341
|
+
secret_api_key: sa_orm.Mapped[str] = sa_orm.mapped_column(sa.Text, default=None)
|
342
|
+
last_validation_time: sa_orm.Mapped[datetime | None] = sa_orm.mapped_column(
|
343
|
+
sa.DateTime(timezone=True),
|
344
|
+
server_default=None,
|
345
|
+
default=None,
|
346
|
+
)
|
347
|
+
last_successful_validation: sa_orm.Mapped[datetime | None] = sa_orm.mapped_column(
|
348
|
+
sa.DateTime(timezone=True),
|
349
|
+
server_default=None,
|
350
|
+
default=None,
|
351
|
+
)
|
352
|
+
|
353
|
+
@property
|
354
|
+
def model_key(self):
|
355
|
+
return self.name
|
356
|
+
|
357
|
+
|
358
|
+
ID = (
|
359
|
+
orm.ID
|
360
|
+
| CompletionModelID
|
361
|
+
| FeatureViewID
|
362
|
+
| FeatureViewSourceID
|
363
|
+
| PipelineID
|
364
|
+
| ResourceID
|
365
|
+
| RoomID
|
366
|
+
| SourceID
|
367
|
+
| SpaceID
|
368
|
+
)
|
369
|
+
|
370
|
+
# These are part of the public interface, exposing them here so that
|
371
|
+
# users don't have to import orm anytime they import eorm
|
372
|
+
Base: TypeAlias = orm.Base
|
373
|
+
Org: TypeAlias = orm.Org
|
374
|
+
Session: TypeAlias = orm.Session
|
375
|
+
|
376
|
+
InvalidORMIdentifierError: TypeAlias = orm.InvalidORMIdentifierError
|
377
|
+
RequestedObjectsForNobodyError: TypeAlias = orm.RequestedObjectsForNobodyError
|
378
|
+
|
379
|
+
__all__ = [
|
380
|
+
"Base",
|
381
|
+
"CompletionModel",
|
382
|
+
"CompletionModelID",
|
383
|
+
"DefaultObjects",
|
384
|
+
"FeatureView",
|
385
|
+
"FeatureViewID",
|
386
|
+
"FeatureViewSource",
|
387
|
+
"FeatureViewSourceID",
|
388
|
+
"ID",
|
389
|
+
"InvalidORMIdentifierError",
|
390
|
+
"OrgID",
|
391
|
+
"PipelineID",
|
392
|
+
"PipelineInput",
|
393
|
+
"PipelineOutput",
|
394
|
+
"RequestedObjectsForNobodyError",
|
395
|
+
"Resource",
|
396
|
+
"ResourceID",
|
397
|
+
"Room",
|
398
|
+
"RoomID",
|
399
|
+
"Session",
|
400
|
+
"Source",
|
401
|
+
"SourceID",
|
402
|
+
"Space",
|
403
|
+
"SpaceID",
|
404
|
+
]
|
corvic/model/_base_model.py
CHANGED
@@ -12,10 +12,10 @@ import sqlalchemy.orm as sa_orm
|
|
12
12
|
import structlog
|
13
13
|
from google.protobuf import timestamp_pb2
|
14
14
|
|
15
|
-
from corvic import
|
15
|
+
from corvic import eorm, system
|
16
16
|
from corvic.model._proto_orm_convert import (
|
17
|
-
ID,
|
18
17
|
UNCOMMITTED_ID_PREFIX,
|
18
|
+
IdType,
|
19
19
|
OrmBelongsToOrgObj,
|
20
20
|
OrmBelongsToRoomObj,
|
21
21
|
OrmObj,
|
@@ -54,7 +54,7 @@ def _create_or_join_session(
|
|
54
54
|
if existing_session:
|
55
55
|
yield existing_session
|
56
56
|
else:
|
57
|
-
with
|
57
|
+
with eorm.Session(client.sa_engine) as session:
|
58
58
|
yield session
|
59
59
|
|
60
60
|
|
@@ -71,7 +71,7 @@ class HasProtoSelf(Generic[ProtoObj], abc.ABC):
|
|
71
71
|
return non_empty_timestamp_to_datetime(self.proto_self.created_at)
|
72
72
|
|
73
73
|
|
74
|
-
class UsesOrmID(Generic[
|
74
|
+
class UsesOrmID(Generic[IdType, ProtoObj], HasProtoSelf[ProtoObj]):
|
75
75
|
def __init__(self, client: system.Client, proto_self: ProtoObj):
|
76
76
|
if not proto_self.id:
|
77
77
|
proto_self.id = _generate_uncommitted_id_str()
|
@@ -79,14 +79,14 @@ class UsesOrmID(Generic[ID, ProtoObj], HasProtoSelf[ProtoObj]):
|
|
79
79
|
|
80
80
|
@classmethod
|
81
81
|
@abc.abstractmethod
|
82
|
-
def id_class(cls) -> type[
|
82
|
+
def id_class(cls) -> type[IdType]: ...
|
83
83
|
|
84
84
|
@functools.cached_property
|
85
|
-
def id(self) ->
|
85
|
+
def id(self) -> IdType:
|
86
86
|
return self.id_class().from_str(self.proto_self.id)
|
87
87
|
|
88
88
|
|
89
|
-
class BaseModel(Generic[
|
89
|
+
class BaseModel(Generic[IdType, ProtoObj, OrmObj], UsesOrmID[IdType, ProtoObj]):
|
90
90
|
"""Base for orm wrappers providing a unified update mechanism."""
|
91
91
|
|
92
92
|
@property
|
@@ -104,19 +104,19 @@ class BaseModel(Generic[ID, ProtoObj, OrmObj], UsesOrmID[ID, ProtoObj]):
|
|
104
104
|
@classmethod
|
105
105
|
@abc.abstractmethod
|
106
106
|
def proto_to_orm(
|
107
|
-
cls, proto_obj: ProtoObj, session:
|
107
|
+
cls, proto_obj: ProtoObj, session: eorm.Session
|
108
108
|
) -> Ok[OrmObj] | InvalidArgumentError: ...
|
109
109
|
|
110
110
|
@classmethod
|
111
111
|
@abc.abstractmethod
|
112
112
|
def delete_by_ids(
|
113
|
-
cls, ids: Sequence[
|
113
|
+
cls, ids: Sequence[IdType], session: eorm.Session
|
114
114
|
) -> Ok[None] | InvalidArgumentError: ...
|
115
115
|
|
116
116
|
@classmethod
|
117
117
|
def load_proto_for(
|
118
118
|
cls,
|
119
|
-
obj_id:
|
119
|
+
obj_id: IdType,
|
120
120
|
client: system.Client,
|
121
121
|
existing_session: sa_orm.Session | None = None,
|
122
122
|
) -> Ok[ProtoObj] | NotFoundError:
|
@@ -155,9 +155,9 @@ class BaseModel(Generic[ID, ProtoObj, OrmObj], UsesOrmID[ID, ProtoObj]):
|
|
155
155
|
client: system.Client,
|
156
156
|
*,
|
157
157
|
limit: int | None = None,
|
158
|
-
room_id:
|
158
|
+
room_id: eorm.RoomID | None = None,
|
159
159
|
created_before: datetime.datetime | None = None,
|
160
|
-
ids: Iterable[
|
160
|
+
ids: Iterable[IdType] | None = None,
|
161
161
|
additional_query_transform: Callable[
|
162
162
|
[sa.Select[tuple[OrmObj]]], sa.Select[tuple[OrmObj]]
|
163
163
|
]
|
@@ -173,7 +173,7 @@ class BaseModel(Generic[ID, ProtoObj, OrmObj], UsesOrmID[ID, ProtoObj]):
|
|
173
173
|
return InvalidArgumentError("limit cannot be negative")
|
174
174
|
query = query.limit(limit)
|
175
175
|
if room_id:
|
176
|
-
if session.get(
|
176
|
+
if session.get(eorm.Room, room_id) is None:
|
177
177
|
return NotFoundError("room not found", room_id=room_id)
|
178
178
|
query = query.filter_by(room_id=room_id)
|
179
179
|
if created_before:
|
@@ -198,7 +198,7 @@ class BaseModel(Generic[ID, ProtoObj, OrmObj], UsesOrmID[ID, ProtoObj]):
|
|
198
198
|
This overwrites the entry at id in the database so that future readers will see
|
199
199
|
this object. One of `id` or `derived_from_id` cannot be empty or None.
|
200
200
|
"""
|
201
|
-
with
|
201
|
+
with eorm.Session(self.client.sa_engine) as session:
|
202
202
|
try:
|
203
203
|
new_orm_self = self.proto_to_orm(
|
204
204
|
self.proto_self, session
|
@@ -230,7 +230,7 @@ class BaseModel(Generic[ID, ProtoObj, OrmObj], UsesOrmID[ID, ProtoObj]):
|
|
230
230
|
return InvalidArgumentError.from_(err)
|
231
231
|
|
232
232
|
def add_to_session(
|
233
|
-
self, session:
|
233
|
+
self, session: eorm.Session
|
234
234
|
) -> Ok[None] | InvalidArgumentError | UnavailableError:
|
235
235
|
"""Like commit, but just calls session.flush to check for database errors.
|
236
236
|
|
@@ -247,7 +247,7 @@ class BaseModel(Generic[ID, ProtoObj, OrmObj], UsesOrmID[ID, ProtoObj]):
|
|
247
247
|
return Ok(None)
|
248
248
|
|
249
249
|
def delete(self) -> Ok[Self] | NotFoundError | InvalidArgumentError:
|
250
|
-
with
|
250
|
+
with eorm.Session(
|
251
251
|
self.client.sa_engine, expire_on_commit=False, autoflush=False
|
252
252
|
) as session:
|
253
253
|
try:
|
@@ -272,22 +272,22 @@ class BaseModel(Generic[ID, ProtoObj, OrmObj], UsesOrmID[ID, ProtoObj]):
|
|
272
272
|
|
273
273
|
|
274
274
|
class BelongsToOrgModel(
|
275
|
-
Generic[
|
276
|
-
BaseModel[
|
275
|
+
Generic[IdType, ProtoBelongsToOrgObj, OrmBelongsToOrgObj],
|
276
|
+
BaseModel[IdType, ProtoBelongsToOrgObj, OrmBelongsToOrgObj],
|
277
277
|
):
|
278
278
|
"""Base for orm wrappers with org mixin providing a unified update mechanism."""
|
279
279
|
|
280
280
|
@property
|
281
|
-
def org_id(self) ->
|
282
|
-
return
|
281
|
+
def org_id(self) -> eorm.OrgID:
|
282
|
+
return eorm.OrgID().from_str(self.proto_self.org_id)
|
283
283
|
|
284
284
|
|
285
285
|
class BelongsToRoomModel(
|
286
|
-
Generic[
|
287
|
-
BelongsToOrgModel[
|
286
|
+
Generic[IdType, ProtoBelongsToRoomObj, OrmBelongsToRoomObj],
|
287
|
+
BelongsToOrgModel[IdType, ProtoBelongsToRoomObj, OrmBelongsToRoomObj],
|
288
288
|
):
|
289
289
|
"""Base for orm wrappers with room mixin providing a unified update mechanism."""
|
290
290
|
|
291
291
|
@property
|
292
|
-
def room_id(self) ->
|
293
|
-
return
|
292
|
+
def room_id(self) -> eorm.RoomID:
|
293
|
+
return eorm.RoomID().from_str(self.proto_self.room_id)
|
@@ -9,7 +9,7 @@ from typing import Literal, TypeAlias
|
|
9
9
|
|
10
10
|
from sqlalchemy import orm as sa_orm
|
11
11
|
|
12
|
-
from corvic import
|
12
|
+
from corvic import eorm, system
|
13
13
|
from corvic.model._base_model import BelongsToOrgModel, non_empty_timestamp_to_datetime
|
14
14
|
from corvic.model._defaults import Defaults
|
15
15
|
from corvic.model._proto_orm_convert import (
|
@@ -21,38 +21,38 @@ from corvic.result import InvalidArgumentError, NotFoundError, Ok
|
|
21
21
|
from corvic_generated.model.v1alpha import models_pb2
|
22
22
|
from corvic_generated.orm.v1 import completion_model_pb2
|
23
23
|
|
24
|
-
CompletionModelID: TypeAlias =
|
25
|
-
OrgID: TypeAlias =
|
24
|
+
CompletionModelID: TypeAlias = eorm.CompletionModelID
|
25
|
+
OrgID: TypeAlias = eorm.OrgID
|
26
26
|
|
27
27
|
|
28
28
|
class CompletionModel(
|
29
29
|
BelongsToOrgModel[
|
30
|
-
CompletionModelID, models_pb2.CompletionModel,
|
30
|
+
CompletionModelID, models_pb2.CompletionModel, eorm.CompletionModel
|
31
31
|
]
|
32
32
|
):
|
33
33
|
"""Completion Models."""
|
34
34
|
|
35
35
|
@classmethod
|
36
36
|
def orm_class(cls):
|
37
|
-
return
|
37
|
+
return eorm.CompletionModel
|
38
38
|
|
39
39
|
@classmethod
|
40
40
|
def id_class(cls):
|
41
41
|
return CompletionModelID
|
42
42
|
|
43
43
|
@classmethod
|
44
|
-
def orm_to_proto(cls, orm_obj:
|
44
|
+
def orm_to_proto(cls, orm_obj: eorm.CompletionModel) -> models_pb2.CompletionModel:
|
45
45
|
return completion_model_orm_to_proto(orm_obj)
|
46
46
|
|
47
47
|
@classmethod
|
48
48
|
def proto_to_orm(
|
49
|
-
cls, proto_obj: models_pb2.CompletionModel, session:
|
50
|
-
) -> Ok[
|
49
|
+
cls, proto_obj: models_pb2.CompletionModel, session: eorm.Session
|
50
|
+
) -> Ok[eorm.CompletionModel] | InvalidArgumentError:
|
51
51
|
return completion_model_proto_to_orm(proto_obj, session)
|
52
52
|
|
53
53
|
@classmethod
|
54
54
|
def delete_by_ids(
|
55
|
-
cls, ids: Sequence[CompletionModelID], session:
|
55
|
+
cls, ids: Sequence[CompletionModelID], session: eorm.Session
|
56
56
|
) -> Ok[None] | InvalidArgumentError:
|
57
57
|
return completion_model_delete_orms(ids, session)
|
58
58
|
|
corvic/model/_defaults.py
CHANGED
@@ -6,7 +6,7 @@ import tempfile
|
|
6
6
|
|
7
7
|
import sqlalchemy as sa
|
8
8
|
|
9
|
-
from corvic import
|
9
|
+
from corvic import eorm, system, system_sqlite
|
10
10
|
from corvic.result import NotFoundError
|
11
11
|
|
12
12
|
|
@@ -33,11 +33,11 @@ class Defaults:
|
|
33
33
|
return _default_default_client()
|
34
34
|
|
35
35
|
@staticmethod
|
36
|
-
def get_default_room_id(client: system.Client) ->
|
37
|
-
with
|
36
|
+
def get_default_room_id(client: system.Client) -> eorm.RoomID:
|
37
|
+
with eorm.Session(client.sa_engine) as session:
|
38
38
|
defaults_row = session.scalars(
|
39
|
-
sa.select(
|
40
|
-
.order_by(
|
39
|
+
sa.select(eorm.DefaultObjects)
|
40
|
+
.order_by(eorm.DefaultObjects.version.desc())
|
41
41
|
.limit(1)
|
42
42
|
).one_or_none()
|
43
43
|
if not defaults_row or not defaults_row.default_room:
|