pyspiral 0.1.0__cp310-abi3-macosx_11_0_arm64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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())