pyspiral 0.6.9__cp312-abi3-macosx_11_0_arm64.whl → 0.7.12__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.
- {pyspiral-0.6.9.dist-info → pyspiral-0.7.12.dist-info}/METADATA +9 -8
- {pyspiral-0.6.9.dist-info → pyspiral-0.7.12.dist-info}/RECORD +53 -45
- {pyspiral-0.6.9.dist-info → pyspiral-0.7.12.dist-info}/entry_points.txt +1 -0
- spiral/__init__.py +20 -0
- spiral/_lib.abi3.so +0 -0
- spiral/api/__init__.py +1 -1
- spiral/api/client.py +1 -1
- spiral/api/types.py +1 -0
- spiral/cli/admin.py +2 -2
- spiral/cli/app.py +8 -4
- spiral/cli/fs.py +4 -4
- spiral/cli/iceberg.py +1 -1
- spiral/cli/key_spaces.py +15 -1
- spiral/cli/login.py +4 -3
- spiral/cli/orgs.py +8 -7
- spiral/cli/projects.py +4 -4
- spiral/cli/state.py +5 -3
- spiral/cli/tables.py +59 -36
- spiral/cli/telemetry.py +1 -1
- spiral/cli/types.py +2 -2
- spiral/cli/workloads.py +3 -3
- spiral/client.py +69 -22
- spiral/core/client/__init__.pyi +48 -13
- spiral/core/config/__init__.pyi +47 -0
- spiral/core/expr/__init__.pyi +15 -0
- spiral/core/expr/images/__init__.pyi +3 -0
- spiral/core/expr/list_/__init__.pyi +4 -0
- spiral/core/expr/refs/__init__.pyi +4 -0
- spiral/core/expr/str_/__init__.pyi +3 -0
- spiral/core/expr/struct_/__init__.pyi +6 -0
- spiral/core/expr/text/__init__.pyi +5 -0
- spiral/core/expr/udf/__init__.pyi +14 -0
- spiral/core/expr/video/__init__.pyi +3 -0
- spiral/core/table/__init__.pyi +37 -2
- spiral/core/table/spec/__init__.pyi +6 -4
- spiral/dataloader.py +52 -38
- spiral/dataset.py +10 -1
- spiral/enrichment.py +304 -0
- spiral/expressions/__init__.py +21 -23
- spiral/expressions/base.py +9 -4
- spiral/expressions/file.py +17 -0
- spiral/expressions/http.py +11 -80
- spiral/expressions/s3.py +16 -0
- spiral/expressions/tiff.py +2 -3
- spiral/expressions/udf.py +38 -24
- spiral/iceberg.py +3 -3
- spiral/project.py +34 -6
- spiral/scan.py +80 -33
- spiral/settings.py +19 -97
- spiral/streaming_/stream.py +1 -1
- spiral/table.py +40 -10
- spiral/transaction.py +99 -2
- spiral/expressions/io.py +0 -100
- spiral/expressions/mp4.py +0 -62
- spiral/expressions/png.py +0 -18
- spiral/expressions/qoi.py +0 -18
- spiral/expressions/refs.py +0 -58
- {pyspiral-0.6.9.dist-info → pyspiral-0.7.12.dist-info}/WHEEL +0 -0
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pyspiral
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.7.12
|
|
4
4
|
Classifier: Intended Audience :: Science/Research
|
|
5
5
|
Classifier: Operating System :: OS Independent
|
|
6
6
|
Classifier: Programming Language :: Python
|
|
7
7
|
Classifier: Programming Language :: Python :: 3
|
|
8
8
|
Classifier: Programming Language :: Python :: 3 :: Only
|
|
9
|
-
Classifier: Programming Language :: Python :: 3.10
|
|
10
|
-
Classifier: Programming Language :: Python :: 3.11
|
|
11
9
|
Classifier: Programming Language :: Python :: 3.12
|
|
12
10
|
Classifier: Programming Language :: Python :: 3.13
|
|
13
11
|
Classifier: Programming Language :: Rust
|
|
@@ -31,20 +29,23 @@ Requires-Dist: typer>=0.16
|
|
|
31
29
|
Requires-Dist: xxhash>=3.4.1
|
|
32
30
|
Requires-Dist: polars>=1.31.0 ; extra == 'polars'
|
|
33
31
|
Requires-Dist: duckdb>=1.3.2 ; extra == 'duckdb'
|
|
34
|
-
Requires-Dist:
|
|
35
|
-
Requires-Dist:
|
|
32
|
+
Requires-Dist: pyiceberg[s3fs]>=0.9.1 ; extra == 'iceberg'
|
|
33
|
+
Requires-Dist: datasets>=4.0.0 ; extra == 'huggingface'
|
|
36
34
|
Requires-Dist: mosaicml-streaming>=0.13.0 ; extra == 'streaming'
|
|
37
35
|
Requires-Dist: vortex-data>=0.52.1 ; extra == 'streaming'
|
|
36
|
+
Requires-Dist: dask>=2025.10.0 ; extra == 'dask'
|
|
37
|
+
Requires-Dist: distributed>=2025.10.0 ; extra == 'dask'
|
|
38
38
|
Provides-Extra: polars
|
|
39
39
|
Provides-Extra: duckdb
|
|
40
|
-
Provides-Extra:
|
|
41
|
-
Provides-Extra:
|
|
40
|
+
Provides-Extra: iceberg
|
|
41
|
+
Provides-Extra: huggingface
|
|
42
42
|
Provides-Extra: streaming
|
|
43
|
+
Provides-Extra: dask
|
|
43
44
|
Summary: Python client for Spiral.
|
|
44
45
|
Home-Page: https://spiraldb.com
|
|
45
46
|
Author-email: SpiralDB <hello@spiraldb.com>
|
|
46
47
|
License: Proprietary License
|
|
47
|
-
Requires-Python: >=3.
|
|
48
|
+
Requires-Python: >=3.12
|
|
48
49
|
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
|
|
49
50
|
|
|
50
51
|
# PySpiral
|
|
@@ -1,75 +1,83 @@
|
|
|
1
|
-
pyspiral-0.
|
|
2
|
-
pyspiral-0.
|
|
3
|
-
pyspiral-0.
|
|
4
|
-
spiral/__init__.py,sha256=
|
|
5
|
-
spiral/_lib.abi3.so,sha256=
|
|
1
|
+
pyspiral-0.7.12.dist-info/METADATA,sha256=pD6hAkv2h3odJlPZosBZSt8IqlCtuusYcsoOwo9v5R4,1875
|
|
2
|
+
pyspiral-0.7.12.dist-info/WHEEL,sha256=KQvxBiy7GLcML6Ad3w_ZPrgSvER1uXd7aYb6wy6b44Y,103
|
|
3
|
+
pyspiral-0.7.12.dist-info/entry_points.txt,sha256=R96Y3FpYX6XbQu9qMPfUTgiCcf4qM9OBQQZTDdBkZwA,74
|
|
4
|
+
spiral/__init__.py,sha256=PwaYBWFBtB7cYi7peMmhk_Lm5XzjRoLwOtLbUhc1ZDo,1449
|
|
5
|
+
spiral/_lib.abi3.so,sha256=WH2ysMTljTLXOUg8hBIkhm-Pj2Z30m1Scd6zBmreGUg,72162400
|
|
6
6
|
spiral/adbc.py,sha256=7IxfWIeQN-fh0W5OdN_PP2x3pzQYg6ZUOLsHg3jktqw,14842
|
|
7
|
-
spiral/api/__init__.py,sha256=
|
|
7
|
+
spiral/api/__init__.py,sha256=fguWdWeMnxWALRpqfKaUY5LmdQPsxTeyVIwIxElcRws,2240
|
|
8
8
|
spiral/api/admin.py,sha256=A1iVR1XYJSObZivPAD5UzmPuMgupXc9kaHNYYa_kwfs,585
|
|
9
|
-
spiral/api/client.py,sha256=
|
|
9
|
+
spiral/api/client.py,sha256=8mT1N6bn6w6E9LGV-JhjfKUPhpVskwY-5SMKV5I6olo,4641
|
|
10
10
|
spiral/api/filesystems.py,sha256=yEHgHfo7t1_becm0UFedc3nd49_G77hHjYwtYQ6P9XU,4240
|
|
11
11
|
spiral/api/key_space_indexes.py,sha256=-38rZXTdkL4mLhp9h3CtqyIyutzzq88tV6bhK05MqYE,640
|
|
12
12
|
spiral/api/organizations.py,sha256=B-8zZ7lFJANGK7dUNbo_aU-cgI959JBP9VcWb6wdgi0,1895
|
|
13
13
|
spiral/api/projects.py,sha256=1JC7VjqZJfwR6zfhBZr3OCwaf6zb-MXMOBTE_NztmcE,6356
|
|
14
14
|
spiral/api/telemetry.py,sha256=tfdA3E_EWJwFVxkQfkm8tiYGRubnx2LuE5nbfsk1oG4,474
|
|
15
15
|
spiral/api/text_indexes.py,sha256=_zVlGBytl-9-Unbu2POfZgLh40H1YRcagFtplgIG428,1828
|
|
16
|
-
spiral/api/types.py,sha256=
|
|
16
|
+
spiral/api/types.py,sha256=HpHsoBuf7IdlXb7Dw-BkBkEvxBVIhkI8JviqhuoP9pY,696
|
|
17
17
|
spiral/api/workers.py,sha256=0wZNUHMioDT53P1OBJfpjyDfIodHwwT6858z2IlRIM4,636
|
|
18
18
|
spiral/api/workloads.py,sha256=XAyXV7vgZcoyyoPoGvOT4jTpyFKFMvrrAfhL6d1h1kE,1748
|
|
19
19
|
spiral/arrow_.py,sha256=fdSIfIs7UjDxXZlppvOW0zz86W_70Pa5pagJilH2kOE,7583
|
|
20
20
|
spiral/cli/__init__.py,sha256=LutjpWZu5Rvmba8C8bPa5vOCv74JuAoE1kvz0nd48dE,2476
|
|
21
21
|
spiral/cli/__main__.py,sha256=kNaKM2xgJo7GRogf83nYldLM-RGUR6vymdGwZxywQu0,71
|
|
22
|
-
spiral/cli/admin.py,sha256
|
|
23
|
-
spiral/cli/app.py,sha256=
|
|
22
|
+
spiral/cli/admin.py,sha256=G_yCj8YKUiLuIZml3rqZLKS_2hBU0r4ILDdO_ZvRnCo,315
|
|
23
|
+
spiral/cli/app.py,sha256=eaY1SRf2wI1_T_cwrGUbldsU1QqfGrpAmN98gH1lJOE,2842
|
|
24
24
|
spiral/cli/console.py,sha256=6JHbAQV6MFWz3P-VzqPOjhHpkIQagsCdzTMvmuDKMkU,2580
|
|
25
|
-
spiral/cli/fs.py,sha256=
|
|
26
|
-
spiral/cli/iceberg.py,sha256=
|
|
27
|
-
spiral/cli/key_spaces.py,sha256=
|
|
28
|
-
spiral/cli/login.py,sha256=
|
|
29
|
-
spiral/cli/orgs.py,sha256=
|
|
25
|
+
spiral/cli/fs.py,sha256=chg4W6j7rPYxUiTUSVCkHoiF3vG5lcpqUKDYwp5VYtY,2919
|
|
26
|
+
spiral/cli/iceberg.py,sha256=wdMyl0j821MLnXNZ6Kwm65ogh98C-pjMJm3Y6YqlnTI,3249
|
|
27
|
+
spiral/cli/key_spaces.py,sha256=Xaw7WH-Qw_j6AxisdIoKfjAgVRXLM9qBFzuCTjPAFLI,3516
|
|
28
|
+
spiral/cli/login.py,sha256=2l2i38XNHGKtV4DP6PZPN4LHxceCn3AdHDE5nM2iK5M,760
|
|
29
|
+
spiral/cli/orgs.py,sha256=Y3hBPqBchPS72uJNn_OVx1fBIc2lO2EiKJsfRHAX1yE,2890
|
|
30
30
|
spiral/cli/printer.py,sha256=aosc763hDFgoXJGkiANmNyO3kAsecAS1JWgjEhn8GCM,1784
|
|
31
|
-
spiral/cli/projects.py,sha256=
|
|
32
|
-
spiral/cli/state.py,sha256=
|
|
33
|
-
spiral/cli/tables.py,sha256=
|
|
34
|
-
spiral/cli/telemetry.py,sha256=
|
|
31
|
+
spiral/cli/projects.py,sha256=awB2Q8gM1MtZOltWZ9ZPCbdUr-4WpsGHMR1rY12kv-s,5748
|
|
32
|
+
spiral/cli/state.py,sha256=3sKQuFtV2vCn3E1Dv7Sw9-IK5jiXCVBEQ9Ze17NZXDs,129
|
|
33
|
+
spiral/cli/tables.py,sha256=6vt6EBGt7I9b0kAQ6sQORbmWiKbRdH4ubQYjjuNBXEg,6900
|
|
34
|
+
spiral/cli/telemetry.py,sha256=9kp7lmimShsGoLRUic5aOEQ4hti-pPFMBFc4cdlPDmk,587
|
|
35
35
|
spiral/cli/text.py,sha256=DlWGe4JrkdERAiqyITNpk91Wqb63Re99rNYlIFsIamc,4031
|
|
36
|
-
spiral/cli/types.py,sha256=
|
|
37
|
-
spiral/cli/workloads.py,sha256=
|
|
38
|
-
spiral/client.py,sha256=
|
|
36
|
+
spiral/cli/types.py,sha256=o-HJhfoyPW3JD5p55yec6QNTtVGzbG-PG3kwjvZz5Zs,1358
|
|
37
|
+
spiral/cli/workloads.py,sha256=HL2_CkmlCm_nzTLjFogAW57Tev7RR73Qan_SZjsAoWk,2009
|
|
38
|
+
spiral/client.py,sha256=l5yej_59qME5RNYMXkS_eWL1XZTZ6FhgFXG5OBiGRlg,7828
|
|
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=
|
|
43
|
-
spiral/core/
|
|
42
|
+
spiral/core/client/__init__.pyi,sha256=TzmtVmfhc0uc9A8lGvUN9VE0qb8eVOyAmNpFUL8NHs0,7529
|
|
43
|
+
spiral/core/config/__init__.pyi,sha256=eOzEPCKICGNNZDivC-9NJLeOVrHicIu-IVa4v4jKLxg,1242
|
|
44
|
+
spiral/core/expr/__init__.pyi,sha256=3HSKjkotiEkxBvGBALXEBIie0JiyI9bCpehwA3nMQkU,571
|
|
45
|
+
spiral/core/expr/images/__init__.pyi,sha256=wnE_wZXq7a4iqTg3SVm-ssxGw1WQZyk5dGOPaP4Btko,73
|
|
46
|
+
spiral/core/expr/list_/__init__.pyi,sha256=Q_9c87eIQfZbqlaw_rq3fvs93YEsW7K5VYk6VZ4g6mU,126
|
|
47
|
+
spiral/core/expr/refs/__init__.pyi,sha256=nZZP3l_Z6bLx6V8lTcH3Jgo--xwfADOU2XdTAvM5IMk,127
|
|
48
|
+
spiral/core/expr/str_/__init__.pyi,sha256=Bm6fZK-d4fNbJuuBhVoWMACXUbQQ2SjlhgrOpdOHIPM,86
|
|
49
|
+
spiral/core/expr/struct_/__init__.pyi,sha256=MXckd98eV_x3X0RhEWvlkA3DcDXRtLs5pNnTQkc09nE,296
|
|
50
|
+
spiral/core/expr/text/__init__.pyi,sha256=ed83n1xcsGY7_QDhMmJGnSQ20UrJFXcdv1AveSEcS1c,175
|
|
51
|
+
spiral/core/expr/udf/__init__.pyi,sha256=zsZs081KVhY3-1JidqTkWMW81Qd_ScoTGZvasIhIK-4,358
|
|
52
|
+
spiral/core/expr/video/__init__.pyi,sha256=nQJEcSsigZuRpMjkI_O4EEtMK_n2zRvorcL_KEeD5vU,95
|
|
53
|
+
spiral/core/table/__init__.pyi,sha256=h84QDg6hLuPcmRpavx5zOZM77ZCi2-YwIlrrUZJp1sE,4374
|
|
44
54
|
spiral/core/table/manifests/__init__.pyi,sha256=eVfDpmhYSjafIvvALqAkZe5baN3Y1HpKpxYEbjwd4gQ,1043
|
|
45
55
|
spiral/core/table/metastore/__init__.pyi,sha256=rc3u9MwEKRvL2kxOc8lBorddFRnM8o_o1frqtae86a4,1697
|
|
46
|
-
spiral/core/table/spec/__init__.pyi,sha256=
|
|
47
|
-
spiral/dataloader.py,sha256=
|
|
48
|
-
spiral/dataset.py,sha256=
|
|
56
|
+
spiral/core/table/spec/__init__.pyi,sha256=fVuc2j3uoTdWfYNm720OfUIgrLYw9fRwj44maI5bgdY,5709
|
|
57
|
+
spiral/dataloader.py,sha256=W9siY4BF4p_rwTTSS4KgsaQsPLxxza6XmQhrdBzzMJ8,10592
|
|
58
|
+
spiral/dataset.py,sha256=S8pdiBXIhwMxQiJYgF7UI_8HkN7pZO798UzlO1LNXy4,8409
|
|
49
59
|
spiral/datetime_.py,sha256=elXaUWtZuuLVcu9E0aXnvYRPB9XWqZbLDToozQYQYjU,950
|
|
50
60
|
spiral/debug/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
51
61
|
spiral/debug/manifests.py,sha256=7f1O3ba9mrA5nXpOF9cEIQuUAteP5wiBkFy_diQJ7No,3216
|
|
52
62
|
spiral/debug/metrics.py,sha256=XdRDcjggtsLNGCAjam6IxG9072pz_d2C8iLApNRFUtk,2044
|
|
53
63
|
spiral/debug/scan.py,sha256=UEm_aRnql5pwDPTpZgakMLNjlzkKL4RurBFFqH_BLAQ,9526
|
|
54
|
-
spiral/
|
|
55
|
-
spiral/expressions/
|
|
56
|
-
spiral/expressions/
|
|
57
|
-
spiral/expressions/
|
|
64
|
+
spiral/enrichment.py,sha256=Fy8wqSIK8ZDkf7yKoNdUJpkVqSJQT1ofnfuwCZjwe58,11499
|
|
65
|
+
spiral/expressions/__init__.py,sha256=ZsD8g7vB0G7xy19GUiH4m79kw7KEkTQRwJl5Gn1cgtw,8049
|
|
66
|
+
spiral/expressions/base.py,sha256=PvhJkcUSsPSIaxirHVzM9zlqyBXiaiia1HXohXdOmL4,5377
|
|
67
|
+
spiral/expressions/file.py,sha256=7D9jIENJcoT0KFharBLkzK9dZgO4DYn5K_KCt0twefg,518
|
|
68
|
+
spiral/expressions/http.py,sha256=OOHh0WBxg3vwza_m74-rkoQWSclRMI60aPAbQ6yKZi0,486
|
|
58
69
|
spiral/expressions/list_.py,sha256=MMt5lf5H1M3O-x6N_PvqOLGq9NOk6Ukv0fPWwPC_uy4,1809
|
|
59
|
-
spiral/expressions/
|
|
60
|
-
spiral/expressions/png.py,sha256=KO8X0OmMzUFwpg2I_j0JTyldPzVXDWIMzjWMWDV9vIY,506
|
|
61
|
-
spiral/expressions/qoi.py,sha256=gvIbb6fXb_Bb080sn9wkpbGGrPs2UEcTXCfuv4-kcYQ,506
|
|
62
|
-
spiral/expressions/refs.py,sha256=omeHBQ5o6N4xgZ3x5Xz7IRrWwYBBtQY8DYK0NNAxeGo,2109
|
|
70
|
+
spiral/expressions/s3.py,sha256=PhQhMP-d8PLsSRtGCZbytnm7lI9VbDAbuSs2LBM4G7Q,505
|
|
63
71
|
spiral/expressions/str_.py,sha256=tY8RXW3JWvr1-bEfCZtk5FAf11wKJnXPuA9EoeJ9tA4,1265
|
|
64
72
|
spiral/expressions/struct.py,sha256=pGAnCDh6AK0BK1XfZ1qG4ce4ranIQEE1HQsgmzBcfwQ,2038
|
|
65
73
|
spiral/expressions/text.py,sha256=-02gBWYoyNQ3qQ1--9HTa8IryUDojYQVIp8C7rgnOWQ,1893
|
|
66
|
-
spiral/expressions/tiff.py,sha256=
|
|
67
|
-
spiral/expressions/udf.py,sha256=
|
|
74
|
+
spiral/expressions/tiff.py,sha256=4dngO97bT1QY0By7-PxOQVmSwQC3PQAiixVhLJ-4HMQ,7986
|
|
75
|
+
spiral/expressions/udf.py,sha256=XOxa7Kocb4Cg4q_qFvRT6hVnVzi22CQenqrvS-TL-VY,1936
|
|
68
76
|
spiral/grpc_.py,sha256=f3czdP1Mxme42Y5--a5ogYq1TTiWn-J_MlGjwJ2mWwM,1015
|
|
69
|
-
spiral/iceberg.py,sha256=
|
|
77
|
+
spiral/iceberg.py,sha256=02OkA348eFxkEbgreeTuVlzavVvZmM4hldrZI76PZ9I,914
|
|
70
78
|
spiral/iterable_dataset.py,sha256=Eekg9ad8tcwXcloHWReBbvCSr5ZappRHn2ldKTvwqS0,4622
|
|
71
79
|
spiral/key_space_index.py,sha256=NAB_nONEjpMYbse8suz42w7Qb5OPHuKN9h9CT2NJe08,1460
|
|
72
|
-
spiral/project.py,sha256=
|
|
80
|
+
spiral/project.py,sha256=dkYc5iWZzz_HMKcu1EXUNNsI7hnEyGy8VrnKdVmKjjE,8199
|
|
73
81
|
spiral/protogen/_/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
74
82
|
spiral/protogen/_/arrow/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
75
83
|
spiral/protogen/_/arrow/flight/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -87,16 +95,16 @@ spiral/protogen/_/substrait/extensions/__init__.py,sha256=nhnEnho70GAT8WPj2xtwJU
|
|
|
87
95
|
spiral/protogen/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
88
96
|
spiral/protogen/util.py,sha256=smnvVo6nYH3FfDm9jqhNLaXz4bbTBaQezHQDCTvZyiQ,1486
|
|
89
97
|
spiral/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
90
|
-
spiral/scan.py,sha256=
|
|
98
|
+
spiral/scan.py,sha256=X8CrUxCFWYzK4aL3VDM95Q7pZ5TNnYyYQYJunvARazw,12578
|
|
91
99
|
spiral/server.py,sha256=ztBmB5lBnUz-smQxR_tC8AI5SOhz17wH0MI3GuzDUdM,600
|
|
92
|
-
spiral/settings.py,sha256=
|
|
100
|
+
spiral/settings.py,sha256=Ae17TH_1kKiyDo6ePjPMeLfbG2pydKSQPRuJbVkro6E,938
|
|
93
101
|
spiral/snapshot.py,sha256=cTobi5jtiANxalGA-isokQHblNmXGtuUvgUGGNVybsI,1555
|
|
94
102
|
spiral/streaming_/__init__.py,sha256=s7MlW2ERsuZmZGExLFL6RcZon2e0tNBocBg5ANgki7k,61
|
|
95
103
|
spiral/streaming_/reader.py,sha256=tl_lC9xgh1-QFhsZn4xQT7It3PVTzHCEUT2BG2dWBRQ,4166
|
|
96
|
-
spiral/streaming_/stream.py,sha256=
|
|
104
|
+
spiral/streaming_/stream.py,sha256=DM1hBDHnWm1ZFKZ-hZ4zxeSXITcUI6kWzwdJZvywI8o,5915
|
|
97
105
|
spiral/substrait_.py,sha256=AKeOD4KIXvz2J4TYxnIneOiHddtBIyOhuNxVO_uH0eg,12592
|
|
98
|
-
spiral/table.py,sha256=
|
|
106
|
+
spiral/table.py,sha256=g6y1iV2Esk6kYhsIJfW7Wje0EGs7jgA0bVuZaSzNX1A,12068
|
|
99
107
|
spiral/text_index.py,sha256=FQ9rgIEGLSJryS9lFdMhKtPFey18BXoWbPXyvZPJJ04,442
|
|
100
|
-
spiral/transaction.py,sha256=
|
|
108
|
+
spiral/transaction.py,sha256=0g3xMBK2KNZVm7x6sEjeKb9U2KmlCe_-cvTwvin68Sg,5478
|
|
101
109
|
spiral/types_.py,sha256=W_jyO7F6rpPiH69jhgSgV7OxQZbOlb1Ho3InpKUP6Eo,155
|
|
102
|
-
pyspiral-0.
|
|
110
|
+
pyspiral-0.7.12.dist-info/RECORD,,
|
spiral/__init__.py
CHANGED
|
@@ -1,14 +1,20 @@
|
|
|
1
1
|
"""Python client for Spiral"""
|
|
2
2
|
|
|
3
|
+
import importlib
|
|
4
|
+
import os
|
|
5
|
+
import warnings
|
|
6
|
+
|
|
3
7
|
# This is here to make sure we load the native extension first
|
|
4
8
|
from spiral import _lib
|
|
5
9
|
|
|
6
10
|
# Eagerly import the Spiral library
|
|
7
11
|
assert _lib, "Spiral library"
|
|
8
12
|
|
|
13
|
+
|
|
9
14
|
from spiral.client import Spiral # noqa: E402
|
|
10
15
|
from spiral.core.client import Shard, ShuffleConfig # noqa: E402
|
|
11
16
|
from spiral.dataloader import SpiralDataLoader, World # noqa: E402
|
|
17
|
+
from spiral.enrichment import Enrichment # noqa: E402
|
|
12
18
|
from spiral.iceberg import Iceberg # noqa: E402
|
|
13
19
|
from spiral.key_space_index import KeySpaceIndex # noqa: E402
|
|
14
20
|
from spiral.project import Project # noqa: E402
|
|
@@ -24,6 +30,7 @@ __all__ = [
|
|
|
24
30
|
"Table",
|
|
25
31
|
"Snapshot",
|
|
26
32
|
"Transaction",
|
|
33
|
+
"Enrichment",
|
|
27
34
|
"Scan",
|
|
28
35
|
"Shard",
|
|
29
36
|
"ShuffleConfig",
|
|
@@ -33,3 +40,16 @@ __all__ = [
|
|
|
33
40
|
"World",
|
|
34
41
|
"Iceberg",
|
|
35
42
|
]
|
|
43
|
+
|
|
44
|
+
__version__ = importlib.metadata.version("pyspiral")
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def _warn_msg():
|
|
48
|
+
warnings.warn(
|
|
49
|
+
"Spiral does not support forking, and it may cause undefined behavior. \
|
|
50
|
+
Please use `spawn` or `forkserver` multiprocessing."
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
if hasattr(os, "register_at_fork"):
|
|
55
|
+
os.register_at_fork(before=_warn_msg)
|
spiral/_lib.abi3.so
CHANGED
|
Binary file
|
spiral/api/__init__.py
CHANGED
spiral/api/client.py
CHANGED
|
@@ -136,7 +136,7 @@ class _Client:
|
|
|
136
136
|
method,
|
|
137
137
|
path,
|
|
138
138
|
params=params or {},
|
|
139
|
-
headers={"
|
|
139
|
+
headers={"Authorization": f"Bearer {token.expose_secret()}"} if token else None,
|
|
140
140
|
**req_data,
|
|
141
141
|
)
|
|
142
142
|
|
spiral/api/types.py
CHANGED
spiral/cli/admin.py
CHANGED
|
@@ -8,7 +8,7 @@ app = AsyncTyper()
|
|
|
8
8
|
def sync(
|
|
9
9
|
org_id: OrgId | None = None,
|
|
10
10
|
):
|
|
11
|
-
state.
|
|
11
|
+
state.spiral.api._admin.sync_orgs()
|
|
12
12
|
|
|
13
|
-
for membership in state.
|
|
13
|
+
for membership in state.spiral.api._admin.sync_memberships(org_id):
|
|
14
14
|
CONSOLE.print(membership)
|
spiral/cli/app.py
CHANGED
|
@@ -22,7 +22,7 @@ from spiral.cli import (
|
|
|
22
22
|
text,
|
|
23
23
|
workloads,
|
|
24
24
|
)
|
|
25
|
-
from spiral.settings import LOG_DIR, PACKAGE_NAME
|
|
25
|
+
from spiral.settings import LOG_DIR, PACKAGE_NAME
|
|
26
26
|
|
|
27
27
|
app = AsyncTyper(name="spiral")
|
|
28
28
|
|
|
@@ -63,9 +63,13 @@ def _callback(
|
|
|
63
63
|
verbose: Annotated[
|
|
64
64
|
bool | None, typer.Option("--verbose", callback=verbose_callback, help=verbose_callback.__doc__)
|
|
65
65
|
] = None,
|
|
66
|
-
):
|
|
67
|
-
#
|
|
68
|
-
|
|
66
|
+
) -> None:
|
|
67
|
+
# Reload the spiral client to support testing under different env vars
|
|
68
|
+
from spiral import Spiral
|
|
69
|
+
from spiral.settings import settings
|
|
70
|
+
|
|
71
|
+
config = settings()
|
|
72
|
+
state.spiral = Spiral(config=config)
|
|
69
73
|
|
|
70
74
|
|
|
71
75
|
app.add_typer(orgs.app, name="orgs")
|
spiral/cli/fs.py
CHANGED
|
@@ -17,12 +17,12 @@ app = AsyncTyper(short_help="File Systems.")
|
|
|
17
17
|
|
|
18
18
|
@app.command(help="Show the file system configured for project.")
|
|
19
19
|
def show(project: ProjectArg):
|
|
20
|
-
file_system = state.
|
|
20
|
+
file_system = state.spiral.api.file_system.get_file_system(project)
|
|
21
21
|
CONSOLE.print(file_system)
|
|
22
22
|
|
|
23
23
|
|
|
24
24
|
def ask_provider():
|
|
25
|
-
res = state.
|
|
25
|
+
res = state.spiral.api.file_system.list_providers()
|
|
26
26
|
return questionary.select("Select a file system provider", choices=res).ask()
|
|
27
27
|
|
|
28
28
|
|
|
@@ -66,11 +66,11 @@ def update(
|
|
|
66
66
|
else:
|
|
67
67
|
raise ValueError(f"Unknown file system type: {type_}")
|
|
68
68
|
|
|
69
|
-
fs = state.
|
|
69
|
+
fs = state.spiral.api.file_system.update_file_system(project, file_system)
|
|
70
70
|
CONSOLE.print(fs)
|
|
71
71
|
|
|
72
72
|
|
|
73
73
|
@app.command(help="Lists the available built-in file system providers.")
|
|
74
74
|
def list_providers():
|
|
75
|
-
for provider in state.
|
|
75
|
+
for provider in state.spiral.api.file_system.list_providers():
|
|
76
76
|
CONSOLE.print(provider)
|
spiral/cli/iceberg.py
CHANGED
|
@@ -8,7 +8,7 @@ from typer import Argument
|
|
|
8
8
|
from spiral.cli import CONSOLE, ERR_CONSOLE, AsyncTyper, state
|
|
9
9
|
from spiral.cli.types import ProjectArg
|
|
10
10
|
|
|
11
|
-
app = AsyncTyper(short_help="Apache Iceberg Catalog")
|
|
11
|
+
app = AsyncTyper(short_help="Apache Iceberg Catalog.")
|
|
12
12
|
|
|
13
13
|
|
|
14
14
|
@app.command(help="List namespaces.")
|
spiral/cli/key_spaces.py
CHANGED
|
@@ -64,7 +64,7 @@ def show(
|
|
|
64
64
|
"""Show index partitions."""
|
|
65
65
|
index_id = get_index_id(project, name)
|
|
66
66
|
index = state.spiral.key_space_index(index_id)
|
|
67
|
-
shards = state.spiral.
|
|
67
|
+
shards = state.spiral.internal.compute_shards(index.core)
|
|
68
68
|
|
|
69
69
|
rich_table = rich.table.Table("Begin", "End", "Cardinality", title=f"Index {index.name} Partitions")
|
|
70
70
|
for partition in shards:
|
|
@@ -87,3 +87,17 @@ def sync(
|
|
|
87
87
|
index_id = get_index_id(project, name)
|
|
88
88
|
response = state.spiral.api.key_space_indexes.sync_index(index_id, SyncIndexRequest(resources=resources))
|
|
89
89
|
CONSOLE.print(f"Triggered sync job {response.worker_id} for index {index_id}.")
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
# TODO(marko): This will be removed.
|
|
93
|
+
@app.command(help="Run a sync and wait for it to complete.")
|
|
94
|
+
def sync_local(
|
|
95
|
+
project: ProjectArg,
|
|
96
|
+
name: Annotated[str | None, Option(help="Index name.")] = None,
|
|
97
|
+
):
|
|
98
|
+
"""Run a sync and wait for it to complete."""
|
|
99
|
+
index_id = get_index_id(project, name)
|
|
100
|
+
index = state.spiral.key_space_index(index_id)
|
|
101
|
+
snapshot = state.spiral.table(index.table_id).snapshot()
|
|
102
|
+
state.spiral.internal.update_key_space_index(index.core, snapshot.core)
|
|
103
|
+
CONSOLE.print(f"Index {index.name} is up to date as-of {snapshot.asof}.")
|
spiral/cli/login.py
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import jwt
|
|
2
2
|
|
|
3
3
|
from spiral.cli import CONSOLE, state
|
|
4
|
+
from spiral.core.authn import DeviceCodeAuth
|
|
4
5
|
|
|
5
6
|
|
|
6
7
|
def command(org_id: str | None = None, force: bool = False, show_token: bool = False):
|
|
7
|
-
token =
|
|
8
|
+
token = DeviceCodeAuth.default().authenticate(force=force, org_id=org_id)
|
|
8
9
|
CONSOLE.print("Successfully logged in.")
|
|
9
10
|
if show_token:
|
|
10
11
|
CONSOLE.print(token.expose_secret(), soft_wrap=True)
|
|
@@ -12,7 +13,7 @@ def command(org_id: str | None = None, force: bool = False, show_token: bool = F
|
|
|
12
13
|
|
|
13
14
|
def whoami():
|
|
14
15
|
"""Display the current user's information."""
|
|
15
|
-
payload = jwt.decode(state.
|
|
16
|
+
payload = jwt.decode(state.spiral.authn.token().expose_secret(), options={"verify_signature": False})
|
|
16
17
|
|
|
17
18
|
if "org_id" in payload:
|
|
18
19
|
CONSOLE.print(f"{payload['org_id']}")
|
|
@@ -20,5 +21,5 @@ def whoami():
|
|
|
20
21
|
|
|
21
22
|
|
|
22
23
|
def logout():
|
|
23
|
-
|
|
24
|
+
DeviceCodeAuth.default().logout()
|
|
24
25
|
CONSOLE.print("Logged out.")
|
spiral/cli/orgs.py
CHANGED
|
@@ -9,13 +9,14 @@ from typer import Option
|
|
|
9
9
|
from spiral.api.organizations import CreateOrgRequest, InviteUserRequest, OrgRole, PortalLinkIntent, PortalLinkRequest
|
|
10
10
|
from spiral.cli import CONSOLE, ERR_CONSOLE, AsyncTyper, state
|
|
11
11
|
from spiral.cli.types import OrganizationArg
|
|
12
|
+
from spiral.core.authn import DeviceCodeAuth
|
|
12
13
|
|
|
13
14
|
app = AsyncTyper(short_help="Org admin.")
|
|
14
15
|
|
|
15
16
|
|
|
16
17
|
@app.command(help="Switch the active organization.")
|
|
17
18
|
def switch(org_id: OrganizationArg):
|
|
18
|
-
|
|
19
|
+
DeviceCodeAuth.default().authenticate(org_id=org_id)
|
|
19
20
|
CONSOLE.print(f"Switched to organization: {org_id}")
|
|
20
21
|
|
|
21
22
|
|
|
@@ -23,10 +24,10 @@ def switch(org_id: OrganizationArg):
|
|
|
23
24
|
def create(
|
|
24
25
|
name: Annotated[str | None, Option(help="The human-readable name of the organization.")] = None,
|
|
25
26
|
):
|
|
26
|
-
res = state.
|
|
27
|
+
res = state.spiral.api.organization.create(CreateOrgRequest(name=name))
|
|
27
28
|
|
|
28
29
|
# Authenticate to the new organization
|
|
29
|
-
|
|
30
|
+
DeviceCodeAuth.default().authenticate(org_id=res.org.id)
|
|
30
31
|
|
|
31
32
|
CONSOLE.print(f"{res.org.name} [dim]{res.org.id}[/dim]")
|
|
32
33
|
|
|
@@ -36,7 +37,7 @@ def ls():
|
|
|
36
37
|
org_id = current_org_id()
|
|
37
38
|
|
|
38
39
|
table = Table("", "id", "name", "role", title="Organizations")
|
|
39
|
-
for m in state.
|
|
40
|
+
for m in state.spiral.api.organization.list_memberships():
|
|
40
41
|
table.add_row("👉" if m.org.id == org_id else "", m.org.id, m.org.name, m.role)
|
|
41
42
|
|
|
42
43
|
CONSOLE.print(table)
|
|
@@ -44,7 +45,7 @@ def ls():
|
|
|
44
45
|
|
|
45
46
|
@app.command(help="Invite a user to the organization.")
|
|
46
47
|
def invite(email: str, role: OrgRole = OrgRole.MEMBER, expires_in_days: int = 7):
|
|
47
|
-
state.
|
|
48
|
+
state.spiral.api.organization.invite_user(
|
|
48
49
|
InviteUserRequest(email=email, role=role, expires_in_days=expires_in_days)
|
|
49
50
|
)
|
|
50
51
|
CONSOLE.print(f"Invited {email} as a {role.value}.")
|
|
@@ -76,13 +77,13 @@ def domains():
|
|
|
76
77
|
|
|
77
78
|
|
|
78
79
|
def _do_action(intent: PortalLinkIntent):
|
|
79
|
-
res = state.
|
|
80
|
+
res = state.spiral.api.organization.portal_link(PortalLinkRequest(intent=intent))
|
|
80
81
|
CONSOLE.print(f"Opening the configuration portal:\n{res.url}")
|
|
81
82
|
webbrowser.open(res.url)
|
|
82
83
|
|
|
83
84
|
|
|
84
85
|
def current_org_id():
|
|
85
|
-
if token := state.
|
|
86
|
+
if token := state.spiral.authn.token():
|
|
86
87
|
if org_id := jwt.decode(token.expose_secret(), options={"verify_signature": False}).get("org_id"):
|
|
87
88
|
return org_id
|
|
88
89
|
ERR_CONSOLE.print("You are not logged in to an organization.")
|
spiral/cli/projects.py
CHANGED
|
@@ -27,7 +27,7 @@ app = AsyncTyper(short_help="Projects and grants.")
|
|
|
27
27
|
|
|
28
28
|
@app.command(help="List projects.")
|
|
29
29
|
def ls():
|
|
30
|
-
projects = list(state.
|
|
30
|
+
projects = list(state.spiral.api.project.list())
|
|
31
31
|
CONSOLE.print(printer.table_of_models(Project, projects))
|
|
32
32
|
|
|
33
33
|
|
|
@@ -38,7 +38,7 @@ def create(
|
|
|
38
38
|
] = None,
|
|
39
39
|
name: Annotated[str | None, Option(help="Friendly name for the project.")] = None,
|
|
40
40
|
):
|
|
41
|
-
res = state.
|
|
41
|
+
res = state.spiral.api.project.create(CreateProjectRequest(id_prefix=id_prefix, name=name))
|
|
42
42
|
CONSOLE.print(f"Created project {res.project.id}")
|
|
43
43
|
|
|
44
44
|
|
|
@@ -130,7 +130,7 @@ def grant(
|
|
|
130
130
|
else:
|
|
131
131
|
raise ValueError("Invalid grant principal")
|
|
132
132
|
|
|
133
|
-
state.
|
|
133
|
+
state.spiral.api.project.grant_role(
|
|
134
134
|
project,
|
|
135
135
|
GrantRoleRequest(
|
|
136
136
|
role_id=role,
|
|
@@ -143,5 +143,5 @@ def grant(
|
|
|
143
143
|
|
|
144
144
|
@app.command(help="List project grants.")
|
|
145
145
|
def grants(project: ProjectArg):
|
|
146
|
-
project_grants = list(state.
|
|
146
|
+
project_grants = list(state.spiral.api.project.list_grants(project))
|
|
147
147
|
CONSOLE.print(printer.table_of_models(Grant, project_grants, title="Project Grants"))
|
spiral/cli/state.py
CHANGED
spiral/cli/tables.py
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import
|
|
2
|
-
from typing import Annotated
|
|
1
|
+
from collections.abc import Callable
|
|
2
|
+
from typing import Annotated
|
|
3
3
|
|
|
4
4
|
import questionary
|
|
5
5
|
import rich
|
|
@@ -60,6 +60,60 @@ def ls(
|
|
|
60
60
|
CONSOLE.print(rich_table)
|
|
61
61
|
|
|
62
62
|
|
|
63
|
+
@app.command(help="Show the leading rows of the table.")
|
|
64
|
+
def head(
|
|
65
|
+
project: ProjectArg,
|
|
66
|
+
table: Annotated[str | None, Option(help="Table name.")] = None,
|
|
67
|
+
dataset: Annotated[str | None, Option(help="Dataset name.")] = None,
|
|
68
|
+
n: Annotated[int, Option("-n", help="Maximum number of rows to show. Defaults to 10.")] = 10,
|
|
69
|
+
):
|
|
70
|
+
import polars as pl
|
|
71
|
+
|
|
72
|
+
_, t = get_table(project, table, dataset)
|
|
73
|
+
|
|
74
|
+
with pl.Config(tbl_rows=-1):
|
|
75
|
+
CONSOLE.print(t.to_polars().limit(n).collect())
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def validate_non_empty_str(text: str) -> bool | str:
|
|
79
|
+
if len(text) > 0:
|
|
80
|
+
return True
|
|
81
|
+
|
|
82
|
+
return "Must provide at least one character."
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def get_string(message: str, validate: Callable[[str], bool | str] = validate_non_empty_str) -> str:
|
|
86
|
+
return questionary.text(message, validate=validate).ask()
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
@app.command(help="Move table to a different dataset.")
|
|
90
|
+
def move(
|
|
91
|
+
project: ProjectArg,
|
|
92
|
+
table: Annotated[str | None, Option(help="Table name.")] = None,
|
|
93
|
+
dataset: Annotated[str | None, Option(help="Dataset name.")] = None,
|
|
94
|
+
new_dataset: Annotated[str | None, Option(help="New dataset name.")] = None,
|
|
95
|
+
):
|
|
96
|
+
identifier, _ = get_table(project, table, dataset)
|
|
97
|
+
new_dataset = get_string("Provide a new dataset name")
|
|
98
|
+
|
|
99
|
+
state.spiral.project(project).move_table(identifier, new_dataset)
|
|
100
|
+
CONSOLE.print("Success.")
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
@app.command(help="Rename table.")
|
|
104
|
+
def rename(
|
|
105
|
+
project: ProjectArg,
|
|
106
|
+
table: Annotated[str | None, Option(help="Table name.")] = None,
|
|
107
|
+
dataset: Annotated[str | None, Option(help="Dataset name.")] = None,
|
|
108
|
+
new_table: Annotated[str | None, Option(help="New table name.")] = None,
|
|
109
|
+
):
|
|
110
|
+
identifier, _ = get_table(project, table, dataset)
|
|
111
|
+
new_table = get_string("Provide a new table name")
|
|
112
|
+
|
|
113
|
+
state.spiral.project(project).rename_table(identifier, new_table)
|
|
114
|
+
CONSOLE.print("Success.")
|
|
115
|
+
|
|
116
|
+
|
|
63
117
|
@app.command(help="Show the table key schema.")
|
|
64
118
|
def key_schema(
|
|
65
119
|
project: ProjectArg,
|
|
@@ -97,40 +151,9 @@ def flush(
|
|
|
97
151
|
project: ProjectArg,
|
|
98
152
|
table: Annotated[str | None, Option(help="Table name.")] = None,
|
|
99
153
|
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
154
|
):
|
|
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
155
|
identifier, t = get_table(project, table, dataset)
|
|
133
|
-
state.spiral.
|
|
156
|
+
state.spiral.internal.flush_wal(t.core) # pyright: ignore[reportPrivateUsage]
|
|
134
157
|
CONSOLE.print(f"Flushed WAL for table {identifier} in project {project}.")
|
|
135
158
|
|
|
136
159
|
|
|
@@ -143,10 +166,10 @@ def manifests(
|
|
|
143
166
|
_, t = get_table(project, table, dataset)
|
|
144
167
|
s = t.snapshot()
|
|
145
168
|
|
|
146
|
-
key_space_state = state.spiral.
|
|
169
|
+
key_space_state = state.spiral.internal.key_space_state(s.core) # pyright: ignore[reportPrivateUsage]
|
|
147
170
|
key_space_manifest = key_space_state.manifest
|
|
148
171
|
|
|
149
|
-
column_groups_states = state.spiral.
|
|
172
|
+
column_groups_states = state.spiral.internal.column_groups_states(s.core, key_space_state) # pyright: ignore[reportPrivateUsage]
|
|
150
173
|
display_manifests(key_space_manifest, [(x.column_group, x.manifest) for x in column_groups_states])
|
|
151
174
|
|
|
152
175
|
|