• Stars
    star
    125
  • Rank 276,349 (Top 6 %)
  • Language
    Python
  • License
    MIT License
  • Created over 8 years ago
  • Updated over 5 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A saner way to traverse JSON in Python

JSane

https://travis-ci.org/skorokithakis/jsane.svg?branch=master

JSane is a JSON "parser" that makes attribute accesses easier.

Three-line intro

>>> import jsane
>>> j = jsane.loads('{"foo": {"bar": {"baz": ["well", "hello", "there"]}}}')
>>> j.foo.bar.baz[1].r()
'hello'

Motivation

Picture the scene. You're a jet-setting developer who is obsessed with going to the gym. One day, a world-class jewel thief kidnaps you and asks you to hack into the super-secure bank server in thirty seconds, while an ultramodel is performing oral sex on you. You hurriedly trace the protocol on the wire, only to discover, to your dismay, that it uses JSON. Nested JSON, with levels and levels of keys.

It's hopeless! You'll never type all those brackets and quotation marks in time! Suddenly, a flash of a memory races through your mind, like some cliche from a badly-written README. You launch the shell and type two words:

import jsane

The day is saved.

Motivation (non-Hollywood version)

Are you frustrated with having to traverse your nested JSON key by key?

root = my_json.get("root")
if root is None:
    return None

key1 = root.get("key1")
if key1 is None:
    return None

key2 = key1.get("key2")
if key2 is None:
    return None

<five more times>

Is your code ruined by pesky all-catching except blocks?

try:
    my_json["root"]["key1"]["key2"]["key3"]
except:
    return None

Are you tired of typing all the braces and quotes all the time?

my_json["root"]["key1"[""]][]"]']'"}}""]

Now there's JSane!

Motivation (non-infomercial version)

Okay seriously, this["thing"]["is"]["no"]["fun"]. JSane lets you traverse.json.like.this.r(). That's it.

Usage

Using JSane is simple, at least. It's pretty much a copy of the builtin json module.

First of all, install it with pip or easy_install:

pip install jsane

Here's an example of its usage:

>>> import jsane

>>> j = jsane.loads('{"some": {"json": [1, 2, 3]}}')
>>> j.some.json[2].r()
3
You can also load an existing object::
>>> j = jsane.from_object({"hi": "there"})
>>> j.hi
<Traversable: 'there'>

If the object contains any data types that aren't valid in JSON (like functions), it still should work, but you're on your own.

Due to Python being a sensible language, there's a limit to the amount of crap you can pull with it, so JSane actually returns a Traversable object on accesses:

>>> j = jsane.loads('{"foo": {"bar": {"baz": "yes!"}}}')
>>> type(j.foo)
<class 'jsane.traversable.Traversable'>

If you want your real object back at the end of the wild attribute ride, call .r():

>>> j.foo.bar.r()
{'baz': 'yes!'}

Likewise, if you prefer, you can call the object as a function with no arguments:

>>> j.foo.bar()
{'baz': 'yes!'}

If an attribute, item or index along the way does not exist, you'll get an exception. You can get rid of that by specifying a default:

>>> import jsane

>>> j = jsane.loads('{"some": "json"}')
>>> j.this.path.doesnt.exist.r()
Traceback (most recent call last):
  ...
jsane.traversable.JSaneException: "Key does not exist: 'this'"
>>> j.haha_sucka_this_doesnt_exist_either.r(default="💩")
'💩'

"But how do I access a key called __call__, r, or _obj where you store the wrapped object?!", I hear you ask. Worry not, object keys are still accessible with indexing:

>>> j = jsane.loads('{"r": {"__call__": {"_obj": 5}}}')
>>> j["r"]["__call__"]["_obj"].r()
5

For convenience, you can access values specifically as numbers:

>>> import jsane

>>> j = jsane.loads('''
...     {
...       "numbers": {
...         "one": 1,
...         "two": "2"
...       },
...       "letters": "XYZ"
...     }
... ''')
>>> +j.numbers.one
1
>>> +j.letter, +j.numbers.two  # Things that aren't numbers are nan
(nan, nan)
>>> +j.numbers
nan
>>> +j.what  # Things that don't exist are also nan.
nan

(NaN is not representable in JSON, so this should be enough for most use cases. Testing for NaN is also easy with the standard library math.isnan() function.)

Likewise for strings, calling str() on a Traversable object is a simple shortcut:

>>> str(j.letters)
'XYZ'
>>> str(j.numbers)
"{'one': 1, 'two': '2'}"
>>> str(j.numbers.one)
'1'

In the same fashion, int() and float() are also shortcuts, but unlike str() (and consistent with their behavior elsewhere in Python) they do not infallibly return objects of their respective type (that is, they may raise a ValueError instead).

That's about it. No guarantees of stability before version 1, as always. Semver giveth, and semver taketh away.

Help needed/welcome/etc, mostly with designing the API. Also, if you find this library useless, let me know.

License

BSD. Or MIT. Whatever's in the LICENSE file. I forget. It's permissive, though, so relax.

Self-promotion

It's me, Stavros.

FAQ

  • Do you find it ironic that the README for JSane is insane?

    No.

  • Is this library awesome?

    Yes.

  • All my JSON data uses 'r' and '_obj' as keys!

    Come on, man. :(

More Repositories

1

catt

Cast All The Things allows you to send videos from many, many online sources to your Chromecast.
Python
3,257
star
2

shortuuid

A generator library for concise, unambiguous and URL-safe UUIDs.
Python
1,905
star
3

django-annoying

A django application that tries to eliminate annoying things in the Django framework. ⛺
Python
917
star
4

expounder

A library for explaining things in HTML.
JavaScript
504
star
5

tbvaccine

A small utility to pretty-print Python tracebacks. ⛺
Python
376
star
6

django-loginas

"Log in as user" for the Django admin.
Python
355
star
7

python-yeelight

A Python library for controlling YeeLight WiFi RGB bulbs (mirror of https://gitlab.com/stavros/python-yeelight).
Python
262
star
8

goatfish

A small, schemaless Python ORM that is backed by SQLite. ⛺
Python
233
star
9

netproxy

A Netflix/Hulu/Pandora/etc proxy in a box.
Python
230
star
10

python-fuse-sample

A sample FUSE filesystem in Python.
Python
169
star
11

django-project-template

The Django project template I use, for installation with django-admin.
Python
161
star
12

gr8w8upd8m8

Gr8W8Upd8M8 is a script to automatically read your weight from a Wii Balance Board. ⛺
Python
145
star
13

imdbapi

An API for the IMDB site. ⛺
Python
131
star
14

A6lib

An ESP8266/Arduino library for communicating with the A6 GSM module. ⛺
C++
127
star
15

encbup

Encrypted backups (without the backups)
Python
121
star
16

sysaidmin

A GPT-powered sysadmin.
Python
115
star
17

tiny-ESP8266-breakout

A very small and basic ESP8266 breakout board
110
star
18

omnisync

omnisync is a universal file synchroniser and backup program (think rsync) that supports multiple transport systems (such as plain files, sftp, s3 and virtual, currently, and support for ftp, http, et al is planned). It is designed to be fast, small, extensible, portable and bandwidth-efficient. It is available for Linux, Windows and Mac. ⛺
Python
87
star
19

iRotary

One man's quest to turn an old rotary phone into a mobile phone.
Arduino
83
star
20

django-cloudflare-push

A piece of middleware that uses Cloudflare's HTTP/2 Push to push static media to the clients. ⛺
Python
75
star
21

gweet

A message queue for the abhorrently named Internet of Things
Go
70
star
22

static-appengine-hoster

An App Engine application for hosting static sites under multiple domains in a single app.
Python
66
star
23

django-tokenauth

Django authentication backend that uses tokens sent over email.
Python
63
star
24

arduino-irrigation

A GSM-based Arduino remote controller for an irrigation system.
Arduino
62
star
25

esplights

A home automation sensor and controller based on an ESP8266.
Arduino
48
star
26

yeecli

A command-line utility for a YeeLight RGB lamp. (mirror of https://gitlab.com/stavros/yeecli)
Python
42
star
27

episode-renamer

Episode renamer is a simple python script that renames folders of TV episode video files to their proper names.
Python
41
star
28

kicad-lib

My KiCad components library.
35
star
29

Spamnesty

A service that tries to have some fun with spam (mirror of https://gitlab.com/stavros/Spamnesty/)
Python
33
star
30

captainwebhook

Captain Webhook eats webhooks and executes commands.
Python
30
star
31

spamgpt

SpamGPT, a bot that wastes spammers' damn time, like they waste mine.
Python
25
star
32

pastebinit

pastebinit is a command-line tool to send data to a "pastebin", a web site which allows its users to upload snippets of text for public viewing. ⛺
Python
25
star
33

apache-config

A script for configuring apache with Django+wsgi/fcgi+virtualenv+etc.
Python
23
star
34

ArduiRC

Remotely control IR/RF devices from a computer with Arduino.
Arduino
18
star
35

docker-fgallery

A Dockerfile for installing fgallery. ⛺
Shell
18
star
36

ez-openai

Ez API, ez life.
Python
16
star
37

landing-page

A very simple landing page app for AppEngine.
Python
15
star
38

stringphone

String phone is a secure communications protocol and library geared towards embedded devices.
Python
14
star
39

bakeit

A command-line utility for pastery, the best pastebin in the world.
Python
12
star
40

pythess-files

The code files/presentations/everything else used in the PyThess meetup
Jupyter Notebook
11
star
41

lektor-shortcodes

A shortcodes plugin for lektor
Python
11
star
42

shufflecast

A TV channel with all your favorite shows.
Python
11
star
43

photocopy

A script to archive photos off a camera to a directory.
Python
10
star
44

nxt-python

NXT-Python is a python driver/interface for the Lego Mindstorms NXT robot based on NXT_python.
Python
10
star
45

Reverend

A clone of Reverend, the naive Bayesian classifier written in Python.
Python
10
star
46

A6-ESP8266-breakout

A breakout board that includes an ESP8266 and an A6 GSM module, for easily making GSM-enabled applications (mirror)
Shell
9
star
47

Pythia

High quality & fast "true random" number generator (shuffling system)
JavaScript
9
star
48

lektor-thumbnail-generator

A thumbnail generator for Lektor content
Python
9
star
49

pastery.vim

A Vim plugin for the sweetest pastebin in the world, pastery.net.
Vim Script
9
star
50

apt-btrfs-snapshot

A fork of apt-btrfs-snapshot.
Python
8
star
51

gamelights

An RGB LED strip WiFi controller, complete with code and PCB designs.
KiCad Layout
8
star
52

mediacenter-in-a-box

A media center in a box, compatible with Harbormaster for one-line deployments.
Python
8
star
53

pylast

A clone of Amr Hassan's pylast: a python interface to last.fm (and other api-compatible websites)
Python
6
star
54

awesomeblog-club

An easily self hostable curation site for collecting blogs and links.
TypeScript
5
star
55

django-project-templates

Some Django project templates for various things.
4
star
56

requests-guard

requests-guard is a small library that allows you to impose size and time limits on your HTTP requests.
Python
4
star
57

ChatGPT-Bot

A small Python library that makes it easier to write a ChatGPT bot.
Python
4
star
58

rust-bakeit

A command-line client for pastery.net, the best pastebin in the world (official mirror of https://gitlab.com/stavros/rust-bakeit).
Rust
3
star
59

the-spam-chronicles

The Spam Chronicles, a static website where I post all the spam I got and SpamGPT auto-replied to.
Python
2
star
60

progress

A simple progress bar in Python
Python
2
star
61

blacklist-pre-commit-hook

A pre-commit hook for blacklisting certain functions
Python
2
star
62

back-scratcher

A back scratching robot!
Python
2
star
63

zulipbot

A ChatGPT Zulip bot
Python
1
star
64

iphoneconverter

A small script to convert a folder of videos into an iPhone format.
1
star
65

reddit-rage-faces

An Opera extension to put ragefaces in every subreddit.
JavaScript
1
star