signalk-cli 2.1.0__tar.gz → 2.2.0__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.
- {signalk_cli-2.1.0 → signalk_cli-2.2.0}/PKG-INFO +12 -2
- {signalk_cli-2.1.0 → signalk_cli-2.2.0}/README.md +11 -1
- {signalk_cli-2.1.0 → signalk_cli-2.2.0}/pyproject.toml +1 -1
- {signalk_cli-2.1.0 → signalk_cli-2.2.0}/pyproject.toml.orig +1 -1
- {signalk_cli-2.1.0 → signalk_cli-2.2.0}/src/signalk_cli/stream/cli.py +42 -7
- {signalk_cli-2.1.0 → signalk_cli-2.2.0}/src/signalk_cli/stream/output.py +79 -6
- {signalk_cli-2.1.0 → signalk_cli-2.2.0}/src/signalk_cli/__init__.py +0 -0
- {signalk_cli-2.1.0 → signalk_cli-2.2.0}/src/signalk_cli/__main__.py +0 -0
- {signalk_cli-2.1.0 → signalk_cli-2.2.0}/src/signalk_cli/history/__init__.py +0 -0
- {signalk_cli-2.1.0 → signalk_cli-2.2.0}/src/signalk_cli/history/__main__.py +0 -0
- {signalk_cli-2.1.0 → signalk_cli-2.2.0}/src/signalk_cli/history/cli.py +0 -0
- {signalk_cli-2.1.0 → signalk_cli-2.2.0}/src/signalk_cli/history/history_api.py +0 -0
- {signalk_cli-2.1.0 → signalk_cli-2.2.0}/src/signalk_cli/history/output.py +0 -0
- {signalk_cli-2.1.0 → signalk_cli-2.2.0}/src/signalk_cli/net.py +0 -0
- {signalk_cli-2.1.0 → signalk_cli-2.2.0}/src/signalk_cli/stream/__init__.py +0 -0
- {signalk_cli-2.1.0 → signalk_cli-2.2.0}/src/signalk_cli/stream/__main__.py +0 -0
- {signalk_cli-2.1.0 → signalk_cli-2.2.0}/src/signalk_cli/stream/stream_api.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: signalk-cli
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.2.0
|
|
4
4
|
Summary: Query SignalK v2 APIs and export data as CSV, JSON or Apache Arrow Feather
|
|
5
5
|
Keywords: signalk,sailing,marine,nmea,boating
|
|
6
6
|
Author: jey burrows
|
|
@@ -486,9 +486,10 @@ interchangeable:
|
|
|
486
486
|
| `--policy [instant\|ideal\|fixed]` | `ideal` | Per-path subscribe `policy` field; see above |
|
|
487
487
|
| `--period SECONDS` | `60` | Per-path subscribe `period` field, in seconds (converted to ms) |
|
|
488
488
|
| `--min-period SECONDS` | — | Per-path subscribe `minPeriod` field, in seconds (converted to ms); only meaningful with `--policy instant` |
|
|
489
|
-
| `--format [csv\|json\|raw\|feather]` | from extension, else csv | Output format. `json` is JSON Lines (one row object per line, suitable for a live stream). `raw` is the exact delta message text, one per line. `feather` requires `pip install 'signalk-cli[feather]'` and `--output` (cannot stream to stdout). |
|
|
489
|
+
| `--format [csv\|json\|raw\|values\|feather]` | from extension, else csv | Output format. `json` is JSON Lines (one row object per line, suitable for a live stream). `raw` is the exact delta message text, one per line. `values` is the bare value only, one per line — no other columns. `feather` requires `pip install 'signalk-cli[feather]'` and `--output` (cannot stream to stdout). |
|
|
490
490
|
| `--no-header` | — | Suppress the CSV header row |
|
|
491
491
|
| `--include-meta` | — | Also emit rows for `meta` entries (units, description, zones, etc.), not just `values`. Adds a `kind` column (`value`/`meta`) to csv/json/feather output. Ignored for `--format raw`, which always includes meta as-is. |
|
|
492
|
+
| `--source PATTERN` | — | Only include updates whose `$source` matches `PATTERN`. Repeatable, OR'd together. Substring match unless `PATTERN` contains a glob metacharacter (`*`/`?`/`[`), e.g. `--source Teltonika` or `--source '*.GP'`. Client-side, applied after receipt: `csv`/`json`/`values`/`feather` filter per-update; `raw` (whole message, verbatim) passes a message through if *any* of its updates match. |
|
|
492
493
|
| `-o, --output [FILE]` | stdout | Write to a file. Omit the filename (`--output` alone) to auto-name as `signalk-stream-<server>-<timestamp>.<ext>`. Required for `--format feather`. |
|
|
493
494
|
| `-f, --follow` | — | Keep streaming until interrupted (Ctrl-C) or `--count` is reached. Without this, print the next message then exit. |
|
|
494
495
|
| `-n, --count N` | 1 without `--follow`, unlimited with it | Number of delta messages to output |
|
|
@@ -500,6 +501,8 @@ interchangeable:
|
|
|
500
501
|
|
|
501
502
|
**raw**: the exact delta message JSON as received from the server, one message per line.
|
|
502
503
|
|
|
504
|
+
**values**: just the `value` column, one per line — no timestamp/context/source/path/kind. Best for piping a single path's readings straight into another tool or script. With `--include-meta`, meta values are interleaved in too, indistinguishable from data values (there's no `kind` column to tell them apart) — generally only useful combined with `--source`/PATH filtering down to one thing.
|
|
505
|
+
|
|
503
506
|
**feather**: Apache Arrow Feather binary format, same columns as csv/json. Requires `pip install 'signalk-cli[feather]'`. Unlike the other formats, rows are buffered in memory across all received messages and written once the session ends (`--count` reached, or Ctrl-C with `--follow`) — cannot be streamed to stdout.
|
|
504
507
|
|
|
505
508
|
#### Examples
|
|
@@ -536,6 +539,13 @@ python -m signalk_cli.stream deltas --host 10.36.10.21 --count 500 --format feat
|
|
|
536
539
|
|
|
537
540
|
# Capture until Ctrl-C to a named Feather file
|
|
538
541
|
python -m signalk_cli.stream deltas --host 10.36.10.21 --follow -o capture.feather 'navigation.*'
|
|
542
|
+
|
|
543
|
+
# Only updates from one sensor (substring match on $source)
|
|
544
|
+
python -m signalk_cli.stream deltas --host 10.36.10.21 --follow --source Teltonika 'navigation.*'
|
|
545
|
+
|
|
546
|
+
# Bare speed values from one sensor, piped straight into another tool
|
|
547
|
+
python -m signalk_cli.stream deltas --host 10.36.10.21 --follow --format values \
|
|
548
|
+
--source Teltonika --bare navigation.speedOverGround
|
|
539
549
|
```
|
|
540
550
|
|
|
541
551
|
---
|
|
@@ -458,9 +458,10 @@ interchangeable:
|
|
|
458
458
|
| `--policy [instant\|ideal\|fixed]` | `ideal` | Per-path subscribe `policy` field; see above |
|
|
459
459
|
| `--period SECONDS` | `60` | Per-path subscribe `period` field, in seconds (converted to ms) |
|
|
460
460
|
| `--min-period SECONDS` | — | Per-path subscribe `minPeriod` field, in seconds (converted to ms); only meaningful with `--policy instant` |
|
|
461
|
-
| `--format [csv\|json\|raw\|feather]` | from extension, else csv | Output format. `json` is JSON Lines (one row object per line, suitable for a live stream). `raw` is the exact delta message text, one per line. `feather` requires `pip install 'signalk-cli[feather]'` and `--output` (cannot stream to stdout). |
|
|
461
|
+
| `--format [csv\|json\|raw\|values\|feather]` | from extension, else csv | Output format. `json` is JSON Lines (one row object per line, suitable for a live stream). `raw` is the exact delta message text, one per line. `values` is the bare value only, one per line — no other columns. `feather` requires `pip install 'signalk-cli[feather]'` and `--output` (cannot stream to stdout). |
|
|
462
462
|
| `--no-header` | — | Suppress the CSV header row |
|
|
463
463
|
| `--include-meta` | — | Also emit rows for `meta` entries (units, description, zones, etc.), not just `values`. Adds a `kind` column (`value`/`meta`) to csv/json/feather output. Ignored for `--format raw`, which always includes meta as-is. |
|
|
464
|
+
| `--source PATTERN` | — | Only include updates whose `$source` matches `PATTERN`. Repeatable, OR'd together. Substring match unless `PATTERN` contains a glob metacharacter (`*`/`?`/`[`), e.g. `--source Teltonika` or `--source '*.GP'`. Client-side, applied after receipt: `csv`/`json`/`values`/`feather` filter per-update; `raw` (whole message, verbatim) passes a message through if *any* of its updates match. |
|
|
464
465
|
| `-o, --output [FILE]` | stdout | Write to a file. Omit the filename (`--output` alone) to auto-name as `signalk-stream-<server>-<timestamp>.<ext>`. Required for `--format feather`. |
|
|
465
466
|
| `-f, --follow` | — | Keep streaming until interrupted (Ctrl-C) or `--count` is reached. Without this, print the next message then exit. |
|
|
466
467
|
| `-n, --count N` | 1 without `--follow`, unlimited with it | Number of delta messages to output |
|
|
@@ -472,6 +473,8 @@ interchangeable:
|
|
|
472
473
|
|
|
473
474
|
**raw**: the exact delta message JSON as received from the server, one message per line.
|
|
474
475
|
|
|
476
|
+
**values**: just the `value` column, one per line — no timestamp/context/source/path/kind. Best for piping a single path's readings straight into another tool or script. With `--include-meta`, meta values are interleaved in too, indistinguishable from data values (there's no `kind` column to tell them apart) — generally only useful combined with `--source`/PATH filtering down to one thing.
|
|
477
|
+
|
|
475
478
|
**feather**: Apache Arrow Feather binary format, same columns as csv/json. Requires `pip install 'signalk-cli[feather]'`. Unlike the other formats, rows are buffered in memory across all received messages and written once the session ends (`--count` reached, or Ctrl-C with `--follow`) — cannot be streamed to stdout.
|
|
476
479
|
|
|
477
480
|
#### Examples
|
|
@@ -508,6 +511,13 @@ python -m signalk_cli.stream deltas --host 10.36.10.21 --count 500 --format feat
|
|
|
508
511
|
|
|
509
512
|
# Capture until Ctrl-C to a named Feather file
|
|
510
513
|
python -m signalk_cli.stream deltas --host 10.36.10.21 --follow -o capture.feather 'navigation.*'
|
|
514
|
+
|
|
515
|
+
# Only updates from one sensor (substring match on $source)
|
|
516
|
+
python -m signalk_cli.stream deltas --host 10.36.10.21 --follow --source Teltonika 'navigation.*'
|
|
517
|
+
|
|
518
|
+
# Bare speed values from one sensor, piped straight into another tool
|
|
519
|
+
python -m signalk_cli.stream deltas --host 10.36.10.21 --follow --format values \
|
|
520
|
+
--source Teltonika --bare navigation.speedOverGround
|
|
511
521
|
```
|
|
512
522
|
|
|
513
523
|
---
|
|
@@ -13,11 +13,13 @@ import niquests
|
|
|
13
13
|
from ..net import api_error, bare_option, host_option, resolve_host, stderr_ctx
|
|
14
14
|
from .output import (
|
|
15
15
|
FEATHER_EXTENSIONS,
|
|
16
|
+
delta_matches_source,
|
|
16
17
|
extract_delta_rows,
|
|
17
18
|
write_csv_delta,
|
|
18
19
|
write_csv_header,
|
|
19
20
|
write_feather_rows,
|
|
20
21
|
write_json_delta,
|
|
22
|
+
write_values_delta,
|
|
21
23
|
)
|
|
22
24
|
from .stream_api import (
|
|
23
25
|
SUBSCRIBE_POLICIES,
|
|
@@ -103,10 +105,13 @@ def cli():
|
|
|
103
105
|
"--format",
|
|
104
106
|
"fmt",
|
|
105
107
|
default=None,
|
|
106
|
-
type=click.Choice(
|
|
108
|
+
type=click.Choice(
|
|
109
|
+
["csv", "json", "raw", "feather", "values"], case_sensitive=False
|
|
110
|
+
),
|
|
107
111
|
help="Output format (default: inferred from --output extension, else csv). "
|
|
108
112
|
"json is JSON Lines (one row object per line). raw is the exact delta "
|
|
109
|
-
"message text, one per line.
|
|
113
|
+
"message text, one per line. values is the bare value only, one per "
|
|
114
|
+
"line — no timestamp/context/source/path/kind columns. feather requires "
|
|
110
115
|
"pip install 'signalk-cli[feather]' and --output (cannot stream to stdout).",
|
|
111
116
|
)
|
|
112
117
|
@click.option("--no-header", is_flag=True, help="Suppress header row (CSV only)")
|
|
@@ -117,6 +122,19 @@ def cli():
|
|
|
117
122
|
"not just 'values'. Adds a 'kind' column (value/meta) to csv/json/feather "
|
|
118
123
|
"output. Ignored for --format raw, which always includes meta as-is.",
|
|
119
124
|
)
|
|
125
|
+
@click.option(
|
|
126
|
+
"--source",
|
|
127
|
+
"source",
|
|
128
|
+
multiple=True,
|
|
129
|
+
metavar="PATTERN",
|
|
130
|
+
help="Only include updates whose $source matches PATTERN. Repeatable "
|
|
131
|
+
"(OR'd together). PATTERN is a substring match unless it contains a "
|
|
132
|
+
"glob metacharacter (*/?/[), in which case it's matched as a glob, "
|
|
133
|
+
"e.g. --source Teltonika or --source '*.GP'. Filtering is client-side, "
|
|
134
|
+
"applied after receipt — for --format raw (whole message, verbatim) a "
|
|
135
|
+
"message passes if ANY of its updates match; other formats filter "
|
|
136
|
+
"per-update.",
|
|
137
|
+
)
|
|
120
138
|
@click.option(
|
|
121
139
|
"--output",
|
|
122
140
|
"-o",
|
|
@@ -156,6 +174,7 @@ def deltas(
|
|
|
156
174
|
fmt,
|
|
157
175
|
no_header,
|
|
158
176
|
include_meta,
|
|
177
|
+
source,
|
|
159
178
|
output,
|
|
160
179
|
follow,
|
|
161
180
|
count,
|
|
@@ -164,7 +183,8 @@ def deltas(
|
|
|
164
183
|
"""Stream live delta updates from the SignalK v1 Streaming API.
|
|
165
184
|
|
|
166
185
|
Connects via WebSocket and prints delta messages as they arrive, in
|
|
167
|
-
csv, json (JSON Lines), raw, or Feather
|
|
186
|
+
csv, json (JSON Lines), raw, values (bare value only), or Feather
|
|
187
|
+
format.
|
|
168
188
|
|
|
169
189
|
Always sends an explicit subscribe message for --context, covering
|
|
170
190
|
PATH arguments if given, otherwise every path ('*'). PATH arguments
|
|
@@ -196,6 +216,10 @@ def deltas(
|
|
|
196
216
|
|
|
197
217
|
# Capture 100 messages to a Feather file (requires signalk-cli[feather])
|
|
198
218
|
signalk_cli.stream deltas --host 10.36.10.21 --count 100 -o capture.feather
|
|
219
|
+
|
|
220
|
+
# Bare speed values from one sensor, piped straight into another tool
|
|
221
|
+
signalk_cli.stream deltas --host 10.36.10.21 --follow --format values \\
|
|
222
|
+
--source Teltonika --bare navigation.speedOverGround
|
|
199
223
|
"""
|
|
200
224
|
with stderr_ctx(bare):
|
|
201
225
|
host = resolve_host(host, no_cache)
|
|
@@ -224,6 +248,8 @@ def deltas(
|
|
|
224
248
|
if fmt == "feather"
|
|
225
249
|
else ".json"
|
|
226
250
|
if fmt in ("json", "raw")
|
|
251
|
+
else ".txt"
|
|
252
|
+
if fmt == "values"
|
|
227
253
|
else ".csv"
|
|
228
254
|
)
|
|
229
255
|
output = f"signalk-stream-{server_name}-{ts}{ext}"
|
|
@@ -280,20 +306,29 @@ def deltas(
|
|
|
280
306
|
message_count += 1
|
|
281
307
|
if fmt == "feather":
|
|
282
308
|
feather_rows.extend(
|
|
283
|
-
extract_delta_rows(
|
|
309
|
+
extract_delta_rows(
|
|
310
|
+
delta, include_meta=include_meta, sources=source
|
|
311
|
+
)
|
|
284
312
|
)
|
|
285
313
|
row_total = len(feather_rows)
|
|
286
314
|
elif fmt == "raw":
|
|
287
|
-
|
|
315
|
+
if delta_matches_source(delta, source):
|
|
316
|
+
click.echo(raw, file=sink)
|
|
288
317
|
elif fmt == "json":
|
|
289
318
|
row_total += write_json_delta(
|
|
290
|
-
delta, sink, include_meta=include_meta
|
|
319
|
+
delta, sink, include_meta=include_meta, sources=source
|
|
320
|
+
)
|
|
321
|
+
elif fmt == "values":
|
|
322
|
+
row_total += write_values_delta(
|
|
323
|
+
delta, sink, include_meta=include_meta, sources=source
|
|
291
324
|
)
|
|
292
325
|
else:
|
|
293
326
|
if not header_written and not no_header:
|
|
294
327
|
write_csv_header(sink, include_meta=include_meta)
|
|
295
328
|
header_written = True
|
|
296
|
-
row_total += write_csv_delta(
|
|
329
|
+
row_total += write_csv_delta(
|
|
330
|
+
delta, sink, include_meta=include_meta, sources=source
|
|
331
|
+
)
|
|
297
332
|
except KeyboardInterrupt:
|
|
298
333
|
pass
|
|
299
334
|
except niquests.RequestException as e:
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"""Row extraction and CSV/JSON/Feather writers for SignalK delta messages."""
|
|
2
2
|
|
|
3
3
|
import csv
|
|
4
|
+
import fnmatch
|
|
4
5
|
import json
|
|
5
6
|
from typing import IO
|
|
6
7
|
|
|
@@ -15,8 +16,42 @@ def _normalize_value(value: object) -> str:
|
|
|
15
16
|
return str(value)
|
|
16
17
|
|
|
17
18
|
|
|
19
|
+
def _update_source(update: dict) -> str:
|
|
20
|
+
return update.get("$source") or json.dumps(update.get("source", {}))
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def source_matches(source: str, patterns: tuple[str, ...]) -> bool:
|
|
24
|
+
"""Match a `$source` string against `--source` filter patterns (OR'd).
|
|
25
|
+
|
|
26
|
+
No patterns means no filtering (always matches). A pattern containing
|
|
27
|
+
glob metacharacters (`*`/`?`/`[`) is matched as-is via `fnmatch`;
|
|
28
|
+
otherwise it's treated as a substring match, e.g. "Teltonika" matches
|
|
29
|
+
the source "Teltonika.GP".
|
|
30
|
+
"""
|
|
31
|
+
if not patterns:
|
|
32
|
+
return True
|
|
33
|
+
return any(
|
|
34
|
+
fnmatch.fnmatch(source, p if any(c in p for c in "*?[") else f"*{p}*")
|
|
35
|
+
for p in patterns
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def delta_matches_source(delta: dict, patterns: tuple[str, ...]) -> bool:
|
|
40
|
+
"""True if any update in the delta has a `$source` matching `patterns`.
|
|
41
|
+
|
|
42
|
+
Used for `--format raw`, which echoes the whole message verbatim and so
|
|
43
|
+
can only filter at message granularity, not per-update.
|
|
44
|
+
"""
|
|
45
|
+
if not patterns:
|
|
46
|
+
return True
|
|
47
|
+
return any(
|
|
48
|
+
source_matches(_update_source(update), patterns)
|
|
49
|
+
for update in delta.get("updates", [])
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
|
|
18
53
|
def extract_delta_rows(
|
|
19
|
-
delta: dict, *, include_meta: bool = False
|
|
54
|
+
delta: dict, *, include_meta: bool = False, sources: tuple[str, ...] = ()
|
|
20
55
|
) -> list[tuple[str, ...]]:
|
|
21
56
|
"""Flatten a single delta message into rows.
|
|
22
57
|
|
|
@@ -26,12 +61,18 @@ def extract_delta_rows(
|
|
|
26
61
|
update's "meta" entries are included too — per the Streaming API spec,
|
|
27
62
|
"meta" entries have the same path/value shape but "value" is a metadata
|
|
28
63
|
object (units, description, zones, etc.), not a telemetry reading.
|
|
64
|
+
|
|
65
|
+
`sources`, if given, drops entire updates whose `$source` doesn't match
|
|
66
|
+
any pattern (see `source_matches`) — filtering is per-update, since
|
|
67
|
+
that's the granularity at which SignalK attaches a source.
|
|
29
68
|
"""
|
|
30
69
|
context = delta.get("context", "")
|
|
31
70
|
rows: list[tuple[str, ...]] = []
|
|
32
71
|
for update in delta.get("updates", []):
|
|
72
|
+
source = _update_source(update)
|
|
73
|
+
if not source_matches(source, sources):
|
|
74
|
+
continue
|
|
33
75
|
timestamp = update.get("timestamp", "")
|
|
34
|
-
source = update.get("$source") or json.dumps(update.get("source", {}))
|
|
35
76
|
for entry in update.get("values", []):
|
|
36
77
|
path = entry.get("path", "")
|
|
37
78
|
value = _normalize_value(entry.get("value"))
|
|
@@ -60,9 +101,15 @@ def write_csv_header(sink: IO[str], *, include_meta: bool = False) -> None:
|
|
|
60
101
|
sink.flush()
|
|
61
102
|
|
|
62
103
|
|
|
63
|
-
def write_csv_delta(
|
|
104
|
+
def write_csv_delta(
|
|
105
|
+
delta: dict,
|
|
106
|
+
sink: IO[str],
|
|
107
|
+
*,
|
|
108
|
+
include_meta: bool = False,
|
|
109
|
+
sources: tuple[str, ...] = (),
|
|
110
|
+
) -> int:
|
|
64
111
|
"""Write one delta's rows as CSV lines. Returns the number of rows written."""
|
|
65
|
-
rows = extract_delta_rows(delta, include_meta=include_meta)
|
|
112
|
+
rows = extract_delta_rows(delta, include_meta=include_meta, sources=sources)
|
|
66
113
|
writer = csv.writer(sink)
|
|
67
114
|
for row in rows:
|
|
68
115
|
writer.writerow(row)
|
|
@@ -70,9 +117,15 @@ def write_csv_delta(delta: dict, sink: IO[str], *, include_meta: bool = False) -
|
|
|
70
117
|
return len(rows)
|
|
71
118
|
|
|
72
119
|
|
|
73
|
-
def write_json_delta(
|
|
120
|
+
def write_json_delta(
|
|
121
|
+
delta: dict,
|
|
122
|
+
sink: IO[str],
|
|
123
|
+
*,
|
|
124
|
+
include_meta: bool = False,
|
|
125
|
+
sources: tuple[str, ...] = (),
|
|
126
|
+
) -> int:
|
|
74
127
|
"""Write one delta's rows as JSON Lines (one row object per line). Returns row count."""
|
|
75
|
-
rows = extract_delta_rows(delta, include_meta=include_meta)
|
|
128
|
+
rows = extract_delta_rows(delta, include_meta=include_meta, sources=sources)
|
|
76
129
|
columns = _columns(include_meta)
|
|
77
130
|
for row in rows:
|
|
78
131
|
sink.write(json.dumps(dict(zip(columns, row))))
|
|
@@ -81,6 +134,26 @@ def write_json_delta(delta: dict, sink: IO[str], *, include_meta: bool = False)
|
|
|
81
134
|
return len(rows)
|
|
82
135
|
|
|
83
136
|
|
|
137
|
+
def write_values_delta(
|
|
138
|
+
delta: dict,
|
|
139
|
+
sink: IO[str],
|
|
140
|
+
*,
|
|
141
|
+
include_meta: bool = False,
|
|
142
|
+
sources: tuple[str, ...] = (),
|
|
143
|
+
) -> int:
|
|
144
|
+
"""Write one delta's bare values, one per line — no other columns.
|
|
145
|
+
|
|
146
|
+
For `--format values`: useful for piping a single path's readings
|
|
147
|
+
straight into another tool/script. Returns the number of values written.
|
|
148
|
+
"""
|
|
149
|
+
rows = extract_delta_rows(delta, include_meta=include_meta, sources=sources)
|
|
150
|
+
for row in rows:
|
|
151
|
+
sink.write(row[-1])
|
|
152
|
+
sink.write("\n")
|
|
153
|
+
sink.flush()
|
|
154
|
+
return len(rows)
|
|
155
|
+
|
|
156
|
+
|
|
84
157
|
def write_feather_rows(
|
|
85
158
|
rows: list[tuple[str, ...]], output: str, *, include_meta: bool = False
|
|
86
159
|
) -> int:
|
|
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
|