Skip to main content

Pydantic models for implementing JSON Patch.

Project description

Pydantic JSON Patch

Python uv CI PyPI - Version SonarQube Cloud - Maintainability Coverage Status

Pydantic models for implementing JSON Patch.

Installation

Pydantic JSON Patch is published to PyPI, and can be installed with e.g.:

pip install pydantic-json-patch

Models

A model is provided for each of the six JSON Patch operations:

  • AddOp
  • CopyOp
  • MoveOp
  • RemoveOp
  • ReplaceOp
  • TestOp

As repeating the op is a bit awkward (CopyOp(op="copy", ...)), a create factory method is available:

>>> from pydantic_json_patch import AddOp
>>> op = AddOp.create(path="/foo/bar", value=123)
>>> op
AddOp(op='add', path='/foo/bar', value=123)
>>> op.model_dump_json()
'{"op":"add","path":"/foo/bar","value":123}'

The operations that take a value (AddOp, ReplaceOp, and TestOp) are generic, so you can parameterize them with a specific value type:

>>> from pydantic_json_patch import ReplaceOp
>>> op = ReplaceOp[str].create(path="/foo/bar", value="hello")
>>> op
ReplaceOp[str](op='replace', path='/foo/bar', value='hello')

Additionally, there are two compound types:

  • Operation is the union of all the operations; and
  • JsonPatch is a Pydantic RootModel representing a sequence of operations.

JsonPatch can be used directly for validation:

>>> from pydantic_json_patch import JsonPatch
>>> patch = JsonPatch.model_validate_json('[{"op":"add","path":"/a/b/c","value":"foo"}]')
>>> patch[0]
AddOp(op='add', path='/a/b/c', value='foo')

Pointer tokens

The path property (and from property, where present) of an operation is a JSON Pointer. This means that any ~ or / characters in property names need to be properly encoded. To aid working with these, the models expose a read-only path_tokens property (and, where appropriate, from_tokens):

>>> from pydantic_json_patch import CopyOp
>>> op = CopyOp.model_validate_json('{"op":"copy","path":"/foo/bar~1new","from":"/foo/bar~0old"}')
>>> op
CopyOp(op='copy', path='/foo/bar~1new', from_='/foo/bar~0old')
>>> op.path_tokens
('foo', 'bar/new')
>>> op.from_tokens
('foo', 'bar~old')

Similarly, the create factory methods can accept sequences of tokens, and will encode them appropriately:

>>> from pydantic_json_patch import TestOp
>>> op = TestOp.create(path=("annotations", "scope/value"), value=None)
>>> op
TestOp(op='test', path='/annotations/scope~1value', value=None)
>>> op.model_dump_json()
'{"op":"test","path":"/annotations/scope~1value","value":null}'

FastAPI

You can use this package to validate a JSON Patch endpoint in a FastAPI application, for example:

import typing as tp
from uuid import UUID

from fastapi import Body, FastAPI

from pydantic_json_patch import JsonPatch

app = FastAPI()


@app.patch("/resource/{resource_id}")
def _(resource_id: UUID, operations: tp.Annotated[JsonPatch, Body()]) -> ...:
    ...

This will provide a sensible example of the request body:

Screenshot of Swagger UI request body example

and list the models along with the other schemas:

Screenshot of Swagger UI schema list

Value type validation

You can also use a more specific type to apply type validation to the value properties:

import typing as tp
from uuid import UUID

from fastapi import Body, FastAPI
from pydantic import Discriminator

from pydantic_json_patch import AddOp, TestOp

app = FastAPI()


@app.patch("/resource/{resource_id}")
def _(
    resource_id: UUID,
    operations: tp.Annotated[list[tp.Annotated[AddOp[int] | TestOp[int], Discriminator("op")]], Body()],
) -> ...:
    ...

Notes:

  • Explicitly specifying the discriminator gives better results on failed validation for unions of operations; and
  • Parameterised versions of the operations will also appear in the JSON Schema as e.g. AddOp_int_ (with the title "JsonPatchAddOperation[int]").

Development

This project uses uv for managing dependencies. Having installed uv, you can set the project up for local development with:

uv sync
uv run pre-commit install

The pre-commit hooks will ensure that the code style checks (using isort and ruff) are applied.

Testing

The test suite uses pytest and can be run with:

uv run pytest

Additionally, there is ty type-checking that can be run with:

uv run ty check

FastAPI

You can preview the FastAPI/Swagger documentation by running:

uv run fastapi dev tests/app.py

and visiting the Documentation link that's logged in the console. This will auto-restart as you make changes.

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

pydantic_json_patch-2.1.0.tar.gz (6.4 kB view details)

Uploaded Source

Built Distribution

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

pydantic_json_patch-2.1.0-py3-none-any.whl (7.5 kB view details)

Uploaded Python 3

File details

Details for the file pydantic_json_patch-2.1.0.tar.gz.

File metadata

  • Download URL: pydantic_json_patch-2.1.0.tar.gz
  • Upload date:
  • Size: 6.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for pydantic_json_patch-2.1.0.tar.gz
Algorithm Hash digest
SHA256 00b3cbf720a81dcabcb29dfbd96e56e74ce5109885c5e9d6ea6c2b7b3d6899e2
MD5 0d24f9e1eca1d6e575e13dcc0c9998a4
BLAKE2b-256 2818b5a34f3db77976585ee60c85c1da298ec0f0b1a73dc53ea9ed76e8b9149f

See more details on using hashes here.

Provenance

The following attestation bundles were made for pydantic_json_patch-2.1.0.tar.gz:

Publisher: push.yml on textbook/pydantic_json_patch

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pydantic_json_patch-2.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for pydantic_json_patch-2.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 0dcda893c297166f0b84beff25a9db3bc09e81ddc7fc4eec2243d68e7fd053a3
MD5 de3c97ff8af404eb44eae8819ca87466
BLAKE2b-256 6b31119f2c6a99fb7495f682d79c454c90b9e9a9465908e51770f158cbabd00b

See more details on using hashes here.

Provenance

The following attestation bundles were made for pydantic_json_patch-2.1.0-py3-none-any.whl:

Publisher: push.yml on textbook/pydantic_json_patch

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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