Skip to main content

build workflow pypi licence status uv-managed

PyDANJA

PyDANtic JSONAPI

JSON:API (or JSONAPI) Suport for Pydantic

Output JSONAPI from your FastAPI or PyDantic based application with very little code.

This is a series of classes that can be included into your Pydantic project that act as a container format for outputting and verifying JSON:API compliant content.

This library makes use of BaseModel generics to contain either a single resource or a list of resources as further BaseModels.

Installation

pip install pydanja

Requirements

This will support the oldest non-EOL Python (3.10 as of the writing of this document)

Usage

With pydantic

from pydanja import DANJAResource


class TestType(BaseModel):
    """A simple Pydantic BaseModel"""
    # We use an extra resource_id to indicate the ID for JSON:API
    testtype_id: Optional[int] = Field(
        alias="id",
        default=None,
        json_schema_extra={
            "resource_id": True
        }
    )
    name: str
    description: str


resource_container = DANJAResource.from_basemodel(TestType(
    id=1,
    name="Stuff!",
    description="This is desc!"
))
print(resource_container.model_dump_json(indent=2))

# The BaseModel contained resource can be acquired by
resource = resource_container.resource

This basic example shows a Pydantic BaseModel being contained within a DANJAResource object. The model_dump_json will output JSON:API:

{
  "data": {
    "id": "1",
    "type": "testtype",
    "lid": null,
    "attributes": {
      "testtype_id": 1,
      "name": "Stuff!",
      "description": "This is desc!"
    },
    "relationships": null,
    "links": null,
    "meta": null
  },
  "links": null,
  "meta": null,
  "included": null
}

Note that all JSON:API fields are included in the output of the model dump. If you are using an API framework like FastAPI, you use the response_model_exclude_none to suppress fields with no values.

FastAPI example

from typing import Optional, Union
from pydantic import BaseModel, Field, ConfigDict
from fastapi import FastAPI
from pydanja import DANJAResource, DANJAResourceList, DANJAError, danja_openapi
from fastapi.openapi.utils import get_openapi


app = FastAPI()


# Optional: Clear up the OpenAPI documentation by de-cluttering schema
def custom_openapi():
    if app.openapi_schema:
        return app.openapi_schema

    openapi_schema = get_openapi(
        title="FastAPI",
        version="2.5.0",
        summary="FastAPI",
        description="FastAPI",
        routes=app.routes,
    )

    app.openapi_schema = danja_openapi(openapi_schema)

    return app.openapi_schema

app.openapi = custom_openapi



# Example BaseModel
class TestType(BaseModel):
    # If we use ID, then we must alias it to avoid clashes with Python
    testtype_id: Optional[int] = Field(
        alias="id",
        default=None,
        json_schema_extra={
            "resource_id": True
        }
    )
    name: str
    description: str


@app.post("/", response_model_exclude_none=True)
async def test_func(payload: DANJAResource[TestType]) -> Union[DANJAResource[TestType], DANJAError]:
    """
    payload will be verified correctly for inbound JSON:API content
    The Union includes a reference to the JSON:API error object that this could throw
    """
    res = TestType(
        id=1,
        name="Stuff!",
        description="This is description!"
    )
    return DANJAResource.from_basemodel(res)

@app.get("/", response_model_exclude_none=True)
async def test_get() -> Union[DANJAResourceList[TestType], DANJAError]:
    values = [
        TestType(id=1, name="One", description="Desc One"),
        TestType(id=2, name="Two", description="Desc Two"),
        TestType(id=3, name="Three", description="Desc Three"),
        TestType(id=4, name="Four", description="Desc Four"),
    ]
    return DANJAResourceList.from_basemodel_list(values)

This library supports:

  • Single resources (DANJAResource)
  • Lists of resources (DANJAResourceList)
  • Error objects (DANJAErrorList/DANJAError)
  • Link objects (DANJALink)

There are more examples, including FastAPI code in the src/examples directory.

Contributing

This project uses uv for dependency and virtual environment management.

It aims to use the lowest supported Python version (3.10 as of the writing of this document)

There are currently three build steps in the actions workflow:

  • Unit test
  • Linting
  • Type checking

These can be run through uv by using:

  • uv run ./lint
  • uv run ./test
  • uv run ./typecheck
  • uv run ./all

Metadata

Release files for pydanja 0.1.32

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pydanja 0.1.32
File Size Uploaded
pydanja-0.1.32.tar.gz 9.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for pydanja 0.1.32
File Interpreter ABI Platform
pydanja-0.1.32-py3-none-any.whl Python 3 none any Details

Total release size: 17.6 kB

Release files / pydanja-0.1.32.tar.gz

Download URL pydanja-0.1.32.tar.gz
Size 9.4 kB
Tags Source
SHA-256 checksum
How to use checksums
75cb945fbada2ef1489b32a82d405e97cc0329d1c84079b005e6a697ad2cc9fc
BLAKE2b-256 checksum
How to use checksums
413dc6f5c68cdfbadad280e5e097ac0324d5419ff08cee1a6a77b4b7e2720d0f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.9.10 {"installer":{"name":"uv","version":"0.9.10"},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / pydanja-0.1.32-py3-none-any.whl

Download URL pydanja-0.1.32-py3-none-any.whl
Size 8.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
d58d14c81cdc609fdadc922c2dcc51610f4909c2aaf566f113c632fff3539b4e
BLAKE2b-256 checksum
How to use checksums
af4b22b5f47406051b6fcda41eeaa006881995fc9e3af1628630bca96a32c6b6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.9.10 {"installer":{"name":"uv","version":"0.9.10"},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release history Release notifications | RSS feed

This release

0.1.32 This release

2 release files

0.1.30

2 release files

0.1.26

2 release files

0.1.21

2 release files

0.1.18

2 release files

0.1.17

2 release files

0.1.15

2 release files

0.1.14

2 release files

0.1.13

2 release files

0.1.12

2 release files

0.1.11

2 release files

0.1.10

2 release files

0.1.9

2 release files

0.1.8

2 release files

0.1.7

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page