pyspiral 0.7.6__cp312-abi3-macosx_11_0_arm64.whl → 0.7.8__cp312-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.

Potentially problematic release.


This version of pyspiral might be problematic. Click here for more details.

@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pyspiral
3
- Version: 0.7.6
3
+ Version: 0.7.8
4
4
  Classifier: Intended Audience :: Science/Research
5
5
  Classifier: Operating System :: OS Independent
6
6
  Classifier: Programming Language :: Python
@@ -1,8 +1,8 @@
1
- pyspiral-0.7.6.dist-info/METADATA,sha256=mBOLr8JlizyBr3w2oyvielfM-EdxU3vOtLG85rQpcHw,1874
2
- pyspiral-0.7.6.dist-info/WHEEL,sha256=KQvxBiy7GLcML6Ad3w_ZPrgSvER1uXd7aYb6wy6b44Y,103
3
- pyspiral-0.7.6.dist-info/entry_points.txt,sha256=R96Y3FpYX6XbQu9qMPfUTgiCcf4qM9OBQQZTDdBkZwA,74
1
+ pyspiral-0.7.8.dist-info/METADATA,sha256=tGCOA2CfvPk_EGKZ35MCaeZ0x6SIm-XZNnLMHd5ao-U,1874
2
+ pyspiral-0.7.8.dist-info/WHEEL,sha256=KQvxBiy7GLcML6Ad3w_ZPrgSvER1uXd7aYb6wy6b44Y,103
3
+ pyspiral-0.7.8.dist-info/entry_points.txt,sha256=R96Y3FpYX6XbQu9qMPfUTgiCcf4qM9OBQQZTDdBkZwA,74
4
4
  spiral/__init__.py,sha256=PwaYBWFBtB7cYi7peMmhk_Lm5XzjRoLwOtLbUhc1ZDo,1449
5
- spiral/_lib.abi3.so,sha256=UAPO7CD9hQTq38oj0OMRjHJ4Xr-UJPaPYVeRR7q8ge4,70569952
5
+ spiral/_lib.abi3.so,sha256=fSclMfCK-CsL8hz65fdTDqXCH9U4R3AZ3UpeNTLSgj0,70882208
6
6
  spiral/adbc.py,sha256=7IxfWIeQN-fh0W5OdN_PP2x3pzQYg6ZUOLsHg3jktqw,14842
7
7
  spiral/api/__init__.py,sha256=ULBlVq3PnfNOO6T5naE_ULmmii-83--qTuN2PpAUQN0,2241
8
8
  spiral/api/admin.py,sha256=A1iVR1XYJSObZivPAD5UzmPuMgupXc9kaHNYYa_kwfs,585
@@ -30,7 +30,7 @@ spiral/cli/orgs.py,sha256=fmOuLxpeIFfKqePRi292Gv9k-EF5pPn_tbKd2BLl2Ig,2869
30
30
  spiral/cli/printer.py,sha256=aosc763hDFgoXJGkiANmNyO3kAsecAS1JWgjEhn8GCM,1784
31
31
  spiral/cli/projects.py,sha256=1M1nGrBT-t0aY9RV5Cnmzy7YrhIvmHwdkpa3y9j8rG8,5756
32
32
  spiral/cli/state.py,sha256=10wTIVQ0SJkY67Z6-KQ1LFlt3aVIPmZhoHFdTwp4kNA,130
33
- spiral/cli/tables.py,sha256=qm3izcysElJrQlerNZdfx5RWSVXtyVfkP3o_H51ltFw,6366
33
+ spiral/cli/tables.py,sha256=Mv6M8zlgG_1i_GsguYIzU-CY2GXq2fMmKnabSMWE1qI,6402
34
34
  spiral/cli/telemetry.py,sha256=Uxo1Q1FkKJ6n6QNGOUmL3j_pRRWRx0qWIhoP-U9BuR0,589
35
35
  spiral/cli/text.py,sha256=DlWGe4JrkdERAiqyITNpk91Wqb63Re99rNYlIFsIamc,4031
36
36
  spiral/cli/types.py,sha256=XYzo1GgX7dBBItoBSrHI4vO5C2lLmS2sktb-2GnGH3E,1362
@@ -39,7 +39,7 @@ spiral/client.py,sha256=53dVv8wxYMmozUfR8MVcUufKGqdVIdb0yZ0gchczBoQ,6426
39
39
  spiral/core/__init__.pyi,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
40
40
  spiral/core/_tools/__init__.pyi,sha256=b2KLfTOQ67pjfbYt07o0IGiTu5o2bZw69lllV8v0Dps,143
41
41
  spiral/core/authn/__init__.pyi,sha256=z_GWyIS62fuiYQrYO8hzw4W8oGaiciqS1u5qtAt54VY,769
42
- spiral/core/client/__init__.pyi,sha256=ZoeCQnEauDbaR0X7aMfHBJtLnoc7ib4JXvsmst6cAUM,6993
42
+ spiral/core/client/__init__.pyi,sha256=YgDM-MoIt3J-QKxvsfs5gRiaTBtOA6TphbNBIAnrFCw,6956
43
43
  spiral/core/expr/__init__.pyi,sha256=3HSKjkotiEkxBvGBALXEBIie0JiyI9bCpehwA3nMQkU,571
44
44
  spiral/core/expr/images/__init__.pyi,sha256=wnE_wZXq7a4iqTg3SVm-ssxGw1WQZyk5dGOPaP4Btko,73
45
45
  spiral/core/expr/list_/__init__.pyi,sha256=Q_9c87eIQfZbqlaw_rq3fvs93YEsW7K5VYk6VZ4g6mU,126
@@ -49,7 +49,7 @@ spiral/core/expr/struct_/__init__.pyi,sha256=MXckd98eV_x3X0RhEWvlkA3DcDXRtLs5pNn
49
49
  spiral/core/expr/text/__init__.pyi,sha256=ed83n1xcsGY7_QDhMmJGnSQ20UrJFXcdv1AveSEcS1c,175
50
50
  spiral/core/expr/udf/__init__.pyi,sha256=zsZs081KVhY3-1JidqTkWMW81Qd_ScoTGZvasIhIK-4,358
51
51
  spiral/core/expr/video/__init__.pyi,sha256=nQJEcSsigZuRpMjkI_O4EEtMK_n2zRvorcL_KEeD5vU,95
52
- spiral/core/table/__init__.pyi,sha256=BkjzdcY0JL97nDRoY5s2gjfdIn1CZ7TR-uYp8f6cxEw,3940
52
+ spiral/core/table/__init__.pyi,sha256=zcf4GripPZtiwh6uHkPgVyDij1g2nYL1DogN83z5ISU,4037
53
53
  spiral/core/table/manifests/__init__.pyi,sha256=eVfDpmhYSjafIvvALqAkZe5baN3Y1HpKpxYEbjwd4gQ,1043
54
54
  spiral/core/table/metastore/__init__.pyi,sha256=rc3u9MwEKRvL2kxOc8lBorddFRnM8o_o1frqtae86a4,1697
55
55
  spiral/core/table/spec/__init__.pyi,sha256=fVuc2j3uoTdWfYNm720OfUIgrLYw9fRwj44maI5bgdY,5709
@@ -60,7 +60,7 @@ spiral/debug/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
60
60
  spiral/debug/manifests.py,sha256=7f1O3ba9mrA5nXpOF9cEIQuUAteP5wiBkFy_diQJ7No,3216
61
61
  spiral/debug/metrics.py,sha256=XdRDcjggtsLNGCAjam6IxG9072pz_d2C8iLApNRFUtk,2044
62
62
  spiral/debug/scan.py,sha256=UEm_aRnql5pwDPTpZgakMLNjlzkKL4RurBFFqH_BLAQ,9526
63
- spiral/enrichment.py,sha256=OYOvFg98p-ti6HTw6tD6ThMGXUUKQ7JEUnqYKvMjOag,7046
63
+ spiral/enrichment.py,sha256=w0MrZ93wDuvS4sazw_8dPmnhzkQ4SAU5A1CGE7WF-F8,7046
64
64
  spiral/expressions/__init__.py,sha256=ZsD8g7vB0G7xy19GUiH4m79kw7KEkTQRwJl5Gn1cgtw,8049
65
65
  spiral/expressions/base.py,sha256=PvhJkcUSsPSIaxirHVzM9zlqyBXiaiia1HXohXdOmL4,5377
66
66
  spiral/expressions/file.py,sha256=7D9jIENJcoT0KFharBLkzK9dZgO4DYn5K_KCt0twefg,518
@@ -94,7 +94,7 @@ spiral/protogen/_/substrait/extensions/__init__.py,sha256=nhnEnho70GAT8WPj2xtwJU
94
94
  spiral/protogen/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
95
95
  spiral/protogen/util.py,sha256=smnvVo6nYH3FfDm9jqhNLaXz4bbTBaQezHQDCTvZyiQ,1486
96
96
  spiral/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
97
- spiral/scan.py,sha256=0ZgzPX5gZ3uvbCyifpjHKXYk_ERphf9xHbrOVKRNkXc,12574
97
+ spiral/scan.py,sha256=8IFuhqxzVGdXPW8uWWTFKiC38mTLpwkBZvK1YHqtbHM,12574
98
98
  spiral/server.py,sha256=ztBmB5lBnUz-smQxR_tC8AI5SOhz17wH0MI3GuzDUdM,600
99
99
  spiral/settings.py,sha256=sUhMMBCXaPvUYztN_gztD9TjeUYJwVeEcJrq4FLy6M0,3232
100
100
  spiral/snapshot.py,sha256=cTobi5jtiANxalGA-isokQHblNmXGtuUvgUGGNVybsI,1555
@@ -102,8 +102,8 @@ spiral/streaming_/__init__.py,sha256=s7MlW2ERsuZmZGExLFL6RcZon2e0tNBocBg5ANgki7k
102
102
  spiral/streaming_/reader.py,sha256=tl_lC9xgh1-QFhsZn4xQT7It3PVTzHCEUT2BG2dWBRQ,4166
103
103
  spiral/streaming_/stream.py,sha256=DM1hBDHnWm1ZFKZ-hZ4zxeSXITcUI6kWzwdJZvywI8o,5915
104
104
  spiral/substrait_.py,sha256=AKeOD4KIXvz2J4TYxnIneOiHddtBIyOhuNxVO_uH0eg,12592
105
- spiral/table.py,sha256=ep8ZYtl6POebkPViR2FrekhFazNmAbOAESoLUODlup8,12242
105
+ spiral/table.py,sha256=p95AYv6b7e14F3t7j-B-r45k9CtG84ngikdlAhh9WxA,12260
106
106
  spiral/text_index.py,sha256=FQ9rgIEGLSJryS9lFdMhKtPFey18BXoWbPXyvZPJJ04,442
107
107
  spiral/transaction.py,sha256=bI5oqBAmPMSF0yOOYcPfGbV37Xc1-_V-wQNKw1xOlTA,4136
108
108
  spiral/types_.py,sha256=W_jyO7F6rpPiH69jhgSgV7OxQZbOlb1Ho3InpKUP6Eo,155
109
- pyspiral-0.7.6.dist-info/RECORD,,
109
+ pyspiral-0.7.8.dist-info/RECORD,,
spiral/_lib.abi3.so CHANGED
Binary file
spiral/cli/tables.py CHANGED
@@ -1,5 +1,5 @@
1
- import datetime
2
- from typing import Annotated, Literal
1
+ from collections.abc import Callable
2
+ from typing import Annotated
3
3
 
4
4
  import questionary
5
5
  import rich
@@ -60,6 +60,45 @@ def ls(
60
60
  CONSOLE.print(rich_table)
61
61
 
62
62
 
63
+ def validate_non_empty_str(text: str) -> bool | str:
64
+ if len(text) > 0:
65
+ return True
66
+
67
+ return "Must provide at least one character."
68
+
69
+
70
+ def get_string(message: str, validate: Callable[[str], bool | str] = validate_non_empty_str) -> str:
71
+ return questionary.text(message, validate=validate).ask()
72
+
73
+
74
+ @app.command(help="Move table to a different dataset.")
75
+ def move(
76
+ project: ProjectArg,
77
+ table: Annotated[str | None, Option(help="Table name.")] = None,
78
+ dataset: Annotated[str | None, Option(help="Dataset name.")] = None,
79
+ new_dataset: Annotated[str | None, Option(help="New dataset name.")] = None,
80
+ ):
81
+ identifier, _ = get_table(project, table, dataset)
82
+ new_dataset = get_string("Provide a new dataset name")
83
+
84
+ state.spiral.project(project).move_table(identifier, new_dataset)
85
+ CONSOLE.print("Success.")
86
+
87
+
88
+ @app.command(help="Rename table.")
89
+ def rename(
90
+ project: ProjectArg,
91
+ table: Annotated[str | None, Option(help="Table name.")] = None,
92
+ dataset: Annotated[str | None, Option(help="Dataset name.")] = None,
93
+ new_table: Annotated[str | None, Option(help="New table name.")] = None,
94
+ ):
95
+ identifier, _ = get_table(project, table, dataset)
96
+ new_table = get_string("Provide a new table name")
97
+
98
+ state.spiral.project(project).rename_table(identifier, new_table)
99
+ CONSOLE.print("Success.")
100
+
101
+
63
102
  @app.command(help="Show the table key schema.")
64
103
  def key_schema(
65
104
  project: ProjectArg,
@@ -97,40 +136,9 @@ def flush(
97
136
  project: ProjectArg,
98
137
  table: Annotated[str | None, Option(help="Table name.")] = None,
99
138
  dataset: Annotated[str | None, Option(help="Dataset name.")] = None,
100
- keep: Annotated[
101
- Literal["1h", "2h", "4h"] | None,
102
- Option(help="Duration string that indicates how much WAL to keep. Defaults to 24h."),
103
- ] = None,
104
- full: Annotated[bool, Option(help="Flush full Write-Ahead-Log.")] = False,
105
139
  ):
106
- # TODO(marko): Use some human-readable duration parsing library.
107
- duration = None
108
- if keep is not None:
109
- if full:
110
- raise ValueError("Cannot specify both --keep and --full")
111
- match keep:
112
- case "1h":
113
- duration = datetime.timedelta(hours=1)
114
- case "2h":
115
- duration = datetime.timedelta(hours=2)
116
- case "4h":
117
- duration = datetime.timedelta(hours=4)
118
- case _:
119
- raise ValueError(f"Invalid duration string: {keep}")
120
-
121
- if full:
122
- # Warn and wait for confirmation.
123
- ERR_CONSOLE.print("[bold yellow]Warning: All currently open transaction will fail to commit.[/bold yellow]")
124
- if not questionary.confirm("Are you sure you want to continue?", default=False).ask(): # pyright: ignore[reportAny]
125
- ERR_CONSOLE.print("Aborting.")
126
- raise typer.Exit(1)
127
-
128
- duration = datetime.timedelta(hours=0)
129
-
130
- keep_latest_s = int(duration.total_seconds()) if duration is not None else None
131
-
132
140
  identifier, t = get_table(project, table, dataset)
133
- state.spiral.internal.flush_wal(t.core, keep_latest_s=keep_latest_s) # pyright: ignore[reportPrivateUsage]
141
+ state.spiral.internal.flush_wal(t.core) # pyright: ignore[reportPrivateUsage]
134
142
  CONSOLE.print(f"Flushed WAL for table {identifier} in project {project}.")
135
143
 
136
144
 
@@ -30,7 +30,7 @@ class Spiral:
30
30
  """Construct a table scan."""
31
31
  ...
32
32
 
33
- def load_scan(self, scan_state: ScanState) -> Scan:
33
+ def load_scan(self, plan_state: ScanState) -> Scan:
34
34
  """Load a scan from a serialized scan state."""
35
35
  ...
36
36
 
@@ -175,7 +175,7 @@ class ShuffleConfig:
175
175
  ): ...
176
176
 
177
177
  class Internal:
178
- def flush_wal(self, table: Table, *, keep_latest_s: int | None = None) -> None:
178
+ def flush_wal(self, table: Table) -> None:
179
179
  """
180
180
  Flush the write-ahead log of the table.
181
181
  """
@@ -57,6 +57,9 @@ class ScanState:
57
57
  @staticmethod
58
58
  def from_json(json: str) -> ScanState: ...
59
59
 
60
+ class MaterializablePlan:
61
+ pass
62
+
60
63
  class Scan:
61
64
  def key_schema(self) -> Schema: ...
62
65
  def schema(self) -> Schema: ...
@@ -67,7 +70,8 @@ class Scan:
67
70
  def column_groups(self) -> list[ColumnGroup]: ...
68
71
  def column_group_state(self, column_group: ColumnGroup) -> ColumnGroupState: ...
69
72
  def key_space_state(self, table_id: str) -> KeySpaceState: ...
70
- def scan_state(self) -> ScanState: ...
73
+ def plan_state(self) -> ScanState: ...
74
+ def materializable_plan(self) -> MaterializablePlan: ...
71
75
  def to_record_batches(
72
76
  self,
73
77
  key_range: KeyRange | None = None,
spiral/enrichment.py CHANGED
@@ -136,7 +136,7 @@ class Enrichment:
136
136
  _compute = partial(
137
137
  _enrichment_task,
138
138
  settings_dict=self._table.spiral.config.model_dump(),
139
- state_json=plan_scan.core.scan_state().to_json(),
139
+ state_json=plan_scan.core.plan_state().to_json(),
140
140
  output_table_id=self._table.table_id,
141
141
  partition_size_bytes=partition_size_bytes,
142
142
  )
spiral/scan.py CHANGED
@@ -125,7 +125,7 @@ class Scan:
125
125
  _read_shard = partial(
126
126
  _read_shard_task,
127
127
  settings_dict=self.spiral.config.model_dump(),
128
- state_json=self.core.scan_state().to_json(),
128
+ state_json=self.core.plan_state().to_json(),
129
129
  )
130
130
  return dd.from_map(_read_shard, self.shards())
131
131
 
spiral/table.py CHANGED
@@ -83,7 +83,7 @@ class Table(Expr):
83
83
  def __repr__(self):
84
84
  return f'Table("{self.identifier}")'
85
85
 
86
- def __getitem__(self, item: str) -> Expr:
86
+ def __getitem__(self, item: str | int | list[str]) -> Expr:
87
87
  return super().__getitem__(item)
88
88
 
89
89
  def select(self, *paths: str, exclude: list[str] = None) -> "Expr":