Skip to main content

pjy - command-line JSON processor

Project description

pjy is a command-line tool to process JSON data and execute queries on it. It is a bit like jq but with a Python syntax for queries.

Usage

pjy [EXPR] [FILES]

pjy will read JSON data from FILES and print the evaluation result of the Python expression EXPR.

If FILES is missing or is “-”, pjy will use stdin.

The simplest expression to use, which outputs the input unchanged is “d” (for data).

It’s possible to use multiple input files.

Examples

In pjy, expressions are also called “filters”, as in jq.

Just pretty-print

d (short for “data”) is the most basic filter, it represents the whole input:

pjy 'd'
    {"foo":"bar","baz":[1,2,3]}

Prints:

{
  "foo": "bar",
  "baz": [
    1,
    2,
    3
  ]
}

Select a dict key

The filters are Python expressions, hence we can select a dict key:

pjy 'd["baz"]'
    {"foo":"bar","baz":[1,2,3]}

Alternatively, in pjy, dicts keys are also attributes:

pjy 'd.baz'
    {"foo":"bar","baz":[1,2,3]}

Both filters will print:

[
  1,
  2,
  3
]

In case a key has a reserved name, like import (keyword) or keys (dict method), simply use the bracket form.

Do a basic operation

It’s possible to use everything that a Python expression can contain:

pjy '[i + 1 for i in d["baz"]]'
    {"foo":"bar","baz":[1,2,3]}

Prints:

[
  2,
  3,
  4
]

Lambda-placeholder

A special identifier, _ can be used to create lambdas. This identifier will absorb most operations done to it and return a lambda applying them. Then, the returned lambda can be applied:

pjy 'map(_ + 1, d.baz)'
    {"foo":"bar","baz":[1,2,3]}

Is equivalent to:

pjy 'map((lambda x: x + 1), d.baz)'
    {"foo":"bar","baz":[1,2,3]}

Which will print:

[
  2,
  3,
  4
]

The lambda-placeholder will absorb chained operations:

pjy 'map((_ + 1) * 2, d.baz)'
    {"foo":"bar","baz":[1,2,3]}

Will result in:

[
  4,
  6,
  8
]

And:

pjy 'map(_[1:3] * 2, d)'
    {"foo":"bar","baz":[1,2,3]}

Will return:

{
  "foo": "arar",
  "baz": [
    2,
    3,
    2,
    3
  ]
}

Pipe-like iteration

The pipe (|) can be used to iterate on a list, it accepts a function as right operand:

pjy 'd.baz | _ + 1'
    {"foo":"bar","baz":[1,2,3]}

Which prints:

[
  2,
  3,
  4
]

It also operates on a dict’s values, and returns a dict:

pjy 'd | (lambda x: repr(x))'
    {"foo":"bar","baz":[1,2,3]}

The values are replaced by the right operand value, the keys are unchanged:

{
  "foo": "'bar'",
  "baz": "[1, 2, 3]"
}

Partial placeholder

It’s not possible to call a function on a placeholder, for example, len(_) will not work. However, it’s possible to use the partial helper to prepare the function call:

pjy 'd | partial(len, _)'
    {"foo":"bar","baz":[1,2,3]}

Prints:

{
  "foo": 3,
  "baz": 3
}

partial ressembles the functools.partial function: it returns a function wrapping the function passed as first argument. The returned function will call the original function with the fixed arguments passed. The difference is that lambda-placeholders can be passed, and they will be replaced by the wrapper’s argument.

p is a short alias for the partial function which can be used in pjy expressions.

Imports

It’s possible to import modules with the imp function:

pjy 'filter(p(imp("fnmatch").fnmatch, _, "f*"), d.keys())'
     {"foo":"bar","baz":[1,2,3]}

Will print:

[
  "foo"
]

The math and re modules are already imported and available directly without having to call imp.

Multiple inputs

In pjy, an inputs variable exists, which is a list containing the JSON data of each input file passed on the command line. The d variable is simply an alias to inputs[0].

For example:

pjy 'filter(_[0] != _[1], zip(inputs[0], inputs[1]))' before.json after.json

will read 2 files before.json and after.json, which consist in a list of objects, and pjy will compare each zipped-pair of objects together. Then it will print the list of differing pairs.

Security

pjy by itself does not write files (except stdout/stderr) or sockets, or run external commands. However, pjy runs the given expressions passed as argument, in the Python interpreter, without a sandbox. Hence, do NOT pass dangerous or untrusted Python expressions to pjy.

Dependencies

pjy is written in Python 3. Its setup.py requires setuptools.

If pygments is installed, pjy’s output will be colorized, but it’s entirely optional.

Version and license

pjy is at version 0.10.0, it uses semantic versioning. It is licensed under the WTFPLv2, see COPYING.WTFPL for license text.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pjy-0.10.0.tar.gz (5.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pjy-0.10.0-py3-none-any.whl (10.6 kB view details)

Uploaded Python 3

File details

Details for the file pjy-0.10.0.tar.gz.

File metadata

  • Download URL: pjy-0.10.0.tar.gz
  • Upload date:
  • Size: 5.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No

File hashes

Hashes for pjy-0.10.0.tar.gz
Algorithm Hash digest
SHA256 9fc78ef8c9f2e20f650c2abc60f94e0303e9b4746f80f8d224ae1a9ed36e1a04
MD5 ea16b5c7c8465eae3dede20e08fc4edc
BLAKE2b-256 da222825523c378be1b5dfb1367010afa7627cc99f5b1b6284e36af79f3e77d7

See more details on using hashes here.

File details

Details for the file pjy-0.10.0-py3-none-any.whl.

File metadata

  • Download URL: pjy-0.10.0-py3-none-any.whl
  • Upload date:
  • Size: 10.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No

File hashes

Hashes for pjy-0.10.0-py3-none-any.whl
Algorithm Hash digest
SHA256 b47c086c2b289da70a1f77b0a7fd657673f7612a1adf00f0b27177576fd8c16b
MD5 826e4ae01fa500653f242e16bbc762a9
BLAKE2b-256 035a9af38abaad187ac4e37d4f83e9d73a0ae78b71a047b5ea6b1d04fd14fdc9

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page