Skip to main content

JSON:API Support for Pydantic

Project description

build workflow pypi licence status

PyDANJA

JSON:API (or JSONAPI) Suport for Pydantic

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.8 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


app = FastAPI()


# 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.

Future Enhancements

  • At the moment, the schema output from FastAPI includes the intermediary objects needed for the heirarchy in JSON:API, these should be suppressed
  • The type names in the API output also include the full canonical generic class names and the contained class name, this should reduce to just the contained class name

Contributing

This project uses PDM for dependency and virtual environment management.

It aims to use the lowest supported Python version (3.8 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 PDM by using:

  • pdm run lint
  • pdm run test
  • pdm run typecheck

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

pydanja-0.1.10.tar.gz (9.7 kB view details)

Uploaded Source

Built Distribution

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

pydanja-0.1.10-py3-none-any.whl (5.3 kB view details)

Uploaded Python 3

File details

Details for the file pydanja-0.1.10.tar.gz.

File metadata

  • Download URL: pydanja-0.1.10.tar.gz
  • Upload date:
  • Size: 9.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: pdm/2.8.2 CPython/3.10.6

File hashes

Hashes for pydanja-0.1.10.tar.gz
Algorithm Hash digest
SHA256 2831d9c847d64caed73256059c72887eaf6a555681099a3feaf6af290c9f48a5
MD5 00c0443294a9931b3ecd486ef4067ed9
BLAKE2b-256 c75c6b5b53e1645d48881b24e5444d8cef889a2a2e52802fe5406e01443f16d9

See more details on using hashes here.

File details

Details for the file pydanja-0.1.10-py3-none-any.whl.

File metadata

  • Download URL: pydanja-0.1.10-py3-none-any.whl
  • Upload date:
  • Size: 5.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: pdm/2.8.2 CPython/3.10.6

File hashes

Hashes for pydanja-0.1.10-py3-none-any.whl
Algorithm Hash digest
SHA256 ef826f122f761221e698256a95b37bd9c9bd4802e436bd12211fa0614a43649d
MD5 41a7abdd7f4e27b7ed3e1204e552c806
BLAKE2b-256 32083c8ff3321468580a265f719b6f11bd395d5c59018682ac7dd6111342938c

See more details on using hashes here.

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