corvic-engine 0.3.0rc54__cp38-abi3-win_amd64.whl → 0.3.0rc56__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.
@@ -1,6 +1,6 @@
1
1
  import datetime
2
2
  from collections.abc import Callable, Sequence
3
- from typing import Any, Protocol, TypeVar, cast
3
+ from typing import Any, Protocol, TypeVar
4
4
 
5
5
  import sqlalchemy as sa
6
6
  import sqlalchemy.orm as sa_orm
@@ -14,26 +14,30 @@ from corvic_generated.orm.v1 import feature_view_pb2
14
14
 
15
15
  UNCOMMITTED_ID_PREFIX = "__uncommitted_object-"
16
16
 
17
- _Proto = TypeVar(
18
- "_Proto",
19
- models_pb2.Resource,
20
- models_pb2.Source,
21
- models_pb2.FeatureView,
22
- models_pb2.Space,
23
- models_pb2.FeatureViewSource,
24
- models_pb2.Agent,
25
- models_pb2.Pipeline,
26
- models_pb2.Room,
27
- models_pb2.CompletionModel,
28
- )
29
17
  ID = TypeVar("ID", bound=orm.BaseID[Any])
30
18
 
31
19
 
20
+ class _ModelProto(Protocol):
21
+ id: str
22
+ created_at: timestamp_pb2.Timestamp
23
+
24
+
25
+ class _ModelBelongsToOrgProto(_ModelProto, Protocol):
26
+ org_id: str
27
+
28
+
29
+ class _ModelBelongsToRoomProto(_ModelBelongsToOrgProto, Protocol):
30
+ room_id: str
31
+
32
+
33
+ ProtoObj = TypeVar("ProtoObj", bound=_ModelProto)
34
+ ProtoBelongsToOrgObj = TypeVar("ProtoBelongsToOrgObj", bound=_ModelBelongsToOrgProto)
35
+ ProtoBelongsToRoomObj = TypeVar("ProtoBelongsToRoomObj", bound=_ModelBelongsToRoomProto)
36
+
37
+
32
38
  class _OrmModel(Protocol[ID]):
33
39
  id: sa_orm.Mapped[ID | None]
34
40
 
35
- org_id: sa_orm.Mapped[orm.OrgID | None]
36
-
37
41
  @sa.ext.hybrid.hybrid_property
38
42
  def created_at(self) -> datetime.datetime | None: ...
39
43
 
@@ -42,7 +46,17 @@ class _OrmModel(Protocol[ID]):
42
46
  def _created_at_expression(cls): ...
43
47
 
44
48
 
49
+ class _OrmBelongsToOrgModel(_OrmModel[ID], Protocol):
50
+ org_id: sa_orm.Mapped[orm.OrgID | None]
51
+
52
+
53
+ class _OrmBelongsToRoomModel(_OrmBelongsToOrgModel[ID], Protocol):
54
+ room_id: sa_orm.Mapped[orm.RoomID | None]
55
+
56
+
45
57
  OrmObj = TypeVar("OrmObj", bound=_OrmModel[Any])
58
+ OrmBelongsToOrgObj = TypeVar("OrmBelongsToOrgObj", bound=_OrmBelongsToOrgModel[Any])
59
+ OrmBelongsToRoomObj = TypeVar("OrmBelongsToRoomObj", bound=_OrmBelongsToRoomModel[Any])
46
60
 
47
61
 
48
62
  def _translate_orm_id(
@@ -58,39 +72,6 @@ def _translate_orm_id(
58
72
  return Ok(parsed_obj_id)
59
73
 
60
74
 
61
- def _translate_orm_ids(
62
- proto_obj: _Proto, obj_id_class: type[ID]
63
- ) -> Ok[tuple[ID | None, orm.RoomID | None]] | orm.InvalidORMIdentifierError:
64
- match _translate_orm_id(proto_obj.id, obj_id_class):
65
- case orm.InvalidORMIdentifierError() as err:
66
- return err
67
- case Ok(obj_id):
68
- pass
69
-
70
- match proto_obj:
71
- case (
72
- models_pb2.Resource()
73
- | models_pb2.Source()
74
- | models_pb2.FeatureView()
75
- | models_pb2.Space()
76
- | models_pb2.Agent()
77
- | models_pb2.Pipeline()
78
- | models_pb2.FeatureViewSource()
79
- ):
80
- room_id = orm.RoomID(proto_obj.room_id)
81
- match room_id.to_db():
82
- case orm.InvalidORMIdentifierError() as err:
83
- return err
84
- case Ok():
85
- pass
86
- case models_pb2.CompletionModel():
87
- room_id = None
88
- case models_pb2.Room():
89
- room_id = cast(orm.RoomID, obj_id)
90
-
91
- return Ok((obj_id, room_id))
92
-
93
-
94
75
  def timestamp_orm_to_proto(
95
76
  timestamp_orm: datetime.datetime | None,
96
77
  ) -> timestamp_pb2.Timestamp | None:
@@ -241,46 +222,57 @@ def completion_model_orm_to_proto(
241
222
  parameters=completion_model_orm.parameters,
242
223
  secret_api_key=completion_model_orm.secret_api_key,
243
224
  created_at=timestamp_orm_to_proto(completion_model_orm.created_at),
225
+ last_validation_time=timestamp_orm_to_proto(
226
+ completion_model_orm.last_validation_time
227
+ ),
244
228
  )
245
229
 
246
230
 
247
- def _add_orm_to_session(
248
- orm_obj: OrmObj, org_id: str, session: sa_orm.Session
249
- ) -> OrmObj:
250
- if org_id:
251
- orm_obj.org_id = orm.OrgID(org_id)
231
+ def add_orm_org_mixin_to_session(
232
+ orm_obj: OrmBelongsToOrgObj,
233
+ proto_obj: _ModelBelongsToOrgProto,
234
+ id_class: type[ID],
235
+ session: sa_orm.Session,
236
+ ) -> Ok[OrmBelongsToOrgObj] | orm.InvalidORMIdentifierError:
237
+ match _translate_orm_id(proto_obj.id, id_class):
238
+ case Ok(orm_id):
239
+ orm_obj.id = orm_id
240
+ case orm.InvalidORMIdentifierError() as err:
241
+ return err
242
+ if proto_obj.org_id:
243
+ org_id = orm.OrgID(proto_obj.org_id)
244
+ match org_id.to_db():
245
+ case Ok():
246
+ orm_obj.org_id = org_id
247
+ case orm.InvalidORMIdentifierError() as err:
248
+ return err
249
+ orm_obj.org_id = org_id
252
250
  if not orm_obj.id:
253
251
  session.add(orm_obj)
254
252
  else:
255
253
  orm_obj = session.merge(orm_obj)
256
- return orm_obj
254
+ return Ok(orm_obj)
257
255
 
258
256
 
259
- def resource_proto_to_orm(
260
- proto_obj: models_pb2.Resource, session: sa_orm.Session
261
- ) -> Ok[orm.Resource] | InvalidArgumentError:
262
- match _translate_orm_ids(proto_obj, orm.ResourceID):
257
+ def add_orm_room_mixin_to_session(
258
+ orm_obj: OrmBelongsToRoomObj,
259
+ proto_obj: _ModelBelongsToRoomProto,
260
+ id_class: type[ID],
261
+ session: sa_orm.Session,
262
+ ) -> Ok[OrmBelongsToRoomObj] | orm.InvalidORMIdentifierError:
263
+ room_id = orm.RoomID(proto_obj.room_id)
264
+ match room_id.to_db():
265
+ case Ok():
266
+ pass
263
267
  case orm.InvalidORMIdentifierError() as err:
264
268
  return err
265
- case Ok((obj_id, room_id)):
266
- pass
267
- if not room_id:
268
- return InvalidArgumentError("room id required to commit")
269
+ orm_obj.room_id = orm.RoomID(proto_obj.room_id)
270
+ return add_orm_org_mixin_to_session(orm_obj, proto_obj, id_class, session)
269
271
 
270
- orm_obj = orm.Resource(
271
- id=obj_id,
272
- name=proto_obj.name,
273
- description=proto_obj.description,
274
- mime_type=proto_obj.mime_type,
275
- md5=proto_obj.md5,
276
- url=proto_obj.url,
277
- size=proto_obj.size,
278
- original_path=proto_obj.original_path,
279
- latest_event=proto_obj.recent_events[-1] if proto_obj.recent_events else None,
280
- room_id=room_id,
281
- )
282
- _add_orm_to_session(orm_obj, proto_obj.org_id, session)
283
272
 
273
+ def _resource_pipeline_to_orm(
274
+ proto_obj: models_pb2.Resource, orm_obj: orm.Resource, session: sa_orm.Session
275
+ ) -> Ok[None] | InvalidArgumentError:
284
276
  if proto_obj.pipeline_id:
285
277
  match _translate_orm_id(proto_obj.pipeline_id, orm.PipelineID):
286
278
  case orm.InvalidORMIdentifierError() as err:
@@ -296,18 +288,41 @@ def resource_proto_to_orm(
296
288
  resource_id=orm_obj.id,
297
289
  name=proto_obj.pipeline_input_name,
298
290
  pipeline_id=pipeline_id,
299
- room_id=room_id,
291
+ room_id=orm_obj.room_id,
300
292
  )
301
293
  if orm_obj.org_id:
302
294
  pipeline_input.org_id = orm_obj.org_id
303
295
  orm_obj.pipeline_ref = session.merge(pipeline_input)
296
+ return Ok(None)
304
297
 
305
- return Ok(orm_obj)
298
+
299
+ def resource_proto_to_orm(
300
+ proto_obj: models_pb2.Resource, session: sa_orm.Session
301
+ ) -> Ok[orm.Resource] | InvalidArgumentError:
302
+ orm_obj = orm.Resource(
303
+ name=proto_obj.name,
304
+ description=proto_obj.description,
305
+ mime_type=proto_obj.mime_type,
306
+ md5=proto_obj.md5,
307
+ url=proto_obj.url,
308
+ size=proto_obj.size,
309
+ original_path=proto_obj.original_path,
310
+ latest_event=proto_obj.recent_events[-1] if proto_obj.recent_events else None,
311
+ )
312
+ add_orm_room_mixin_to_session(orm_obj, proto_obj, orm.ResourceID, session)
313
+
314
+ match _resource_pipeline_to_orm(proto_obj, orm_obj, session):
315
+ case Ok(None):
316
+ return Ok(orm_obj)
317
+ case InvalidArgumentError() as err:
318
+ return err
306
319
 
307
320
 
308
321
  def _ensure_id(
309
- proto_obj: _Proto,
310
- proto_to_orm: Callable[[_Proto, sa_orm.Session], Ok[OrmObj] | InvalidArgumentError],
322
+ proto_obj: ProtoObj,
323
+ proto_to_orm: Callable[
324
+ [ProtoObj, sa_orm.Session], Ok[OrmObj] | InvalidArgumentError
325
+ ],
311
326
  id_type: type[ID],
312
327
  session: sa_orm.Session,
313
328
  ) -> Ok[ID] | orm.InvalidORMIdentifierError | InvalidArgumentError:
@@ -330,23 +345,19 @@ def _ensure_id(
330
345
  def pipeline_proto_to_orm( # noqa: C901
331
346
  proto_obj: models_pb2.Pipeline, session: sa_orm.Session
332
347
  ) -> Ok[orm.Pipeline] | orm.InvalidORMIdentifierError | InvalidArgumentError:
333
- match _translate_orm_ids(proto_obj, orm.PipelineID):
334
- case orm.InvalidORMIdentifierError() as err:
335
- return err
336
- case Ok((obj_id, room_id)):
337
- pass
338
- if not room_id:
339
- return InvalidArgumentError("room id required to commit")
340
-
341
348
  inputs = list[orm.PipelineInput]()
342
349
  orm_obj = orm.Pipeline(
343
- id=obj_id,
344
350
  name=proto_obj.name,
345
- room_id=room_id,
346
351
  transformation=proto_obj.pipeline_transformation,
347
352
  description=proto_obj.description,
348
353
  )
349
- orm_obj = _add_orm_to_session(orm_obj, proto_obj.org_id, session)
354
+ if proto_obj.org_id:
355
+ orm_obj.org_id = orm.OrgID(proto_obj.org_id)
356
+ match add_orm_room_mixin_to_session(orm_obj, proto_obj, orm.PipelineID, session):
357
+ case Ok(orm_obj):
358
+ pass
359
+ case orm.InvalidORMIdentifierError() as err:
360
+ return err
350
361
  session.flush()
351
362
 
352
363
  if not orm_obj.id:
@@ -361,7 +372,10 @@ def pipeline_proto_to_orm( # noqa: C901
361
372
  pass
362
373
  outputs.append(
363
374
  orm.PipelineOutput(
364
- source_id=source_id, name=name, pipeline_id=orm_obj.id, room_id=room_id
375
+ source_id=source_id,
376
+ name=name,
377
+ pipeline_id=orm_obj.id,
378
+ room_id=orm_obj.room_id,
365
379
  )
366
380
  )
367
381
 
@@ -377,21 +391,11 @@ def pipeline_proto_to_orm( # noqa: C901
377
391
  def source_proto_to_orm(
378
392
  proto_obj: models_pb2.Source, session: sa_orm.Session
379
393
  ) -> Ok[orm.Source] | orm.InvalidORMIdentifierError | InvalidArgumentError:
380
- match _translate_orm_ids(proto_obj, orm.SourceID):
381
- case orm.InvalidORMIdentifierError() as err:
382
- return err
383
- case Ok((obj_id, room_id)):
384
- pass
385
- if not room_id:
386
- return InvalidArgumentError("room id required to commit")
387
-
388
394
  orm_obj = orm.Source(
389
- id=obj_id,
390
395
  name=proto_obj.name,
391
396
  table_op_graph=proto_obj.table_op_graph,
392
- room_id=room_id,
393
397
  )
394
- return Ok(_add_orm_to_session(orm_obj, proto_obj.org_id, session))
398
+ return add_orm_room_mixin_to_session(orm_obj, proto_obj, orm.SourceID, session)
395
399
 
396
400
 
397
401
  def _update_agent_associations(
@@ -428,21 +432,15 @@ def _update_agent_associations(
428
432
  def agent_proto_to_orm(
429
433
  proto_obj: models_pb2.Agent, session: sa_orm.Session
430
434
  ) -> Ok[orm.Agent] | orm.InvalidORMIdentifierError | InvalidArgumentError:
431
- match _translate_orm_ids(proto_obj, orm.AgentID):
432
- case orm.InvalidORMIdentifierError() as err:
433
- return err
434
- case Ok((obj_id, room_id)):
435
- pass
436
- if not room_id:
437
- return InvalidArgumentError("room id required to commit")
438
-
439
435
  orm_obj = orm.Agent(
440
- id=obj_id,
441
436
  name=proto_obj.name,
442
437
  parameters=proto_obj.agent_parameters,
443
- room_id=room_id,
444
438
  )
445
- agent = _add_orm_to_session(orm_obj, proto_obj.org_id, session)
439
+ match add_orm_room_mixin_to_session(orm_obj, proto_obj, orm.AgentID, session):
440
+ case Ok(agent):
441
+ pass
442
+ case orm.InvalidORMIdentifierError() as err:
443
+ return err
446
444
  session.flush()
447
445
 
448
446
  if not agent.id:
@@ -459,14 +457,6 @@ def agent_proto_to_orm(
459
457
  def space_proto_to_orm(
460
458
  proto_obj: models_pb2.Space, session: sa_orm.Session
461
459
  ) -> Ok[orm.Space] | orm.InvalidORMIdentifierError | InvalidArgumentError:
462
- match _translate_orm_ids(proto_obj, orm.SpaceID):
463
- case orm.InvalidORMIdentifierError() as err:
464
- return err
465
- case Ok((obj_id, room_id)):
466
- pass
467
- if not room_id:
468
- return InvalidArgumentError("room id required to commit")
469
-
470
460
  match _ensure_id(
471
461
  proto_obj.feature_view, feature_view_proto_to_orm, orm.FeatureViewID, session
472
462
  ):
@@ -479,38 +469,29 @@ def space_proto_to_orm(
479
469
  raise InternalError("internal assertion did not hold")
480
470
 
481
471
  orm_obj = orm.Space(
482
- id=obj_id,
483
472
  name=proto_obj.name,
484
473
  description=proto_obj.description,
485
- room_id=room_id,
486
474
  feature_view_id=feature_view_id,
487
475
  parameters=proto_obj.space_parameters,
488
476
  auto_sync=proto_obj.auto_sync,
489
477
  )
490
- return Ok(_add_orm_to_session(orm_obj, proto_obj.org_id, session))
478
+ return add_orm_room_mixin_to_session(orm_obj, proto_obj, orm.SpaceID, session)
491
479
 
492
480
 
493
- def feature_view_proto_to_orm( # noqa: C901
481
+ def feature_view_proto_to_orm(
494
482
  proto_obj: models_pb2.FeatureView, session: sa_orm.Session
495
483
  ) -> Ok[orm.FeatureView] | orm.InvalidORMIdentifierError | InvalidArgumentError:
496
- match _translate_orm_ids(proto_obj, orm.FeatureViewID):
497
- case orm.InvalidORMIdentifierError() as err:
498
- return err
499
- case Ok((obj_id, room_id)):
500
- pass
501
- if not room_id:
502
- return InvalidArgumentError("room id required to commit")
503
-
504
484
  orm_obj = orm.FeatureView(
505
- id=obj_id,
506
485
  name=proto_obj.name,
507
486
  description=proto_obj.description,
508
- room_id=room_id,
509
487
  )
510
488
  if proto_obj.org_id:
511
489
  orm_obj.org_id = orm.OrgID(proto_obj.org_id)
512
-
513
- orm_obj = _add_orm_to_session(orm_obj, proto_obj.org_id, session)
490
+ match add_orm_room_mixin_to_session(orm_obj, proto_obj, orm.FeatureViewID, session):
491
+ case Ok(orm_obj):
492
+ pass
493
+ case orm.InvalidORMIdentifierError() as err:
494
+ return err
514
495
  session.flush()
515
496
 
516
497
  if not orm_obj.id:
@@ -570,56 +551,38 @@ def _feature_view_source_proto_to_orm(
570
551
  return err
571
552
  case Ok(source_id):
572
553
  pass
573
- match _translate_orm_id(proto_obj.id, orm.FeatureViewSourceID):
574
- case orm.InvalidORMIdentifierError() as err:
575
- return err
576
- case Ok(obj_id):
577
- pass
578
554
 
579
555
  orm_obj = orm.FeatureViewSource(
580
- room_id=orm.RoomID(proto_obj.room_id),
581
- id=obj_id,
582
556
  table_op_graph=proto_obj.table_op_graph,
583
557
  drop_disconnected=proto_obj.drop_disconnected,
584
558
  source_id=source_id,
585
559
  feature_view_id=feature_view_id,
586
560
  )
587
- return Ok(_add_orm_to_session(orm_obj, proto_obj.org_id, session))
561
+ return add_orm_room_mixin_to_session(
562
+ orm_obj, proto_obj, orm.FeatureViewSourceID, session
563
+ )
588
564
 
589
565
 
590
566
  def room_proto_to_orm(
591
567
  proto_obj: models_pb2.Room, session: sa_orm.Session
592
568
  ) -> Ok[orm.Room] | orm.InvalidORMIdentifierError | InvalidArgumentError:
593
- match _translate_orm_ids(proto_obj, orm.RoomID):
594
- case orm.InvalidORMIdentifierError() as err:
595
- return err
596
- case Ok((obj_id, _)):
597
- pass
598
-
599
- orm_obj = orm.Room(
600
- id=obj_id,
601
- name=proto_obj.name,
602
- )
603
- return Ok(_add_orm_to_session(orm_obj, proto_obj.org_id, session))
569
+ orm_obj = orm.Room(name=proto_obj.name)
570
+ return add_orm_org_mixin_to_session(orm_obj, proto_obj, orm.RoomID, session)
604
571
 
605
572
 
606
573
  def completion_model_proto_to_orm(
607
574
  proto_obj: models_pb2.CompletionModel, session: sa_orm.Session
608
575
  ) -> Ok[orm.CompletionModel] | InvalidArgumentError:
609
- match _translate_orm_ids(proto_obj, orm.CompletionModelID):
610
- case orm.InvalidORMIdentifierError() as err:
611
- return err
612
- case Ok((obj_id, _)):
613
- pass
614
-
615
576
  orm_obj = orm.CompletionModel(
616
- id=obj_id,
617
577
  name=proto_obj.name,
618
578
  description=proto_obj.description,
619
579
  parameters=proto_obj.parameters,
620
580
  secret_api_key=proto_obj.secret_api_key,
581
+ last_validation_time=proto_obj.last_validation_time.ToDatetime(),
582
+ )
583
+ return add_orm_org_mixin_to_session(
584
+ orm_obj, proto_obj, orm.CompletionModelID, session
621
585
  )
622
- return Ok(_add_orm_to_session(orm_obj, proto_obj.org_id, session))
623
586
 
624
587
 
625
588
  def source_delete_orms(
corvic/model/_resource.py CHANGED
@@ -15,7 +15,7 @@ from sqlalchemy.orm.interfaces import LoaderOption
15
15
  from typing_extensions import Self
16
16
 
17
17
  from corvic import orm, system
18
- from corvic.model._base_model import BaseModel
18
+ from corvic.model._base_model import BelongsToRoomModel
19
19
  from corvic.model._defaults import Defaults
20
20
  from corvic.model._proto_orm_convert import (
21
21
  resource_delete_orms,
@@ -32,7 +32,7 @@ RoomID: TypeAlias = orm.RoomID
32
32
  PipelineID: TypeAlias = orm.PipelineID
33
33
 
34
34
 
35
- class Resource(BaseModel[ResourceID, models_pb2.Resource, orm.Resource]):
35
+ class Resource(BelongsToRoomModel[ResourceID, models_pb2.Resource, orm.Resource]):
36
36
  """Resources represent import data."""
37
37
 
38
38
  @classmethod
@@ -67,10 +67,6 @@ class Resource(BaseModel[ResourceID, models_pb2.Resource, orm.Resource]):
67
67
  def name(self) -> str:
68
68
  return self.proto_self.name
69
69
 
70
- @property
71
- def room_id(self) -> RoomID:
72
- return RoomID(self.proto_self.room_id)
73
-
74
70
  @property
75
71
  def pipeline_id(self) -> PipelineID | None:
76
72
  return PipelineID(self.proto_self.pipeline_id) or None
corvic/model/_room.py CHANGED
@@ -8,7 +8,7 @@ from typing import TypeAlias
8
8
  import structlog
9
9
 
10
10
  from corvic import orm, system
11
- from corvic.model._base_model import BaseModel
11
+ from corvic.model._base_model import BelongsToOrgModel
12
12
  from corvic.model._defaults import Defaults
13
13
  from corvic.model._proto_orm_convert import (
14
14
  room_delete_orms,
@@ -25,7 +25,7 @@ RoomID: TypeAlias = orm.RoomID
25
25
  FeatureViewID: TypeAlias = orm.FeatureViewID
26
26
 
27
27
 
28
- class Room(BaseModel[RoomID, models_pb2.Room, orm.Room]):
28
+ class Room(BelongsToOrgModel[RoomID, models_pb2.Room, orm.Room]):
29
29
  """Rooms contain conversations and tables."""
30
30
 
31
31
  @classmethod
corvic/model/_source.py CHANGED
@@ -15,7 +15,7 @@ from sqlalchemy.orm.interfaces import LoaderOption
15
15
  from typing_extensions import Self
16
16
 
17
17
  from corvic import op_graph, orm, system
18
- from corvic.model._base_model import BaseModel
18
+ from corvic.model._base_model import BelongsToRoomModel
19
19
  from corvic.model._defaults import Defaults
20
20
  from corvic.model._proto_orm_convert import (
21
21
  source_delete_orms,
@@ -46,7 +46,7 @@ def foreign_key(
46
46
  )
47
47
 
48
48
 
49
- class Source(BaseModel[SourceID, models_pb2.Source, orm.Source]):
49
+ class Source(BelongsToRoomModel[SourceID, models_pb2.Source, orm.Source]):
50
50
  """Sources describe how resources should be treated.
51
51
 
52
52
  Example:
@@ -269,14 +269,18 @@ class Source(BaseModel[SourceID, models_pb2.Source, orm.Source]):
269
269
  self.client, op_graph.op.from_proto(self.proto_self.table_op_graph)
270
270
  )
271
271
 
272
+ @functools.cached_property
273
+ def prop_table(self):
274
+ if self.proto_self.prop_table_op_graph is None:
275
+ return None
276
+ return Table.from_ops(
277
+ self.client, op_graph.op.from_proto(self.proto_self.prop_table_op_graph)
278
+ )
279
+
272
280
  @property
273
281
  def name(self) -> str:
274
282
  return self.proto_self.name
275
283
 
276
- @property
277
- def room_id(self) -> RoomID:
278
- return RoomID(self.proto_self.room_id)
279
-
280
284
  @property
281
285
  def pipeline_id(self) -> PipelineID | None:
282
286
  return PipelineID(self.proto_self.pipeline_id) or None
corvic/model/_space.py CHANGED
@@ -14,7 +14,7 @@ from sqlalchemy import orm as sa_orm
14
14
  from typing_extensions import Self
15
15
 
16
16
  from corvic import op_graph, orm, system
17
- from corvic.model._base_model import BaseModel
17
+ from corvic.model._base_model import BelongsToRoomModel
18
18
  from corvic.model._defaults import Defaults
19
19
  from corvic.model._feature_view import FeatureView, FeatureViewEdgeTableMetadata
20
20
  from corvic.model._proto_orm_convert import (
@@ -61,7 +61,7 @@ name_to_proto_image_model = {
61
61
  }
62
62
 
63
63
 
64
- class Space(BaseModel[SpaceID, models_pb2.Space, orm.Space]):
64
+ class Space(BelongsToRoomModel[SpaceID, models_pb2.Space, orm.Space]):
65
65
  """Spaces apply embedding methods to FeatureViews.
66
66
 
67
67
  Example:
@@ -105,10 +105,6 @@ class Space(BaseModel[SpaceID, models_pb2.Space, orm.Space]):
105
105
  def name(self):
106
106
  return self.proto_self.name
107
107
 
108
- @property
109
- def room_id(self):
110
- return RoomID(self.proto_self.room_id)
111
-
112
108
  @property
113
109
  def description(self):
114
110
  return self.proto_self.description
@@ -694,7 +690,7 @@ class TabularSpace(Space):
694
690
  )
695
691
  return Ok(cls(client, proto_self))
696
692
 
697
- def embeddings_tables( # noqa: C901
693
+ def embeddings_tables( # noqa: C901, PLR0915
698
694
  self,
699
695
  ) -> Ok[Mapping[str, Table]] | InvalidArgumentError:
700
696
  output_sources = self.feature_view.output_sources
@@ -750,7 +746,38 @@ class TabularSpace(Space):
750
746
  pass
751
747
  case InvalidArgumentError() as err:
752
748
  return err
753
-
749
+ case op_graph.feature_type.Timestamp():
750
+ encoded_column_name = f"__encoded-{uuid.uuid4()}"
751
+ embedding_column_tmp_names.append(encoded_column_name)
752
+ match op.encode_columns(
753
+ [
754
+ op_graph.encoder.EncodedColumn(
755
+ column_name=column.name,
756
+ encoded_column_name=encoded_column_name,
757
+ encoder=op_graph.encoder.timestamp_encoder(),
758
+ )
759
+ ]
760
+ ):
761
+ case Ok(op):
762
+ pass
763
+ case InvalidArgumentError() as err:
764
+ return err
765
+ case op_graph.feature_type.Text():
766
+ encoded_column_name = f"__encoded-{uuid.uuid4()}"
767
+ embedding_column_tmp_names.append(encoded_column_name)
768
+ match op.encode_columns(
769
+ [
770
+ op_graph.encoder.EncodedColumn(
771
+ column_name=column.name,
772
+ encoded_column_name=encoded_column_name,
773
+ encoder=op_graph.encoder.text_encoder(),
774
+ )
775
+ ]
776
+ ):
777
+ case Ok(op):
778
+ pass
779
+ case InvalidArgumentError() as err:
780
+ return err
754
781
  case _:
755
782
  continue
756
783