jospy Documentation

jospy helps Python developers build, clean, filter, and serialize JSON payloads for REST APIs. It has no runtime dependencies and uses Python’s built-in json module underneath.

Install

pip install jospy

For local development:

pip install -e ".[dev]"

For local docs builds:

pip install -e ".[docs]"
sphinx-build -b html docs docs/_build/html

JSON Conversion

from jospy import to_json, to_python

data = to_python('{"name": "Ada", "active": true}')
body = to_json(data, pretty=True)

Chainable Data Layer

data() wraps a JSON-like value in a DataLayer, so helpers can be composed with dot calls.

from jospy import data

users = [
    {"id": 1, "name": "Ada", "team": "api", "email": None, "password": "secret"},
    {"id": 2, "name": "Grace", "team": "infra", "email": "g@example.com"},
]

body = (
    data(users)
    .where(team="api")
    .filter(exclude=["password"], drop_nulls=True)
    .fill({"active": True})
    .api_response(message="ok")
    .to_json(pretty=True)
)

Use .unwrap() when you want the plain Python value back.

public_users = data(users).omit("password").unwrap()

Nested paths work with .get() and .set().

payload = data({}).set("user.profile.email", "ada@example.com")
email = payload.get("user.profile.email").unwrap()

Nulls And Defaults

from jospy import fill, null

payload = {"name": "Ada", "email": null()}
payload = fill(payload, {"email": "unknown@example.com", "active": True})

null() returns Python None when called without arguments. With values, it checks whether every value is None.

Filtering API Payloads

from jospy import filter_data

users = [
    {"id": 1, "name": "Ada", "password": "secret", "team": "api"},
    {"id": 2, "name": "Grace", "password": "secret", "team": "infra"},
]

public_users = filter_data(
    users,
    exclude=["password"],
    where={"team": "api"},
    drop_nulls=True,
)

REST Responses

from jospy import api_response, paginated

response = api_response({"id": 1}, message="created", status=201)
page = paginated([1, 2, 3], page=1, per_page=2)

API Reference

to_python(data, default=...)

Convert JSON text, bytes, bytearray, or a Path to Python data. If data is already a Python object, it is returned unchanged.

data(value)

Create a chainable DataLayer.

DataLayer

Chainable wrapper with these methods:

  • .to_python() / .from_json()

  • .to_json()

  • .clean()

  • .fill()

  • .filter()

  • .pick() / .omit()

  • .get() / .set()

  • .map()

  • .where()

  • .api_response()

  • .paginated()

  • .unwrap()

from_json(data, default=...)

Alias for to_python().

to_json(data, pretty=False, sort_keys=False, ensure_ascii=False, default=None)

Serialize Python data to a JSON string.

load_json(path, default=...)

Read a JSON file into Python data.

save_json(path, data, pretty=True)

Write Python data to a JSON file and return the target Path.

clean(data, drop_nulls=False, drop_empty=False)

Normalize common Python objects into JSON-friendly values. Supports dataclasses, dates, datetimes, times, decimals, enums, UUIDs, paths, mappings, tuples, and sets.

null(value=..., *values)

Return None with no arguments. With one or more arguments, return True only when all values are None.

is_empty(value)

Return True for None, blank strings, and empty containers.

fill(data, defaults=None, overwrite_empty=False)

Recursively fill missing or None values from a default shape.

filter_data(data, include=None, exclude=None, where=None, drop_nulls=False, drop_empty=False)

Filter dictionaries or lists of dictionaries for API payloads. where accepts exact values or predicate functions.

pick(data, *keys)

Return only the selected dictionary keys.

omit(data, *keys)

Return a dictionary without the selected keys.

get_path(data, path, default=None, sep=".")

Read nested values from dictionaries and lists with dot path syntax.

set_path(data, path, value, sep=".")

Set nested dictionary values with dot path syntax.

api_response(data=None, message=None, status=200, success=None, errors=None, meta=None)

Create a consistent REST API response dictionary.

paginated(items, page=1, per_page=25, total=None)

Create a REST-friendly paginated response.