pyspiral 0.1.0__cp310-abi3-macosx_11_0_arm64.whl

Sign up to get free protection for your applications and to get access to all the features.
Files changed (81) hide show
  1. pyspiral-0.1.0.dist-info/METADATA +48 -0
  2. pyspiral-0.1.0.dist-info/RECORD +81 -0
  3. pyspiral-0.1.0.dist-info/WHEEL +4 -0
  4. pyspiral-0.1.0.dist-info/entry_points.txt +2 -0
  5. spiral/__init__.py +11 -0
  6. spiral/_lib.abi3.so +0 -0
  7. spiral/adbc.py +386 -0
  8. spiral/api/__init__.py +221 -0
  9. spiral/api/admin.py +29 -0
  10. spiral/api/filesystems.py +125 -0
  11. spiral/api/organizations.py +90 -0
  12. spiral/api/projects.py +160 -0
  13. spiral/api/tables.py +94 -0
  14. spiral/api/tokens.py +56 -0
  15. spiral/api/workloads.py +45 -0
  16. spiral/arrow.py +209 -0
  17. spiral/authn/__init__.py +0 -0
  18. spiral/authn/authn.py +89 -0
  19. spiral/authn/device.py +206 -0
  20. spiral/authn/github_.py +33 -0
  21. spiral/authn/modal_.py +18 -0
  22. spiral/catalog.py +78 -0
  23. spiral/cli/__init__.py +82 -0
  24. spiral/cli/__main__.py +4 -0
  25. spiral/cli/admin.py +21 -0
  26. spiral/cli/app.py +48 -0
  27. spiral/cli/console.py +95 -0
  28. spiral/cli/fs.py +47 -0
  29. spiral/cli/login.py +13 -0
  30. spiral/cli/org.py +90 -0
  31. spiral/cli/printer.py +45 -0
  32. spiral/cli/project.py +107 -0
  33. spiral/cli/state.py +3 -0
  34. spiral/cli/table.py +20 -0
  35. spiral/cli/token.py +27 -0
  36. spiral/cli/types.py +53 -0
  37. spiral/cli/workload.py +59 -0
  38. spiral/config.py +26 -0
  39. spiral/core/__init__.py +0 -0
  40. spiral/core/core/__init__.pyi +53 -0
  41. spiral/core/manifests/__init__.pyi +53 -0
  42. spiral/core/metastore/__init__.pyi +91 -0
  43. spiral/core/spec/__init__.pyi +257 -0
  44. spiral/dataset.py +239 -0
  45. spiral/debug.py +251 -0
  46. spiral/expressions/__init__.py +222 -0
  47. spiral/expressions/base.py +149 -0
  48. spiral/expressions/http.py +86 -0
  49. spiral/expressions/io.py +100 -0
  50. spiral/expressions/list_.py +68 -0
  51. spiral/expressions/refs.py +44 -0
  52. spiral/expressions/str_.py +39 -0
  53. spiral/expressions/struct.py +57 -0
  54. spiral/expressions/tiff.py +223 -0
  55. spiral/expressions/udf.py +46 -0
  56. spiral/grpc_.py +32 -0
  57. spiral/project.py +137 -0
  58. spiral/proto/_/__init__.py +0 -0
  59. spiral/proto/_/arrow/__init__.py +0 -0
  60. spiral/proto/_/arrow/flight/__init__.py +0 -0
  61. spiral/proto/_/arrow/flight/protocol/__init__.py +0 -0
  62. spiral/proto/_/arrow/flight/protocol/sql/__init__.py +1990 -0
  63. spiral/proto/_/scandal/__init__.py +223 -0
  64. spiral/proto/_/spfs/__init__.py +36 -0
  65. spiral/proto/_/spiral/__init__.py +0 -0
  66. spiral/proto/_/spiral/table/__init__.py +225 -0
  67. spiral/proto/_/spiraldb/__init__.py +0 -0
  68. spiral/proto/_/spiraldb/metastore/__init__.py +499 -0
  69. spiral/proto/__init__.py +0 -0
  70. spiral/proto/scandal/__init__.py +45 -0
  71. spiral/proto/spiral/__init__.py +0 -0
  72. spiral/proto/spiral/table/__init__.py +96 -0
  73. spiral/proto/substrait/__init__.py +3399 -0
  74. spiral/proto/substrait/extensions/__init__.py +115 -0
  75. spiral/proto/util.py +41 -0
  76. spiral/py.typed +0 -0
  77. spiral/scan_.py +168 -0
  78. spiral/settings.py +157 -0
  79. spiral/substrait_.py +275 -0
  80. spiral/table.py +157 -0
  81. spiral/types_.py +6 -0
@@ -0,0 +1,499 @@
1
+ # Generated by the protocol buffer compiler. DO NOT EDIT!
2
+ # sources: spiraldb/metastore.proto
3
+ # plugin: python-betterproto
4
+ # This file has been @generated
5
+
6
+ from dataclasses import dataclass
7
+ from typing import (
8
+ TYPE_CHECKING,
9
+ Dict,
10
+ List,
11
+ Optional,
12
+ )
13
+
14
+ import betterproto
15
+ import grpclib
16
+ from betterproto.grpc.grpclib_server import ServiceBase
17
+
18
+ from ...spiral import table as __spiral_table__
19
+
20
+
21
+ if TYPE_CHECKING:
22
+ import grpclib.server
23
+ from betterproto.grpc.grpclib_client import MetadataLike
24
+ from grpclib.metadata import Deadline
25
+
26
+
27
+ class FileType(betterproto.Enum):
28
+ UNSPECIFIED = 0
29
+ FRAGMENT = 1
30
+ FRAGMENT_MANIFEST = 2
31
+ REFERENCE = 3
32
+
33
+
34
+ @dataclass(eq=False, repr=False)
35
+ class FileHandle(betterproto.Message):
36
+ uri: str = betterproto.string_field(1)
37
+ format: "__spiral_table__.FileFormat" = betterproto.enum_field(2)
38
+ spfs_token: Optional[str] = betterproto.string_field(3, optional=True)
39
+
40
+
41
+ @dataclass(eq=False, repr=False)
42
+ class GetReadToken(betterproto.Message):
43
+ pass
44
+
45
+
46
+ @dataclass(eq=False, repr=False)
47
+ class GetReadTokenRequest(betterproto.Message):
48
+ table_id: str = betterproto.string_field(1)
49
+
50
+
51
+ @dataclass(eq=False, repr=False)
52
+ class GetReadTokenResponse(betterproto.Message):
53
+ spfs_token: str = betterproto.string_field(1)
54
+
55
+
56
+ @dataclass(eq=False, repr=False)
57
+ class SignFileWrite(betterproto.Message):
58
+ pass
59
+
60
+
61
+ @dataclass(eq=False, repr=False)
62
+ class SignFileWriteRequest(betterproto.Message):
63
+ table_id: str = betterproto.string_field(1)
64
+ file_type: "FileType" = betterproto.enum_field(2)
65
+ file_format: "__spiral_table__.FileFormat" = betterproto.enum_field(3)
66
+
67
+
68
+ @dataclass(eq=False, repr=False)
69
+ class SignFileWriteResponse(betterproto.Message):
70
+ id: str = betterproto.string_field(1)
71
+ handle: "FileHandle" = betterproto.message_field(2)
72
+
73
+
74
+ @dataclass(eq=False, repr=False)
75
+ class AppendWal(betterproto.Message):
76
+ pass
77
+
78
+
79
+ @dataclass(eq=False, repr=False)
80
+ class AppendWalRequest(betterproto.Message):
81
+ table_id: str = betterproto.string_field(1)
82
+ prev_last_modified_at: int = betterproto.uint64_field(2)
83
+ """
84
+ Timestamp of the last modification in the log.
85
+ For simple compare and swap or conflict resolution.
86
+ """
87
+
88
+ entries: List["__spiral_table__.LogEntry"] = betterproto.message_field(3)
89
+
90
+
91
+ @dataclass(eq=False, repr=False)
92
+ class AppendWalResponse(betterproto.Message):
93
+ committed: "__spiral_table__.WriteAheadLog" = betterproto.message_field(
94
+ 1, group="status"
95
+ )
96
+ """New log (includes the committed operations)."""
97
+
98
+ conflicted: "__spiral_table__.WriteAheadLog" = betterproto.message_field(
99
+ 2, group="status"
100
+ )
101
+ """In case of a conflict, the existing log is returned."""
102
+
103
+
104
+ @dataclass(eq=False, repr=False)
105
+ class UpdateWal(betterproto.Message):
106
+ """NOTE: WAL is updated only on flush."""
107
+
108
+ pass
109
+
110
+
111
+ @dataclass(eq=False, repr=False)
112
+ class UpdateWalRequest(betterproto.Message):
113
+ table_id: str = betterproto.string_field(1)
114
+ prev_last_modified_at: int = betterproto.uint64_field(2)
115
+ """
116
+ Only sequential update is supported.
117
+
118
+ Truncation does not modify the last modified at so we require
119
+ both fields to be passed for compare and swap.
120
+
121
+ The assumption with this API is that all WAL updates will modify
122
+ log entries and therefore change at least one of the timestamps.
123
+ """
124
+
125
+ prev_truncated_up_to: int = betterproto.uint64_field(3)
126
+ new_wal: "__spiral_table__.WriteAheadLog" = betterproto.message_field(4)
127
+
128
+
129
+ @dataclass(eq=False, repr=False)
130
+ class UpdateWalResponse(betterproto.Message):
131
+ committed: "__spiral_table__.WriteAheadLog" = betterproto.message_field(
132
+ 1, group="status"
133
+ )
134
+ conflicted: "__spiral_table__.WriteAheadLog" = betterproto.message_field(
135
+ 2, group="status"
136
+ )
137
+
138
+
139
+ @dataclass(eq=False, repr=False)
140
+ class GetWal(betterproto.Message):
141
+ pass
142
+
143
+
144
+ @dataclass(eq=False, repr=False)
145
+ class GetWalRequest(betterproto.Message):
146
+ table_id: str = betterproto.string_field(1)
147
+
148
+
149
+ @dataclass(eq=False, repr=False)
150
+ class GetWalResponse(betterproto.Message):
151
+ wal: "__spiral_table__.WriteAheadLog" = betterproto.message_field(1)
152
+
153
+
154
+ @dataclass(eq=False, repr=False)
155
+ class UpdateColumnGroupMetadata(betterproto.Message):
156
+ """NOTE: Metadata is updated only on flush."""
157
+
158
+ pass
159
+
160
+
161
+ @dataclass(eq=False, repr=False)
162
+ class UpdateColumnGroupMetadataRequest(betterproto.Message):
163
+ table_id: str = betterproto.string_field(1)
164
+ prev_last_modified_at: int = betterproto.uint64_field(3)
165
+ """Used to compare and swap."""
166
+
167
+ new_metadata: "__spiral_table__.ColumnGroupMetadata" = betterproto.message_field(4)
168
+
169
+
170
+ @dataclass(eq=False, repr=False)
171
+ class UpdateColumnGroupMetadataResponse(betterproto.Message):
172
+ committed: "__spiral_table__.ColumnGroupMetadata" = betterproto.message_field(
173
+ 1, group="status"
174
+ )
175
+ conflicted: "__spiral_table__.ColumnGroupMetadata" = betterproto.message_field(
176
+ 2, group="status"
177
+ )
178
+
179
+
180
+ @dataclass(eq=False, repr=False)
181
+ class GetColumnGroupMetadata(betterproto.Message):
182
+ pass
183
+
184
+
185
+ @dataclass(eq=False, repr=False)
186
+ class GetColumnGroupMetadataRequest(betterproto.Message):
187
+ table_id: str = betterproto.string_field(1)
188
+ column_group: "__spiral_table__.ColumnGroup" = betterproto.message_field(2)
189
+
190
+
191
+ @dataclass(eq=False, repr=False)
192
+ class GetColumnGroupMetadataResponse(betterproto.Message):
193
+ metadata: "__spiral_table__.ColumnGroupMetadata" = betterproto.message_field(1)
194
+
195
+
196
+ @dataclass(eq=False, repr=False)
197
+ class GetColumnGroups(betterproto.Message):
198
+ pass
199
+
200
+
201
+ @dataclass(eq=False, repr=False)
202
+ class GetColumnGroupsRequest(betterproto.Message):
203
+ table_id: str = betterproto.string_field(1)
204
+
205
+
206
+ @dataclass(eq=False, repr=False)
207
+ class GetColumnGroupsResponse(betterproto.Message):
208
+ column_groups: List["__spiral_table__.ColumnGroup"] = betterproto.message_field(1)
209
+ last_modified_at: int = betterproto.uint64_field(2)
210
+
211
+
212
+ class MetastoreServiceStub(betterproto.ServiceStub):
213
+ async def get_read_token(
214
+ self,
215
+ get_read_token_request: "GetReadTokenRequest",
216
+ *,
217
+ timeout: Optional[float] = None,
218
+ deadline: Optional["Deadline"] = None,
219
+ metadata: Optional["MetadataLike"] = None
220
+ ) -> "GetReadTokenResponse":
221
+ return await self._unary_unary(
222
+ "/spiraldb.metastore.MetastoreService/GetReadToken",
223
+ get_read_token_request,
224
+ GetReadTokenResponse,
225
+ timeout=timeout,
226
+ deadline=deadline,
227
+ metadata=metadata,
228
+ )
229
+
230
+ async def sign_write_file(
231
+ self,
232
+ sign_file_write_request: "SignFileWriteRequest",
233
+ *,
234
+ timeout: Optional[float] = None,
235
+ deadline: Optional["Deadline"] = None,
236
+ metadata: Optional["MetadataLike"] = None
237
+ ) -> "SignFileWriteResponse":
238
+ return await self._unary_unary(
239
+ "/spiraldb.metastore.MetastoreService/SignWriteFile",
240
+ sign_file_write_request,
241
+ SignFileWriteResponse,
242
+ timeout=timeout,
243
+ deadline=deadline,
244
+ metadata=metadata,
245
+ )
246
+
247
+ async def append_wal(
248
+ self,
249
+ append_wal_request: "AppendWalRequest",
250
+ *,
251
+ timeout: Optional[float] = None,
252
+ deadline: Optional["Deadline"] = None,
253
+ metadata: Optional["MetadataLike"] = None
254
+ ) -> "AppendWalResponse":
255
+ return await self._unary_unary(
256
+ "/spiraldb.metastore.MetastoreService/AppendWAL",
257
+ append_wal_request,
258
+ AppendWalResponse,
259
+ timeout=timeout,
260
+ deadline=deadline,
261
+ metadata=metadata,
262
+ )
263
+
264
+ async def update_wal(
265
+ self,
266
+ update_wal_request: "UpdateWalRequest",
267
+ *,
268
+ timeout: Optional[float] = None,
269
+ deadline: Optional["Deadline"] = None,
270
+ metadata: Optional["MetadataLike"] = None
271
+ ) -> "UpdateWalResponse":
272
+ return await self._unary_unary(
273
+ "/spiraldb.metastore.MetastoreService/UpdateWAL",
274
+ update_wal_request,
275
+ UpdateWalResponse,
276
+ timeout=timeout,
277
+ deadline=deadline,
278
+ metadata=metadata,
279
+ )
280
+
281
+ async def get_wal(
282
+ self,
283
+ get_wal_request: "GetWalRequest",
284
+ *,
285
+ timeout: Optional[float] = None,
286
+ deadline: Optional["Deadline"] = None,
287
+ metadata: Optional["MetadataLike"] = None
288
+ ) -> "GetWalResponse":
289
+ return await self._unary_unary(
290
+ "/spiraldb.metastore.MetastoreService/GetWAL",
291
+ get_wal_request,
292
+ GetWalResponse,
293
+ timeout=timeout,
294
+ deadline=deadline,
295
+ metadata=metadata,
296
+ )
297
+
298
+ async def update_column_group_metadata(
299
+ self,
300
+ update_column_group_metadata_request: "UpdateColumnGroupMetadataRequest",
301
+ *,
302
+ timeout: Optional[float] = None,
303
+ deadline: Optional["Deadline"] = None,
304
+ metadata: Optional["MetadataLike"] = None
305
+ ) -> "UpdateColumnGroupMetadataResponse":
306
+ return await self._unary_unary(
307
+ "/spiraldb.metastore.MetastoreService/UpdateColumnGroupMetadata",
308
+ update_column_group_metadata_request,
309
+ UpdateColumnGroupMetadataResponse,
310
+ timeout=timeout,
311
+ deadline=deadline,
312
+ metadata=metadata,
313
+ )
314
+
315
+ async def get_column_group_metadata(
316
+ self,
317
+ get_column_group_metadata_request: "GetColumnGroupMetadataRequest",
318
+ *,
319
+ timeout: Optional[float] = None,
320
+ deadline: Optional["Deadline"] = None,
321
+ metadata: Optional["MetadataLike"] = None
322
+ ) -> "GetColumnGroupMetadataResponse":
323
+ return await self._unary_unary(
324
+ "/spiraldb.metastore.MetastoreService/GetColumnGroupMetadata",
325
+ get_column_group_metadata_request,
326
+ GetColumnGroupMetadataResponse,
327
+ timeout=timeout,
328
+ deadline=deadline,
329
+ metadata=metadata,
330
+ )
331
+
332
+ async def get_column_groups(
333
+ self,
334
+ get_column_groups_request: "GetColumnGroupsRequest",
335
+ *,
336
+ timeout: Optional[float] = None,
337
+ deadline: Optional["Deadline"] = None,
338
+ metadata: Optional["MetadataLike"] = None
339
+ ) -> "GetColumnGroupsResponse":
340
+ return await self._unary_unary(
341
+ "/spiraldb.metastore.MetastoreService/GetColumnGroups",
342
+ get_column_groups_request,
343
+ GetColumnGroupsResponse,
344
+ timeout=timeout,
345
+ deadline=deadline,
346
+ metadata=metadata,
347
+ )
348
+
349
+
350
+ class MetastoreServiceBase(ServiceBase):
351
+ async def get_read_token(
352
+ self, get_read_token_request: "GetReadTokenRequest"
353
+ ) -> "GetReadTokenResponse":
354
+ raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)
355
+
356
+ async def sign_write_file(
357
+ self, sign_file_write_request: "SignFileWriteRequest"
358
+ ) -> "SignFileWriteResponse":
359
+ raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)
360
+
361
+ async def append_wal(
362
+ self, append_wal_request: "AppendWalRequest"
363
+ ) -> "AppendWalResponse":
364
+ raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)
365
+
366
+ async def update_wal(
367
+ self, update_wal_request: "UpdateWalRequest"
368
+ ) -> "UpdateWalResponse":
369
+ raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)
370
+
371
+ async def get_wal(self, get_wal_request: "GetWalRequest") -> "GetWalResponse":
372
+ raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)
373
+
374
+ async def update_column_group_metadata(
375
+ self, update_column_group_metadata_request: "UpdateColumnGroupMetadataRequest"
376
+ ) -> "UpdateColumnGroupMetadataResponse":
377
+ raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)
378
+
379
+ async def get_column_group_metadata(
380
+ self, get_column_group_metadata_request: "GetColumnGroupMetadataRequest"
381
+ ) -> "GetColumnGroupMetadataResponse":
382
+ raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)
383
+
384
+ async def get_column_groups(
385
+ self, get_column_groups_request: "GetColumnGroupsRequest"
386
+ ) -> "GetColumnGroupsResponse":
387
+ raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)
388
+
389
+ async def __rpc_get_read_token(
390
+ self, stream: "grpclib.server.Stream[GetReadTokenRequest, GetReadTokenResponse]"
391
+ ) -> None:
392
+ request = await stream.recv_message()
393
+ response = await self.get_read_token(request)
394
+ await stream.send_message(response)
395
+
396
+ async def __rpc_sign_write_file(
397
+ self,
398
+ stream: "grpclib.server.Stream[SignFileWriteRequest, SignFileWriteResponse]",
399
+ ) -> None:
400
+ request = await stream.recv_message()
401
+ response = await self.sign_write_file(request)
402
+ await stream.send_message(response)
403
+
404
+ async def __rpc_append_wal(
405
+ self, stream: "grpclib.server.Stream[AppendWalRequest, AppendWalResponse]"
406
+ ) -> None:
407
+ request = await stream.recv_message()
408
+ response = await self.append_wal(request)
409
+ await stream.send_message(response)
410
+
411
+ async def __rpc_update_wal(
412
+ self, stream: "grpclib.server.Stream[UpdateWalRequest, UpdateWalResponse]"
413
+ ) -> None:
414
+ request = await stream.recv_message()
415
+ response = await self.update_wal(request)
416
+ await stream.send_message(response)
417
+
418
+ async def __rpc_get_wal(
419
+ self, stream: "grpclib.server.Stream[GetWalRequest, GetWalResponse]"
420
+ ) -> None:
421
+ request = await stream.recv_message()
422
+ response = await self.get_wal(request)
423
+ await stream.send_message(response)
424
+
425
+ async def __rpc_update_column_group_metadata(
426
+ self,
427
+ stream: "grpclib.server.Stream[UpdateColumnGroupMetadataRequest, UpdateColumnGroupMetadataResponse]",
428
+ ) -> None:
429
+ request = await stream.recv_message()
430
+ response = await self.update_column_group_metadata(request)
431
+ await stream.send_message(response)
432
+
433
+ async def __rpc_get_column_group_metadata(
434
+ self,
435
+ stream: "grpclib.server.Stream[GetColumnGroupMetadataRequest, GetColumnGroupMetadataResponse]",
436
+ ) -> None:
437
+ request = await stream.recv_message()
438
+ response = await self.get_column_group_metadata(request)
439
+ await stream.send_message(response)
440
+
441
+ async def __rpc_get_column_groups(
442
+ self,
443
+ stream: "grpclib.server.Stream[GetColumnGroupsRequest, GetColumnGroupsResponse]",
444
+ ) -> None:
445
+ request = await stream.recv_message()
446
+ response = await self.get_column_groups(request)
447
+ await stream.send_message(response)
448
+
449
+ def __mapping__(self) -> Dict[str, grpclib.const.Handler]:
450
+ return {
451
+ "/spiraldb.metastore.MetastoreService/GetReadToken": grpclib.const.Handler(
452
+ self.__rpc_get_read_token,
453
+ grpclib.const.Cardinality.UNARY_UNARY,
454
+ GetReadTokenRequest,
455
+ GetReadTokenResponse,
456
+ ),
457
+ "/spiraldb.metastore.MetastoreService/SignWriteFile": grpclib.const.Handler(
458
+ self.__rpc_sign_write_file,
459
+ grpclib.const.Cardinality.UNARY_UNARY,
460
+ SignFileWriteRequest,
461
+ SignFileWriteResponse,
462
+ ),
463
+ "/spiraldb.metastore.MetastoreService/AppendWAL": grpclib.const.Handler(
464
+ self.__rpc_append_wal,
465
+ grpclib.const.Cardinality.UNARY_UNARY,
466
+ AppendWalRequest,
467
+ AppendWalResponse,
468
+ ),
469
+ "/spiraldb.metastore.MetastoreService/UpdateWAL": grpclib.const.Handler(
470
+ self.__rpc_update_wal,
471
+ grpclib.const.Cardinality.UNARY_UNARY,
472
+ UpdateWalRequest,
473
+ UpdateWalResponse,
474
+ ),
475
+ "/spiraldb.metastore.MetastoreService/GetWAL": grpclib.const.Handler(
476
+ self.__rpc_get_wal,
477
+ grpclib.const.Cardinality.UNARY_UNARY,
478
+ GetWalRequest,
479
+ GetWalResponse,
480
+ ),
481
+ "/spiraldb.metastore.MetastoreService/UpdateColumnGroupMetadata": grpclib.const.Handler(
482
+ self.__rpc_update_column_group_metadata,
483
+ grpclib.const.Cardinality.UNARY_UNARY,
484
+ UpdateColumnGroupMetadataRequest,
485
+ UpdateColumnGroupMetadataResponse,
486
+ ),
487
+ "/spiraldb.metastore.MetastoreService/GetColumnGroupMetadata": grpclib.const.Handler(
488
+ self.__rpc_get_column_group_metadata,
489
+ grpclib.const.Cardinality.UNARY_UNARY,
490
+ GetColumnGroupMetadataRequest,
491
+ GetColumnGroupMetadataResponse,
492
+ ),
493
+ "/spiraldb.metastore.MetastoreService/GetColumnGroups": grpclib.const.Handler(
494
+ self.__rpc_get_column_groups,
495
+ grpclib.const.Cardinality.UNARY_UNARY,
496
+ GetColumnGroupsRequest,
497
+ GetColumnGroupsResponse,
498
+ ),
499
+ }
File without changes
@@ -0,0 +1,45 @@
1
+ from spiral.proto._ import scandal as scandal_
2
+
3
+ from spiral.proto._.scandal import (
4
+ Connectivity,
5
+ Delete,
6
+ DeleteRequest,
7
+ DeleteResponse,
8
+ Fetch,
9
+ FetchRequest,
10
+ FetchResponse,
11
+ Metadata,
12
+ MetadataParquet,
13
+ Put,
14
+ PutRequest,
15
+ PutResponse,
16
+ ScandalServiceStub,
17
+ ScandalServiceBase,
18
+ ServiceBase,
19
+ Sink,
20
+ Source,
21
+ )
22
+
23
+ __all__ = [
24
+ "Connectivity",
25
+ "Delete",
26
+ "DeleteRequest",
27
+ "DeleteResponse",
28
+ "Fetch",
29
+ "FetchRequest",
30
+ "FetchResponse",
31
+ "Metadata",
32
+ "MetadataParquet",
33
+ "Put",
34
+ "PutRequest",
35
+ "PutResponse",
36
+ "ScandalServiceStub",
37
+ "ScandalServiceBase",
38
+ "ServiceBase",
39
+ "Sink",
40
+ "Source",
41
+ ]
42
+
43
+ from spiral.proto.util import patch_protos
44
+
45
+ patch_protos(scandal_, globals())
File without changes
@@ -0,0 +1,96 @@
1
+ import betterproto
2
+ import pyarrow as pa
3
+
4
+ from spiral.proto._.spiral import table as table_
5
+ from spiral.proto._.spiral.table import (
6
+ ColumnGroup,
7
+ ConfigurationOp,
8
+ FileFormat,
9
+ KeyExtent,
10
+ KeySpan,
11
+ Level,
12
+ ManifestHandle,
13
+ Schema,
14
+ SchemaBreakOp,
15
+ SchemaEvolutionOp,
16
+ VersionedSchema,
17
+ WriteOp,
18
+ )
19
+ from spiral.proto._.spiral.table import (
20
+ ColumnGroupMetadata as ColumnGroupMetadata_,
21
+ )
22
+ from spiral.proto._.spiral.table import (
23
+ Entry as Entry_,
24
+ )
25
+ from spiral.proto._.spiral.table import (
26
+ WriteAheadLog as WriteAheadLog_,
27
+ )
28
+
29
+ __all__ = [
30
+ "ColumnGroup",
31
+ "ColumnGroupMetadata",
32
+ "ConfigurationOp",
33
+ "Entry",
34
+ "FileFormat",
35
+ "KeyExtent",
36
+ "KeySpan",
37
+ "Level",
38
+ "ManifestHandle",
39
+ "Schema",
40
+ "SchemaBreakOp",
41
+ "SchemaEvolutionOp",
42
+ "VersionedSchema",
43
+ "WriteAheadLog",
44
+ "WriteOp",
45
+ ]
46
+
47
+
48
+ class ColumnGroupMetadata(ColumnGroupMetadata_):
49
+ @property
50
+ def latest_schema(self) -> pa.Schema:
51
+ if self.schema_versions:
52
+ return pa.ipc.read_schema(pa.py_buffer(self.schema_versions[-1].schema.arrow))
53
+ return pa.schema([])
54
+
55
+ def asof(self, asof: int | None) -> "ColumnGroupMetadata":
56
+ """Return the metadata as of the given timestamp."""
57
+ if asof is None:
58
+ return self.model_copy()
59
+
60
+ versions = [v for v in self.schema_versions if v.ts <= asof]
61
+ return self.model_copy(update=dict(schema_versions=versions))
62
+
63
+
64
+ class Entry(Entry_):
65
+ @property
66
+ def column_group(self) -> tuple[str, ...] | None:
67
+ match betterproto.which_one_of(self, "operation"):
68
+ case _, op:
69
+ return tuple(op.column_group.parts)
70
+
71
+
72
+ class WriteAheadLog(WriteAheadLog_):
73
+ # TODO(ngates): add a single `filter` function that takes these as kwargs
74
+
75
+ def asof(self, asof: int | None) -> "WriteAheadLog":
76
+ """Return the WAL with all entries after the given timestamp removed."""
77
+ if asof is None:
78
+ return self.model_copy()
79
+ return self.model_copy(update=dict(logs=[entry for entry in self.logs if entry.ts <= asof]))
80
+
81
+ def since(self, since: int | None) -> "WriteAheadLog":
82
+ """Return the WAL with all entries before the given timestamp removed."""
83
+ if since is None:
84
+ return self.model_copy()
85
+ return self.model_copy(update=dict(logs=[entry for entry in self.logs if entry.ts > since]))
86
+
87
+ def for_column_group(self, column_group_path: tuple[str, ...]) -> "WriteAheadLog":
88
+ """Return the WAL with all entries for the given column group."""
89
+ return self.model_copy(
90
+ update=dict(logs=[entry for entry in self.logs if tuple(entry.op.column_group.parts) == column_group_path])
91
+ )
92
+
93
+
94
+ from spiral.proto.util import patch_protos
95
+
96
+ patch_protos(table_, globals())