Skip to content

Commit b43c9b2

Browse files
Merge pull request #72 from kellyjonbrazil/dev
Dev v1.6.1
2 parents 641bdfc + bba5e9e commit b43c9b2

10 files changed

Lines changed: 111 additions & 16 deletions

File tree

.github/workflows/pythonapp.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,12 @@ jobs:
1414
strategy:
1515
matrix:
1616
os: [macos-latest, ubuntu-latest, windows-latest]
17-
python-version: ["3.7", "3.8", "3.9", "3.10"]
17+
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13"]
1818

1919
steps:
20-
- uses: actions/checkout@v2
20+
- uses: actions/checkout@v3
2121
- name: Set up Python ${{ matrix.python-version }}
22-
uses: actions/setup-python@v1
22+
uses: actions/setup-python@v4
2323
with:
2424
python-version: ${{ matrix.python-version }}
2525
- name: Install dependencies

ADVANCED_USAGE.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,11 @@ To set `jello` options in the `.jelloconf.py` file, import the `jello.lib.opts`
1414
from jello.lib import opts
1515
opts.mono = True # -m option
1616
opts.compact = True # -c option
17+
opts.empty = True # -e option
1718
opts.lines = True # -l option
1819
opts.raw = True # -r option
20+
opts.raw_input = True # -R option
21+
opts.force_color = True # -C option
1922
opts.nulls = True # -n option
2023
opts.schema = True # -s option
2124
opts.types = True # -t option

CHANGELOG

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
jello changelog
22

3+
20250529 v1.6.1
4+
- Add the `-R` option to ingest the data as a raw string instead of converting to a dict/list
5+
- Add more information to query errors
6+
- Add the ability to add more information to the query scope
7+
- Add Python runtime information to `-v` option
8+
39
20230423 v1.6.0
410
- Add the ability to directly use a JSON file or JSON Lines files as data input (`-f`)
511
- Add the ability to load a query from a file (`-q`)

README.md

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
[![Tests](https://github.com/kellyjonbrazil/jello/workflows/Tests/badge.svg?branch=master)](https://github.com/kellyjonbrazil/jello/actions)
21
[![Pypi](https://img.shields.io/pypi/v/jello.svg)](https://pypi.org/project/jello/)
32

43
>Built on `jello`:
@@ -74,6 +73,7 @@ jello '_["foo"]' -f data.json
7473
- `-n` print selected `null` values
7574
- `-q` load query from a file
7675
- `-r` raw output of selected strings (no quotes)
76+
- `-R` raw string input (don't auto convert input to dict/list)
7777
- `-s` print the JSON schema in grep-able format
7878
- `-t` print type annotations in schema view
7979
- `-h` help
@@ -152,6 +152,30 @@ while read -r value; do
152152
done < <(cat data.json | jello -rl _.foo)
153153
```
154154

155+
### Non-JSON Data Input (YAML, CSV, etc.)
156+
You can work with other types of data with the `-R` (raw string input) option. For example,
157+
if you would like to read in YAML data you can load the data as a raw string, import
158+
the `yaml` library, and load the string data into `_` with the `yaml` library:
159+
160+
```bash
161+
$ cat values.yaml
162+
163+
var1: value1
164+
var2: value2
165+
var3: value3
166+
167+
$ jello -Rr '
168+
import yaml
169+
_ = yaml.safe_load(_)
170+
_["var2"]
171+
' -f values.yaml
172+
173+
value2
174+
```
175+
176+
> Note: Dot notation is not supported with the `-R` option unless the library used to
177+
> convert the raw string supports this. (e.g. `python-benedict`)
178+
155179
### Setting Custom Colors via Environment Variable
156180
Custom colors can be set via the `JELLO_COLORS` environment variable. Any colors set in the environment variable will take precedence over any colors set in the initialization file. (see [Advanced Usage](https://github.com/kellyjonbrazil/jello/blob/master/ADVANCED_USAGE.md))
157181

jello/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
"""jello - query JSON at the command line with python syntax"""
22

33

4-
__version__ = '1.6.0'
4+
__version__ = '1.6.1'
55
AUTHOR = 'Kelly Brazil'
66
WEBSITE = 'https://github.com/kellyjonbrazil/jello'
7-
COPYRIGHT = '© 2020-2023 Kelly Brazil'
7+
COPYRIGHT = '© 2020-2025 Kelly Brazil'
88
LICENSE = 'MIT License'

jello/cli.py

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import signal
66
import shutil
77
import textwrap
8+
import traceback
89
from textwrap import TextWrapper
910
import jello
1011
from jello.lib import opts, load_json, read_file, pyquery, Schema, Json
@@ -41,6 +42,7 @@ def print_help():
4142
-n print selected null values
4243
-q load query from a file
4344
-r raw string output (no quotes)
45+
-R raw string input (don't auto convert input to dict/list)
4446
-s print the JSON schema in grep-able format
4547
-t print type annotations in schema view
4648
-v version info
@@ -71,6 +73,16 @@ def print_exception(e=None, data='', query='', response='', ex_type='Runtime'):
7173
if split_length < 10:
7274
split_length = 10
7375

76+
# prepare short info where the error occurred
77+
stacktrace = traceback.extract_tb(e.__traceback__)
78+
stacklines = []
79+
if len(stacktrace):
80+
if stacktrace[-1].filename == "<string>":
81+
# we get <string> as filename when exception occurs in a exec() call
82+
stacklines.append(f"Jello query, line {stacktrace[-1].lineno}")
83+
# lineno begins with 1, lists with 0 -> subtract 1
84+
stacklines.append(" " + query.split('\n')[stacktrace[-1].lineno-1])
85+
7486
wrapper = TextWrapper(width=term_width,
7587
initial_indent='',
7688
subsequent_indent=' ' * 12)
@@ -79,6 +91,13 @@ def print_exception(e=None, data='', query='', response='', ex_type='Runtime'):
7991
wrapper = TextWrapper(width=term_width,
8092
initial_indent=' ' * 8,
8193
subsequent_indent=' ' * 12)
94+
95+
# add pre-formatted stacktrace text: flatten the info into lines, normalize newlines
96+
for errstring in stacklines:
97+
for errline in errstring.split('\n'):
98+
if len(errline.replace('\n', '')):
99+
exception_message += wrapper.fill(errline.replace('\n', '')) + '\n'
100+
82101
exception_message += wrapper.fill(f'{e}') + '\n'
83102

84103
e_text = ''
@@ -173,6 +192,7 @@ def main(data=None, query='_'):
173192
opts.mono = opts.mono or ('m' in options or bool(os.getenv('NO_COLOR')))
174193
opts.nulls = opts.nulls or 'n' in options
175194
opts.raw = opts.raw or 'r' in options
195+
opts.raw_input = opts.raw_input or 'R' in options
176196
opts.schema = opts.schema or 's' in options
177197
opts.types = opts.types or 't' in options
178198
opts.version_info = opts.version_info or 'v' in options
@@ -182,8 +202,11 @@ def main(data=None, query='_'):
182202
print_help()
183203

184204
if opts.version_info:
205+
py_ver: str = '.'.join((str(sys.version_info.major), str(sys.version_info.minor), str(sys.version_info.micro)))
185206
print(textwrap.dedent(f'''\
186207
jello: Version: {jello.__version__}
208+
Python Version: {py_ver}
209+
Python Path: {sys.executable}
187210
Author: {jello.AUTHOR}
188211
Website: {jello.WEBSITE}
189212
Copyright: {jello.COPYRIGHT}
@@ -197,11 +220,16 @@ def main(data=None, query='_'):
197220
if opts.empty:
198221
data = '{}'
199222

200-
# load the JSON or JSON Lines into a dict or list of dicts
201-
try:
202-
data = load_json(data)
203-
except Exception as e:
204-
print_exception(e, ex_type='JSON Load')
223+
# load the data as a raw string or JSON
224+
if opts.raw_input:
225+
data = str(data).rstrip('\r\n')
226+
227+
else:
228+
# load the JSON or JSON Lines into a dict or list of dicts
229+
try:
230+
data = load_json(data)
231+
except Exception as e:
232+
print_exception(e, ex_type='JSON Load')
205233

206234
# Read .jelloconf.py (if it exists) and run the query
207235
response = ''

jello/lib.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ class opts:
4747
empty = None
4848
nulls = None
4949
raw = None
50+
raw_input = None
5051
lines = None
5152
force_color = None
5253
mono = None
@@ -396,7 +397,7 @@ def read_file(file_path):
396397
with open(file_path, 'r') as f:
397398
return f.read()
398399

399-
def pyquery(data, query):
400+
def pyquery(data, query, add_to_scope=None):
400401
"""Sets options and runs the user's query."""
401402
output = None
402403

@@ -475,6 +476,8 @@ def pyquery(data, query):
475476
# add any functions in initialization file to the scope
476477
scope = {'_': _, 'os': os}
477478
scope.update(jcnf_dict)
479+
if add_to_scope is not None:
480+
scope.update(add_to_scope)
478481

479482
# run the query
480483
block = ast.parse(query, mode='exec')

man/jello.1

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
.TH jello 1 2022-06-26 1.6.0 "Jello JSON Filter"
1+
.TH jello 1 2025-05-29 1.6.1 "Jello JSON Filter"
22
.SH NAME
33
Jello \- Filter JSON and JSON Lines data with Python syntax
44
.SH SYNOPSIS
@@ -88,6 +88,8 @@ $ jello _.foo -f data.json
8888
.IP
8989
\fB-r\fP raw output of selected strings (no quotes)
9090
.IP
91+
\fB-R\fP raw string input (don't auto convert input to dict/list)
92+
.IP
9193
\fB-s\fP print the JSON schema in grep-able format
9294
.IP
9395
\fB-t\fP print type annotations in schema view
@@ -364,6 +366,33 @@ glom(_, (\[dq]parsers\[dq], [\[dq]name\[dq]]))\[aq]
364366
...
365367
]
366368

369+
.fi
370+
.SS Non-JSON Data Input (YAML, CSV, etc.)
371+
.PP
372+
You can work with other types of data with the \fB-R\fP (raw string input) option. For example,
373+
if you would like to read in YAML data you can load the data as a raw string, import
374+
the \fByaml\fP library, and load the string data into \fB_\fP with the \fByaml\fP library:
375+
.IP
376+
.nf
377+
378+
$ cat values.yaml
379+
var1: value1
380+
var2: value2
381+
var3: value3
382+
383+
$ jello -Rr \[aq]
384+
import yaml
385+
_ = yaml.safe_load(_)
386+
_[\[dq]var2\[dq]]
387+
\[aq] -f values.yaml
388+
389+
value2
390+
391+
.PP
392+
Note: Dot notation is not supported with the \fB-R\fP option unless the library used to
393+
convert the raw string supports this. (e.g. \fBpython-benedict\fP)
394+
.IP
395+
367396
.fi
368397

369398
.SH ADVANCED USAGE
@@ -384,8 +413,10 @@ To set jello options in the \fB.jelloconf.py\fP file, import the \fBjello.lib.op
384413
from jello.lib import opts
385414
opts.mono = True # -m option
386415
opts.compact = True # -c option
416+
opts.empty = True # -e option
387417
opts.lines = True # -l option
388418
opts.raw = True # -r option
419+
opts.raw_input = True # -R option
389420
opts.force_color = True # -C option
390421
opts.nulls = True # -n option
391422
opts.schema = True # -s option
@@ -521,6 +552,6 @@ Kelly Brazil (kellyjonbrazil@gmail.com)
521552
https://github.com/kellyjonbrazil/jello
522553

523554
.SH COPYRIGHT
524-
Copyright (c) 2020-2023 Kelly Brazil
555+
Copyright (c) 2020-2025 Kelly Brazil
525556

526557
License: MIT License

setup.cfg

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
[metadata]
2-
license_file = LICENSE
2+
license_files = LICENSE

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
setuptools.setup(
77
name='jello',
8-
version='1.6.0',
8+
version='1.6.1',
99
author='Kelly Brazil',
1010
author_email='kellyjonbrazil@gmail.com',
1111
description='Filter JSON and JSON Lines data with Python syntax.',

0 commit comments

Comments
 (0)