Another Python API schema handling and JSON (de)serialization through typing annotation; light, simple, powerful.
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:
- properties.py
- conversion.py
- validator.py
- stringified.py
- generic.py
- properties2.py
- conversion2.py
- validator2.py
- recursivity_and_pep563.py
- generic_conversion.py
- raw_conversion.py
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
Built Distribution
Hashes for apischema-0.1.3-py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 814180affe9457d94a9814cd48d90563245ff646daf9d8eec7b7bc78af668011 |
|
MD5 | caf97811ca9d58ad9d114da7c486b688 |
|
BLAKE2b-256 | 17d9b7d3f394ca70e97ce6fb53e670b13106798b89210eabcbc7ba080ac374a9 |