scistackplotdb 0.1.31__tar.gz → 0.1.33__tar.gz
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.
- {scistackplotdb-0.1.31 → scistackplotdb-0.1.33}/PKG-INFO +5 -3
- {scistackplotdb-0.1.31 → scistackplotdb-0.1.33}/pyproject.toml +14 -4
- {scistackplotdb-0.1.31 → scistackplotdb-0.1.33}/src/scistackplotdb/_versioned.py +38 -0
- scistackplotdb-0.1.33/src/scistackplotdb/bundle_section.py +59 -0
- {scistackplotdb-0.1.31 → scistackplotdb-0.1.33}/.gitignore +0 -0
- {scistackplotdb-0.1.31 → scistackplotdb-0.1.33}/README.md +0 -0
- {scistackplotdb-0.1.31 → scistackplotdb-0.1.33}/src/scistackplotdb/__init__.py +0 -0
- {scistackplotdb-0.1.31 → scistackplotdb-0.1.33}/src/scistackplotdb/endpoint.py +0 -0
- {scistackplotdb-0.1.31 → scistackplotdb-0.1.33}/src/scistackplotdb/hierarchy.py +0 -0
- {scistackplotdb-0.1.31 → scistackplotdb-0.1.33}/src/scistackplotdb/load.py +0 -0
- {scistackplotdb-0.1.31 → scistackplotdb-0.1.33}/src/scistackplotdb/presets.py +0 -0
- {scistackplotdb-0.1.31 → scistackplotdb-0.1.33}/src/scistackplotdb/saved.py +0 -0
- {scistackplotdb-0.1.31 → scistackplotdb-0.1.33}/src/scistackplotdb/source.py +0 -0
- {scistackplotdb-0.1.31 → scistackplotdb-0.1.33}/src/scistackplotdb/variants.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: scistackplotdb
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.33
|
|
4
4
|
Summary: scidb-backed plotting: load variables into long tables and plot them with scistackplot
|
|
5
5
|
Author: SciStack Contributors
|
|
6
6
|
License-Expression: MIT
|
|
@@ -17,8 +17,10 @@ Classifier: Programming Language :: Python :: 3.13
|
|
|
17
17
|
Classifier: Topic :: Scientific/Engineering :: Visualization
|
|
18
18
|
Classifier: Typing :: Typed
|
|
19
19
|
Requires-Python: >=3.10
|
|
20
|
-
Requires-Dist:
|
|
21
|
-
Requires-Dist:
|
|
20
|
+
Requires-Dist: sciduckdb==0.1.33
|
|
21
|
+
Requires-Dist: scistack-db==0.1.33
|
|
22
|
+
Requires-Dist: scistacklog==0.1.33
|
|
23
|
+
Requires-Dist: scistackplot==0.1.33
|
|
22
24
|
Provides-Extra: dev
|
|
23
25
|
Requires-Dist: matplotlib>=3.6; extra == 'dev'
|
|
24
26
|
Requires-Dist: pytest-cov>=4.0; extra == 'dev'
|
|
@@ -1,14 +1,22 @@
|
|
|
1
1
|
[build-system]
|
|
2
|
-
requires = ["hatchling", "hatch-vcs"]
|
|
2
|
+
requires = ["hatchling", "hatch-vcs", "hatch-dependency-coversion==0.0.1a4"]
|
|
3
3
|
build-backend = "hatchling.build"
|
|
4
4
|
|
|
5
5
|
[tool.hatch.version]
|
|
6
6
|
source = "vcs"
|
|
7
7
|
raw-options = { search_parent_directories = true, local_scheme = "no-local-version" }
|
|
8
8
|
|
|
9
|
+
# Sibling SciStack packages are pinned to EXACTLY this build's version at build
|
|
10
|
+
# time (lockstep releases), so [project] dependencies lists them unversioned. The
|
|
11
|
+
# extra "dynamic" entry is what makes hatchling run the hook. Every sibling in
|
|
12
|
+
# dependencies must be named here: CI's build job fails a wheel whose internal
|
|
13
|
+
# dependency is not "==<its own version>".
|
|
14
|
+
[tool.hatch.metadata.hooks.dependency-coversion]
|
|
15
|
+
override-versions-of = ["scistackplot", "scistack-db", "sciduckdb", "scistacklog"]
|
|
16
|
+
|
|
9
17
|
[project]
|
|
10
18
|
name = "scistackplotdb"
|
|
11
|
-
dynamic = ["version"]
|
|
19
|
+
dynamic = ["version", "dependency-coversioning"]
|
|
12
20
|
description = "scidb-backed plotting: load variables into long tables and plot them with scistackplot"
|
|
13
21
|
readme = "README.md"
|
|
14
22
|
license = "MIT"
|
|
@@ -37,8 +45,10 @@ classifiers = [
|
|
|
37
45
|
"Typing :: Typed",
|
|
38
46
|
]
|
|
39
47
|
dependencies = [
|
|
40
|
-
"scistackplot
|
|
41
|
-
"scistack-db
|
|
48
|
+
"scistackplot",
|
|
49
|
+
"scistack-db",
|
|
50
|
+
"sciduckdb",
|
|
51
|
+
"scistacklog",
|
|
42
52
|
]
|
|
43
53
|
|
|
44
54
|
[project.optional-dependencies]
|
|
@@ -352,3 +352,41 @@ class VersionedStore:
|
|
|
352
352
|
)
|
|
353
353
|
return {}
|
|
354
354
|
return envelope
|
|
355
|
+
|
|
356
|
+
# ---- copying a whole store (project bundles) ------------------------
|
|
357
|
+
|
|
358
|
+
def _all_columns(self) -> list[str]:
|
|
359
|
+
scope = [self.scope_column] if self.scope_column else []
|
|
360
|
+
return [self.id_column, *scope, "name", "version", "saved_at", "hidden", "envelope_json"]
|
|
361
|
+
|
|
362
|
+
def dump_rows(self, db) -> list[dict]:
|
|
363
|
+
"""Every row, every version, hidden ones too, as plain dicts: what a
|
|
364
|
+
project bundle carries (``scistackplotdb.bundle_section``). Nothing
|
|
365
|
+
is filtered -- a copy keeps the history the original kept."""
|
|
366
|
+
if not self.table_exists(db):
|
|
367
|
+
return []
|
|
368
|
+
cols = self._all_columns()
|
|
369
|
+
rows = db._duck._fetchall(
|
|
370
|
+
f"SELECT {', '.join(cols)} FROM {self.table} ORDER BY {self.id_column}, version"
|
|
371
|
+
)
|
|
372
|
+
Log.info("[%s] dump_rows: %d row(s)", self.tag, len(rows), layer=LAYER)
|
|
373
|
+
return [dict(zip(cols, row)) for row in rows]
|
|
374
|
+
|
|
375
|
+
def load_rows(self, db, rows: list[dict]) -> int:
|
|
376
|
+
"""Insert *rows* (from :meth:`dump_rows`) verbatim, ids and versions
|
|
377
|
+
kept; a row already present is left as it is. Returns rows inserted."""
|
|
378
|
+
if not rows:
|
|
379
|
+
return 0
|
|
380
|
+
self.ensure_table(db)
|
|
381
|
+
cols = self._all_columns()
|
|
382
|
+
before = db._duck._fetchone(f"SELECT count(*) FROM {self.table}")[0]
|
|
383
|
+
for row in rows:
|
|
384
|
+
db._duck._execute(
|
|
385
|
+
f"INSERT INTO {self.table} ({', '.join(cols)}) "
|
|
386
|
+
f"VALUES ({', '.join('?' for _ in cols)}) ON CONFLICT DO NOTHING",
|
|
387
|
+
[row.get(c) for c in cols],
|
|
388
|
+
)
|
|
389
|
+
after = db._duck._fetchone(f"SELECT count(*) FROM {self.table}")[0]
|
|
390
|
+
Log.info("[%s] load_rows: %d of %d row(s) inserted", self.tag, after - before,
|
|
391
|
+
len(rows), layer=LAYER)
|
|
392
|
+
return after - before
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"""
|
|
2
|
+
The ``plots`` section of a project bundle (``scidb.bundle``): saved plots and
|
|
3
|
+
plot presets, copied row for row.
|
|
4
|
+
|
|
5
|
+
Both stores key nothing by canvas ids or database record ids -- a saved plot
|
|
6
|
+
is named per VARIABLE, a preset per project -- so a verbatim copy into the
|
|
7
|
+
new project is the whole story: ids, versions and hidden rows kept, exactly
|
|
8
|
+
as the exporting project had them (``VersionedStore.dump_rows`` /
|
|
9
|
+
``load_rows``, the one owner of the table's columns).
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
from __future__ import annotations
|
|
13
|
+
|
|
14
|
+
import json
|
|
15
|
+
|
|
16
|
+
from scistacklog import Log
|
|
17
|
+
|
|
18
|
+
from . import presets, saved
|
|
19
|
+
|
|
20
|
+
LAYER = "scistackplotdb"
|
|
21
|
+
|
|
22
|
+
_STORES = {"saved_plots.json": saved.STORE, "presets.json": presets.STORE}
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class PlotsSection:
|
|
26
|
+
name = "plots"
|
|
27
|
+
|
|
28
|
+
def export(self, ctx) -> "dict[str, bytes]":
|
|
29
|
+
files: dict[str, bytes] = {}
|
|
30
|
+
for filename, store in _STORES.items():
|
|
31
|
+
rows = store.dump_rows(ctx.db)
|
|
32
|
+
if rows:
|
|
33
|
+
files[filename] = json.dumps(rows, indent=2, default=str).encode("utf-8")
|
|
34
|
+
Log.info("[bundle_section] plots export: %s", sorted(files), layer=LAYER)
|
|
35
|
+
return files
|
|
36
|
+
|
|
37
|
+
def import_(self, ctx, files: "dict[str, bytes]") -> dict:
|
|
38
|
+
report = {}
|
|
39
|
+
key_map = getattr(ctx, "key_map", None)
|
|
40
|
+
for filename, store in _STORES.items():
|
|
41
|
+
if filename in files:
|
|
42
|
+
rows = json.loads(files[filename].decode("utf-8"))
|
|
43
|
+
if key_map is not None and not key_map.is_identity:
|
|
44
|
+
rows = [_remap_row(row, store, key_map, ctx.map_report) for row in rows]
|
|
45
|
+
report[store.table] = store.load_rows(ctx.db, rows)
|
|
46
|
+
Log.info("[bundle_section] plots import: %s", report, layer=LAYER)
|
|
47
|
+
return report
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def _remap_row(row: dict, store, key_map, map_report) -> dict:
|
|
51
|
+
"""A saved plot or preset carried into another schema (portability Stage
|
|
52
|
+
6). A spec names factors in many fields (roles, groups, facets, colours,
|
|
53
|
+
filters, difference bars, ...), so every string EQUAL to an exporter key
|
|
54
|
+
is renamed (``KeyMap.exact_strings``) and the item is flagged for review
|
|
55
|
+
-- a factor that merely equals a key name cannot be told apart."""
|
|
56
|
+
envelope = json.loads(row["envelope_json"])
|
|
57
|
+
where = f"{store.noun} {row.get('name')!r}"
|
|
58
|
+
mapped = key_map.exact_strings(envelope, where, map_report)
|
|
59
|
+
return {**row, "envelope_json": json.dumps(mapped)}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|