kerno.web.jsonright module

A better way to send entities through the wire.

What problems does this solve?

1. Python model classes do not need to implement as_dict(). Instead, you implement a variation of a jsonright() function in a separate step, which could even be in a separate package, totally decoupled. This does single dispatch – please learn about this.

2. When we send objects through the wire, different detail levels are commonly needed – for instance, first we only want the names of users to be shown in a list, and then in a separate step, we might want all the details of a single user. Your jsonright() implementation receives a features argument which can be a set of strings (or a sequence of any type) specifying the level of detail. This keeps the API uniform.

3. This module also offers tools to help you write those jsonright() implementations – especially entity2dict().

4. Sending common JSON through the wire has a problem: the repetition of keys. For example, if you output a list of users, the keys of each object, such as “id”, “name”, “email” etc. are repeated for each instance in the JSON. Here we save bandwidth by encoding the data differently and then reassembling it in the client.

5. The jsonright() interface has a peto argument, therefore when implementing it you have access to the context, including application configuration, repository (data access layer), current user etc.

How are data organized to save bandwidth?

jsonright avoids repeating key names when outputting sequences of entities in JSON. It pivots the table so it grows to the right:

[
    ["id", 1, 2],
    ["email", "ex@am.pl", "sagan@nasa.gov"],
]

Of course objects are easily reassembled in Javascript. The function that does that is in the file kerno.js.

Usage

Please see a usage example in our tests.

kerno.web.jsonright.entity2dict(obj: Any, keys: Iterable[str] = ()) Dict[str, Any][source]

Dump certain instance variables of obj into a dictionary.

This function is reusable.

If you do not provide any keys, a sensible default is used.

kerno.web.jsonright.excluding(blacklist: Sequence[str], keys: Iterable[str]) Iterable[str][source]
kerno.web.jsonright.jsonright(obj: Any, peto: kerno.peto.AbstractPeto, features=(), **kw) Any[source]
kerno.web.jsonright.jsonright(obj: None, peto: kerno.peto.AbstractPeto, features=(), **kw) Any
kerno.web.jsonright.jsonright(obj: bool, peto: kerno.peto.AbstractPeto, features=(), **kw) Any
kerno.web.jsonright.jsonright(obj: float, peto: kerno.peto.AbstractPeto, features=(), **kw) Any
kerno.web.jsonright.jsonright(obj: int, peto: kerno.peto.AbstractPeto, features=(), **kw) Any
kerno.web.jsonright.jsonright(obj: str, peto: kerno.peto.AbstractPeto, features=(), **kw) Any
kerno.web.jsonright.jsonright(obj: bytes, peto: kerno.peto.AbstractPeto, features=(), **kw) Any
kerno.web.jsonright.jsonright(obj: decimal.Decimal, peto: kerno.peto.AbstractPeto, features=(), **kw) float
kerno.web.jsonright.jsonright(obj: datetime.date, peto: kerno.peto.AbstractPeto, features=(), **kw) str
kerno.web.jsonright.jsonright(obj: datetime.datetime, peto: kerno.peto.AbstractPeto, features=(), **kw) str
kerno.web.jsonright.jsonright(obj: dict, peto: kerno.peto.AbstractPeto, features=(), **kw) Dict[str, Any]
kerno.web.jsonright.jsonright(obj: frozenset, peto: kerno.peto.AbstractPeto, features=(), **kw) Sequence
kerno.web.jsonright.jsonright(obj: set, peto: kerno.peto.AbstractPeto, features=(), **kw) Sequence
kerno.web.jsonright.jsonright(obj: tuple, peto: kerno.peto.AbstractPeto, features=(), **kw) Sequence
kerno.web.jsonright.jsonright(obj: list, peto: kerno.peto.AbstractPeto, features=(), **kw) Sequence

Overloadable function to encode entities for sending through the wire.

You can register your own implementations which get called depending on the type of obj.

kerno.web.jsonright.keys_from(obj: Any) Iterable[str][source]

Return the names of the instance variables of obj.

kerno.web.jsonright.only_relevant(keys: Iterable[str]) Iterable[str][source]

Ignore strings that start in dunder (“__”) or in “_sa_”.

These usually keep SQLAlchemy state.