Skip to main content

Another Python API schema handling and JSON (de)serialization through typing annotation; light, simple, powerful.

Reason this release was yanked:

not stable

Project description

APISchema

Another Python API schema handling and JSON (de)serialization through typing annotation; light, simple, powerful.

Why another library

Because i'm not satisfied with existing ones. I would like to:

  • stay closest as possible to the standard library (dataclasses, etc.) and use it 'as is'
  • be able to tune the library and use my own types, instead of having to do a PR for handling of bson.ObjectId
  • have the least possible dynamic thing (like using string for attribute name) And I simply want to enjoy myself coding this stuff.

Getting Started

pip install apischema and follow examples (the only documentation for now)

Examples

Following example can be run 'as is' in Python 3.7 (all examples are valid tests of the library). quickstart.py

from dataclasses import dataclass, field
from enum import Enum
from typing import List, NewType
from uuid import UUID, uuid4

from pytest import raises

from apischema import (ValidationError, build_input_schema, build_output_schema,
                       from_data, schema, to_data)

Tag = NewType("Tag", str)
schema(title="resource tag", max_len=64)(Tag)


class ResourceType(Enum):
    RESOURCE_A = "A"
    RESOURCE_B = "B"


@dataclass
class Resource:
    id: UUID
    type: ResourceType
    tags: List[Tag] = field(default_factory=list,
                            metadata=schema(max_items=5, unique=True))


def test_resource():
    uuid = uuid4()
    data = {
        "id":   str(uuid),
        "type": "A",
        "tags": ["tag1"]
    }
    resource = from_data(data, Resource)
    assert resource == Resource(uuid, ResourceType.RESOURCE_A, [Tag("tag1")])
    assert to_data(resource) == data
    json_schema = build_input_schema(Resource)
    assert json_schema == build_output_schema(Resource)
    assert to_data(json_schema) == {
        "type":                 "object",
        "required":             ["id", "type"],
        "additionalProperties": False,
        "properties":           {
            "id":   {
                "type":   "string",
                "format": "uuid",
            },
            "type": {
                "type": "string",
                "enum": ["A", "B"],
            },
            "tags": {
                "type":        "array",
                "maxItems":    5,
                "uniqueItems": True,
                "items":       {
                    "type":      "string",
                    "title":     "resource tag",
                    "maxLength": 64,
                },
            },
        }
    }


def test_resource_error():
    with raises(ValidationError) as err:
        from_data({"id": "uuid", "type": None, "tags": ["a", "a"]}, Resource)
    assert err.value == ValidationError(children={
        "id":   ValidationError([
            "[ValueError]badly formed hexadecimal UUID string"
        ]),
        "type": ValidationError([
            "None is not a valid ResourceType"
        ]),
        "tags": ValidationError([
            "duplicates items in ['a', 'a'] (uniqueItems)"
        ])
    })

See other examples; a suggested order:

Benchmark

According to Pydantic benchmark, using only CPython, apischema is a little behind Pydantic, and by toggling some features not provided by Pydantic BaseModel (__post_init__, patternProperties at field level) with some optimizations (dataclass fields caching), apischema becomes the fastest, ahead of Pydantic and others.

Concerning Cython, apischema is blocked for now by this Cython issue

Todo

  • documentation (obviously)
  • tests (coverage is not enough, and edge cases)
  • make it work in Python 3.6 (adds dataclass dependency in packaging, checks, etc.)
  • optimizations (even if the performances are quite satisfactory) About formatting and packaging, I'm honestly not interested by the mess of Python regarding theses 20th century issues so I did the minimum. But I know that if the library gains popularity, it will be a mandatory step to dig in it.

Project details


Release history Release notifications | RSS feed

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

apischema-0.1.4.tar.gz (34.7 kB view hashes)

Uploaded Source

Built Distribution

apischema-0.1.4-py3-none-any.whl (35.5 kB view hashes)

Uploaded Python 3

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page