Skip to main content
Join the official 2019 Python Developers SurveyStart the survey!

Another Python API schema handling through typing annotation; light, simple, powerful.

Project description

APISchema

Another Python API schema handling through typing annotation; light, simple, powerful.

Getting Started

Install with pip install pyapischema (I'm currently claiming apischema name on PyPi). Use it following example below

Examples

Simple example:

import json
import uuid
from dataclasses import dataclass
from typing import Iterator, Sequence

from apischema.data import from_data, to_data
from apischema.model import Model
from apischema.schema import build_schema
from apischema.validator import Error, validate


class UUID(Model[str], uuid.UUID):
    pass


@dataclass
class MyModel:
    id: UUID
    elts: Sequence[int]
    check_sum: int

    @validate("elts", "check_sum")
    def elts_sum(self) -> Iterator[Error]:
        if sum(self.elts) != self.check_sum:
            yield "check_sum doesn't match elts"


data = json.load(...) # type: ignore
# data = {"id": str(uuid4()), "elts": [1, 2], "check_sum": 3} 
my_model = from_data(MyModel, data, camel_case=False)
data2 = to_data(MyModel, my_model, camel_case=False)

openapi = build_schema(MyModel, camel_case=False)

A little bit more complex

from __future__ import annotations

from dataclasses import dataclass, field
from typing import List, TypeVar, Union, Iterator, Generic

import pytest

from apischema.data import from_data
from apischema.model import Model
from apischema.validation import ValidationError
from apischema.validator import Error, validate

T = TypeVar("T")


class A(Model[Union[T, List[T]]], List[T]):
    @classmethod
    def from_model(cls, obj: Union[T, List[T]]) -> A:
        if isinstance(obj, list):
            return A(obj)
        else:
            return A([obj])

    def to_model(self) -> Union[T, List[T]]:
        return self[0] if len(self) == 1 else list(self)

    @validate
    def no_consecutive_duplicates(self) -> Iterator[Error]:
        if len(self) == 0:
            return
        cur = self[0]
        for i in range(1, len(self)):
            if cur == self[i]:
                yield f"duplicate elt {cur} in position {i}"
            cur = self[i]


@dataclass
class B(Generic[T]):
    a: A[T] = field(default_factory=A)


def test():
    print()
    print(from_data(B, {}))
    print(from_data(B[int], {}))
    print(from_data(B[int], {"a": 0}))
    print(from_data(B[int], {"a": [1, 2]}))
    with pytest.raises(ValidationError) as err:
        print(from_data(B[int], {"a": [1, 2, 2]}))
    print(err.value)
    with pytest.raises(ValidationError) as err:
        print(from_data(B[str], {"a": ["", 0, 1]}))
    print(err.value)

With spec:

from dataclasses import dataclass

from apischema.data import from_data, to_data
from apischema.field import field
from apischema.model import Model
from apischema.schema import Schema, build_schema
from apischema.spec import NumSpec, SpecClass


class ShortString(Model[str], SpecClass, str):
    max_length = 10


@dataclass
class A:
    positive: int = field(spec=NumSpec(min=0))
    short_string: ShortString = ShortString("")


def test():
    # data = json.load(...)
    data = {"positive": 1, "shortString": "ok"}
    a = from_data(A, data)
    data2 = to_data(A, a)
    print(data2)

    openapi = build_schema(A)
    print(to_data(Schema, openapi))

Project details


Release history Release notifications

Download files

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

Files for pyapischema, version 1.0.0
Filename, size File type Python version Upload date Hashes
Filename, size pyapischema-1.0.0-py3-none-any.whl (13.6 kB) File type Wheel Python version py3 Upload date Hashes View hashes
Filename, size pyapischema-1.0.0.tar.gz (10.9 kB) File type Source Python version None Upload date Hashes View hashes

Supported by

Elastic Elastic Search Pingdom Pingdom Monitoring Google Google BigQuery Sentry Sentry Error logging AWS AWS Cloud computing DataDog DataDog Monitoring Fastly Fastly CDN SignalFx SignalFx Supporter DigiCert DigiCert EV certificate StatusPage StatusPage Status page