python-jack-knife 0.7.0__tar.gz → 0.7.1__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.
- {python_jack_knife-0.7.0/src/python_jack_knife.egg-info → python_jack_knife-0.7.1}/PKG-INFO +1 -1
- {python_jack_knife-0.7.0 → python_jack_knife-0.7.1}/src/pjk/history.py +3 -0
- {python_jack_knife-0.7.0 → python_jack_knife-0.7.1}/src/pjk/integrations/postgres_pipe.py +12 -3
- {python_jack_knife-0.7.0 → python_jack_knife-0.7.1}/src/pjk/pipes/factory.py +1 -1
- {python_jack_knife-0.7.0 → python_jack_knife-0.7.1}/src/pjk/pipes/select.py +2 -2
- {python_jack_knife-0.7.0 → python_jack_knife-0.7.1}/src/pjk/sinks/graph_bar_line.py +11 -9
- {python_jack_knife-0.7.0 → python_jack_knife-0.7.1}/src/pjk/sources/npy_source.py +3 -4
- {python_jack_knife-0.7.0 → python_jack_knife-0.7.1}/src/pjk/version.py +1 -1
- {python_jack_knife-0.7.0 → python_jack_knife-0.7.1/src/python_jack_knife.egg-info}/PKG-INFO +1 -1
- {python_jack_knife-0.7.0 → python_jack_knife-0.7.1}/LICENSE +0 -0
- {python_jack_knife-0.7.0 → python_jack_knife-0.7.1}/README.md +0 -0
- {python_jack_knife-0.7.0 → python_jack_knife-0.7.1}/pyproject.toml +0 -0
- {python_jack_knife-0.7.0 → python_jack_knife-0.7.1}/setup.cfg +0 -0
- {python_jack_knife-0.7.0 → python_jack_knife-0.7.1}/src/pjk/__init__.py +0 -0
- {python_jack_knife-0.7.0 → python_jack_knife-0.7.1}/src/pjk/common.py +0 -0
- {python_jack_knife-0.7.0 → python_jack_knife-0.7.1}/src/pjk/components.py +0 -0
- {python_jack_knife-0.7.0 → python_jack_knife-0.7.1}/src/pjk/integrations/opensearch_client.py +0 -0
- {python_jack_knife-0.7.0 → python_jack_knife-0.7.1}/src/pjk/integrations/opensearch_index_sink.py +0 -0
- {python_jack_knife-0.7.0 → python_jack_knife-0.7.1}/src/pjk/integrations/opensearch_query_pipe.py +0 -0
- {python_jack_knife-0.7.0 → python_jack_knife-0.7.1}/src/pjk/integrations/snowflake_pipe.py +0 -0
- {python_jack_knife-0.7.0 → python_jack_knife-0.7.1}/src/pjk/log.py +0 -0
- {python_jack_knife-0.7.0 → python_jack_knife-0.7.1}/src/pjk/main.py +0 -0
- {python_jack_knife-0.7.0 → python_jack_knife-0.7.1}/src/pjk/man_page.py +0 -0
- {python_jack_knife-0.7.0 → python_jack_knife-0.7.1}/src/pjk/parser.py +0 -0
- {python_jack_knife-0.7.0 → python_jack_knife-0.7.1}/src/pjk/pipes/__init__.py +0 -0
- {python_jack_knife-0.7.0 → python_jack_knife-0.7.1}/src/pjk/pipes/denorm.py +0 -0
- {python_jack_knife-0.7.0 → python_jack_knife-0.7.1}/src/pjk/pipes/filter.py +0 -0
- {python_jack_knife-0.7.0 → python_jack_knife-0.7.1}/src/pjk/pipes/head.py +0 -0
- {python_jack_knife-0.7.0 → python_jack_knife-0.7.1}/src/pjk/pipes/join.py +0 -0
- {python_jack_knife-0.7.0 → python_jack_knife-0.7.1}/src/pjk/pipes/let_reduce.py +0 -0
- {python_jack_knife-0.7.0 → python_jack_knife-0.7.1}/src/pjk/pipes/map.py +0 -0
- {python_jack_knife-0.7.0 → python_jack_knife-0.7.1}/src/pjk/pipes/move_field.py +0 -0
- {python_jack_knife-0.7.0 → python_jack_knife-0.7.1}/src/pjk/pipes/progress_pipe.py +0 -0
- {python_jack_knife-0.7.0 → python_jack_knife-0.7.1}/src/pjk/pipes/query_pipe.py +0 -0
- {python_jack_knife-0.7.0 → python_jack_knife-0.7.1}/src/pjk/pipes/remove_field.py +0 -0
- {python_jack_knife-0.7.0 → python_jack_knife-0.7.1}/src/pjk/pipes/sample.py +0 -0
- {python_jack_knife-0.7.0 → python_jack_knife-0.7.1}/src/pjk/pipes/sort.py +0 -0
- {python_jack_knife-0.7.0 → python_jack_knife-0.7.1}/src/pjk/pipes/tail.py +0 -0
- {python_jack_knife-0.7.0 → python_jack_knife-0.7.1}/src/pjk/pipes/user_pipe_factory.py +0 -0
- {python_jack_knife-0.7.0 → python_jack_knife-0.7.1}/src/pjk/pipes/where.py +0 -0
- {python_jack_knife-0.7.0 → python_jack_knife-0.7.1}/src/pjk/progress.py +0 -0
- {python_jack_knife-0.7.0 → python_jack_knife-0.7.1}/src/pjk/registry.py +0 -0
- {python_jack_knife-0.7.0 → python_jack_knife-0.7.1}/src/pjk/sinks/__init__.py +0 -0
- {python_jack_knife-0.7.0 → python_jack_knife-0.7.1}/src/pjk/sinks/create_sink.py +0 -0
- {python_jack_knife-0.7.0 → python_jack_knife-0.7.1}/src/pjk/sinks/csv_sink.py +0 -0
- {python_jack_knife-0.7.0 → python_jack_knife-0.7.1}/src/pjk/sinks/devnull.py +0 -0
- {python_jack_knife-0.7.0 → python_jack_knife-0.7.1}/src/pjk/sinks/dir_sink.py +0 -0
- {python_jack_knife-0.7.0 → python_jack_knife-0.7.1}/src/pjk/sinks/expect.py +0 -0
- {python_jack_knife-0.7.0 → python_jack_knife-0.7.1}/src/pjk/sinks/factory.py +0 -0
- {python_jack_knife-0.7.0 → python_jack_knife-0.7.1}/src/pjk/sinks/format_sink.py +0 -0
- {python_jack_knife-0.7.0 → python_jack_knife-0.7.1}/src/pjk/sinks/graph.py +0 -0
- {python_jack_knife-0.7.0 → python_jack_knife-0.7.1}/src/pjk/sinks/graph_cumulative.py +0 -0
- {python_jack_knife-0.7.0 → python_jack_knife-0.7.1}/src/pjk/sinks/graph_hist.py +0 -0
- {python_jack_knife-0.7.0 → python_jack_knife-0.7.1}/src/pjk/sinks/graph_scatter.py +0 -0
- {python_jack_knife-0.7.0 → python_jack_knife-0.7.1}/src/pjk/sinks/json_sink.py +0 -0
- {python_jack_knife-0.7.0 → python_jack_knife-0.7.1}/src/pjk/sinks/s3_sink.py +0 -0
- {python_jack_knife-0.7.0 → python_jack_knife-0.7.1}/src/pjk/sinks/s3_stream.py +0 -0
- {python_jack_knife-0.7.0 → python_jack_knife-0.7.1}/src/pjk/sinks/sinks.py +0 -0
- {python_jack_knife-0.7.0 → python_jack_knife-0.7.1}/src/pjk/sinks/stdout.py +0 -0
- {python_jack_knife-0.7.0 → python_jack_knife-0.7.1}/src/pjk/sinks/tsv_sink.py +0 -0
- {python_jack_knife-0.7.0 → python_jack_knife-0.7.1}/src/pjk/sinks/user_sink_factory.py +0 -0
- {python_jack_knife-0.7.0 → python_jack_knife-0.7.1}/src/pjk/sources/__init__.py +0 -0
- {python_jack_knife-0.7.0 → python_jack_knife-0.7.1}/src/pjk/sources/csv_source.py +0 -0
- {python_jack_knife-0.7.0 → python_jack_knife-0.7.1}/src/pjk/sources/dir_source.py +0 -0
- {python_jack_knife-0.7.0 → python_jack_knife-0.7.1}/src/pjk/sources/factory.py +0 -0
- {python_jack_knife-0.7.0 → python_jack_knife-0.7.1}/src/pjk/sources/favorite_source.py +0 -0
- {python_jack_knife-0.7.0 → python_jack_knife-0.7.1}/src/pjk/sources/format_source.py +0 -0
- {python_jack_knife-0.7.0 → python_jack_knife-0.7.1}/src/pjk/sources/inline_source.py +0 -0
- {python_jack_knife-0.7.0 → python_jack_knife-0.7.1}/src/pjk/sources/json_source.py +0 -0
- {python_jack_knife-0.7.0 → python_jack_knife-0.7.1}/src/pjk/sources/lazy_file.py +0 -0
- {python_jack_knife-0.7.0 → python_jack_knife-0.7.1}/src/pjk/sources/lazy_file_local.py +0 -0
- {python_jack_knife-0.7.0 → python_jack_knife-0.7.1}/src/pjk/sources/lazy_file_s3.py +0 -0
- {python_jack_knife-0.7.0 → python_jack_knife-0.7.1}/src/pjk/sources/parquet_source.py +0 -0
- {python_jack_knife-0.7.0 → python_jack_knife-0.7.1}/src/pjk/sources/s3_source.py +0 -0
- {python_jack_knife-0.7.0 → python_jack_knife-0.7.1}/src/pjk/sources/source_list.py +0 -0
- {python_jack_knife-0.7.0 → python_jack_knife-0.7.1}/src/pjk/sources/sql_source.py +0 -0
- {python_jack_knife-0.7.0 → python_jack_knife-0.7.1}/src/pjk/sources/tsv_source.py +0 -0
- {python_jack_knife-0.7.0 → python_jack_knife-0.7.1}/src/pjk/sources/user_source_factory.py +0 -0
- {python_jack_knife-0.7.0 → python_jack_knife-0.7.1}/src/pjk/usage.py +0 -0
- {python_jack_knife-0.7.0 → python_jack_knife-0.7.1}/src/python_jack_knife.egg-info/SOURCES.txt +0 -0
- {python_jack_knife-0.7.0 → python_jack_knife-0.7.1}/src/python_jack_knife.egg-info/dependency_links.txt +0 -0
- {python_jack_knife-0.7.0 → python_jack_knife-0.7.1}/src/python_jack_knife.egg-info/entry_points.txt +0 -0
- {python_jack_knife-0.7.0 → python_jack_knife-0.7.1}/src/python_jack_knife.egg-info/requires.txt +0 -0
- {python_jack_knife-0.7.0 → python_jack_knife-0.7.1}/src/python_jack_knife.egg-info/top_level.txt +0 -0
|
@@ -35,9 +35,12 @@ class DBClient:
|
|
|
35
35
|
self.conn = DBClient._connection
|
|
36
36
|
|
|
37
37
|
def close(self):
|
|
38
|
+
import pg8000 # lazy
|
|
38
39
|
if self.conn is not None:
|
|
39
40
|
try:
|
|
40
41
|
self.conn.close()
|
|
42
|
+
except pg8000.exceptions.InterfaceError:
|
|
43
|
+
pass
|
|
41
44
|
finally:
|
|
42
45
|
DBClient._connection = None
|
|
43
46
|
|
|
@@ -123,10 +126,15 @@ class PostgresPipe(QueryPipe,Integration):
|
|
|
123
126
|
|
|
124
127
|
self.params_field = "params" # optional: list/tuple (positional) or dict (named)
|
|
125
128
|
|
|
129
|
+
self.client = None
|
|
130
|
+
|
|
126
131
|
def reset(self):
|
|
127
132
|
# stateless across reset
|
|
128
133
|
pass
|
|
129
134
|
|
|
135
|
+
def close(self):
|
|
136
|
+
self.client.close()
|
|
137
|
+
|
|
130
138
|
def _make_header(self, cur, query: str, params=None) -> Dict[str, Any]:
|
|
131
139
|
"""
|
|
132
140
|
Inspect the cursor and build a full header record.
|
|
@@ -155,7 +163,7 @@ class PostgresPipe(QueryPipe,Integration):
|
|
|
155
163
|
return h
|
|
156
164
|
|
|
157
165
|
def execute_query_returning_S_xO_iterable(self, record):
|
|
158
|
-
client = DBClient(
|
|
166
|
+
self.client = DBClient(
|
|
159
167
|
host=self.db_host,
|
|
160
168
|
username=self.db_user,
|
|
161
169
|
password=self.db_pass,
|
|
@@ -173,7 +181,7 @@ class PostgresPipe(QueryPipe,Integration):
|
|
|
173
181
|
params = record.get(self.params_field) # single-exec params
|
|
174
182
|
batch = record.get("batch_params", None) # list[tuple|dict] for batching
|
|
175
183
|
|
|
176
|
-
cur = client.conn.cursor()
|
|
184
|
+
cur = self.client.conn.cursor()
|
|
177
185
|
try:
|
|
178
186
|
did_executemany = False
|
|
179
187
|
|
|
@@ -215,4 +223,5 @@ class PostgresPipe(QueryPipe,Integration):
|
|
|
215
223
|
finally:
|
|
216
224
|
cur.close()
|
|
217
225
|
finally:
|
|
218
|
-
|
|
226
|
+
pass
|
|
227
|
+
# client.close()
|
|
@@ -10,12 +10,12 @@ class SelectFields(DeepCopyPipe):
|
|
|
10
10
|
@classmethod
|
|
11
11
|
def usage(cls):
|
|
12
12
|
usage = Usage(
|
|
13
|
-
name='
|
|
13
|
+
name='select',
|
|
14
14
|
desc='Select specific fields from each record.',
|
|
15
15
|
component_class=cls
|
|
16
16
|
)
|
|
17
17
|
usage.def_arg(name='fields', usage='Comma-separated list of fields to retain')
|
|
18
|
-
usage.def_example(expr_tokens=["{id:1, dir:'up', color:'blue'}", '
|
|
18
|
+
usage.def_example(expr_tokens=["{id:1, dir:'up', color:'blue'}", 'select:id,color'], expect="id: 1, color:'blue'")
|
|
19
19
|
return usage
|
|
20
20
|
|
|
21
21
|
def __init__(self, ptok: ParsedToken, usage: Usage):
|
|
@@ -20,10 +20,6 @@ from typing import Any, Dict, Iterable, List, Optional, Sequence
|
|
|
20
20
|
from datetime import date, datetime
|
|
21
21
|
from collections import defaultdict
|
|
22
22
|
|
|
23
|
-
import numpy as np
|
|
24
|
-
import pandas as pd
|
|
25
|
-
|
|
26
|
-
|
|
27
23
|
# ----------------------------- Public Params -----------------------------
|
|
28
24
|
@dataclass
|
|
29
25
|
class GraphParams:
|
|
@@ -48,6 +44,8 @@ class TimeDetector:
|
|
|
48
44
|
|
|
49
45
|
@staticmethod
|
|
50
46
|
def is_time(xs: pd.Series) -> bool:
|
|
47
|
+
import numpy as np # lazy
|
|
48
|
+
import pandas as pd # lazy
|
|
51
49
|
# Already datetime dtype?
|
|
52
50
|
if pd.api.types.is_datetime64_any_dtype(xs):
|
|
53
51
|
return True
|
|
@@ -74,6 +72,7 @@ class TimeDetector:
|
|
|
74
72
|
|
|
75
73
|
@staticmethod
|
|
76
74
|
def parse_times(series: pd.Series) -> pd.Series:
|
|
75
|
+
import pandas as pd # lazy
|
|
77
76
|
numeric = pd.to_numeric(series, errors="coerce")
|
|
78
77
|
parsed = None
|
|
79
78
|
if numeric.notna().mean() >= 0.9:
|
|
@@ -92,6 +91,7 @@ class MultiYAdapter:
|
|
|
92
91
|
"""Builds wide dataframe: columns = ['x'] + y_fields; sums duplicates of x."""
|
|
93
92
|
@staticmethod
|
|
94
93
|
def to_df(records: Iterable[Dict[str, Any]], x_field: str, y_fields: Sequence[str]) -> pd.DataFrame:
|
|
94
|
+
import pandas as pd # lazy
|
|
95
95
|
rows: List[Dict[str, Any]] = []
|
|
96
96
|
for r in records:
|
|
97
97
|
if x_field not in r:
|
|
@@ -137,12 +137,14 @@ class SingleYWithSetsAdapter:
|
|
|
137
137
|
# ----------------------------- Plotter -----------------------------
|
|
138
138
|
class GraphPlotter:
|
|
139
139
|
def __init__(self, params: GraphParams):
|
|
140
|
+
import numpy as np
|
|
140
141
|
self.pms = params
|
|
141
142
|
self.y_fields = list(dict.fromkeys(self.pms.y_fields)) # dedupe, preserve order
|
|
142
143
|
|
|
143
144
|
def plot(self, chart_type: str = "line"):
|
|
144
|
-
import matplotlib.pyplot as plt
|
|
145
|
-
import matplotlib.dates as mdates
|
|
145
|
+
import matplotlib.pyplot as plt # lazy
|
|
146
|
+
import matplotlib.dates as mdates # lazy
|
|
147
|
+
import pandas as pd # lazy
|
|
146
148
|
|
|
147
149
|
fig = plt.figure()
|
|
148
150
|
ax = plt.gca()
|
|
@@ -258,7 +260,7 @@ class GraphPlotter:
|
|
|
258
260
|
# ---------- Formatting helpers ----------
|
|
259
261
|
@staticmethod
|
|
260
262
|
def _format_time_axis(ax, df: pd.DataFrame) -> None:
|
|
261
|
-
import matplotlib.dates as mdates
|
|
263
|
+
import matplotlib.dates as mdates # lazy
|
|
262
264
|
fig = ax.get_figure()
|
|
263
265
|
ts = df["ts"]
|
|
264
266
|
if ts.empty:
|
|
@@ -322,7 +324,7 @@ class GraphPlotter:
|
|
|
322
324
|
|
|
323
325
|
# ---------- Misc ----------
|
|
324
326
|
def _apply_args_dict(self) -> None:
|
|
325
|
-
import matplotlib.pyplot as plt
|
|
327
|
+
import matplotlib.pyplot as plt # lazy
|
|
326
328
|
for name, val in getattr(self.pms, "args_dict", {}).items():
|
|
327
329
|
fn = getattr(plt, name, None)
|
|
328
330
|
if callable(fn):
|
|
@@ -345,7 +347,7 @@ def graph_bar_line(obj, type):
|
|
|
345
347
|
Returns (fig, ax) for optional downstream tweaks (safe to ignore).
|
|
346
348
|
"""
|
|
347
349
|
# Lazy import (ensures MPL backend)
|
|
348
|
-
import matplotlib.pyplot as plt # noqa: F401
|
|
350
|
+
import matplotlib.pyplot as plt # noqa: F401 # lazy
|
|
349
351
|
|
|
350
352
|
# Normalize y_fields from string or list
|
|
351
353
|
raw_y = obj.y_field if isinstance(obj.y_field, str) else str(obj.y_field)
|
|
@@ -4,18 +4,15 @@
|
|
|
4
4
|
import json
|
|
5
5
|
from typing import Iterator, Dict, Any
|
|
6
6
|
|
|
7
|
-
import numpy as np
|
|
8
|
-
from pjk.usage import NoBindUsage
|
|
9
|
-
from pjk.components import Source
|
|
10
7
|
from pjk.sources.lazy_file import LazyFile
|
|
11
8
|
from pjk.sources.format_source import FormatSource
|
|
12
9
|
from pjk.log import logger
|
|
13
10
|
|
|
14
|
-
|
|
15
11
|
class NpySource(FormatSource):
|
|
16
12
|
extension = 'npy'
|
|
17
13
|
|
|
18
14
|
def __init__(self, lazy_file: LazyFile):
|
|
15
|
+
super().__init__(root=None)
|
|
19
16
|
self.lazy_file = lazy_file
|
|
20
17
|
self.num_vecs = 0
|
|
21
18
|
|
|
@@ -32,9 +29,11 @@ class NpySource(FormatSource):
|
|
|
32
29
|
|
|
33
30
|
try:
|
|
34
31
|
# Use mmap to avoid loading entire array in RAM at once.
|
|
32
|
+
import numpy as np #lazy import
|
|
35
33
|
arr = np.load(path, mmap_mode="r", allow_pickle=False)
|
|
36
34
|
except Exception as e:
|
|
37
35
|
logger.error(f"Failed to load .npy file at {path}: {e}")
|
|
36
|
+
raise Exception(f"Failed to load .npy file at {path}: {e}")
|
|
38
37
|
return
|
|
39
38
|
|
|
40
39
|
if arr.size == 0:
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_jack_knife-0.7.0 → python_jack_knife-0.7.1}/src/pjk/integrations/opensearch_client.py
RENAMED
|
File without changes
|
{python_jack_knife-0.7.0 → python_jack_knife-0.7.1}/src/pjk/integrations/opensearch_index_sink.py
RENAMED
|
File without changes
|
{python_jack_knife-0.7.0 → python_jack_knife-0.7.1}/src/pjk/integrations/opensearch_query_pipe.py
RENAMED
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
File without changes
|
{python_jack_knife-0.7.0 → python_jack_knife-0.7.1}/src/python_jack_knife.egg-info/SOURCES.txt
RENAMED
|
File without changes
|
|
File without changes
|
{python_jack_knife-0.7.0 → python_jack_knife-0.7.1}/src/python_jack_knife.egg-info/entry_points.txt
RENAMED
|
File without changes
|
{python_jack_knife-0.7.0 → python_jack_knife-0.7.1}/src/python_jack_knife.egg-info/requires.txt
RENAMED
|
File without changes
|
{python_jack_knife-0.7.0 → python_jack_knife-0.7.1}/src/python_jack_knife.egg-info/top_level.txt
RENAMED
|
File without changes
|