Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/wyfo/apischema
JSON (de)serialization, GraphQL and JSON schema generation using Python typing.
https://github.com/wyfo/apischema
dataclasses graphql graphql-python graphql-relay graphql-schema graphql-server json json-api json-schema json-schema-generator openapi pypy3 python python-typing serialization validation
Last synced: 4 days ago
JSON representation
JSON (de)serialization, GraphQL and JSON schema generation using Python typing.
- Host: GitHub
- URL: https://github.com/wyfo/apischema
- Owner: wyfo
- License: mit
- Created: 2019-08-08T07:33:15.000Z (over 5 years ago)
- Default Branch: master
- Last Pushed: 2025-01-06T20:08:06.000Z (15 days ago)
- Last Synced: 2025-01-10T04:05:01.774Z (11 days ago)
- Topics: dataclasses, graphql, graphql-python, graphql-relay, graphql-schema, graphql-server, json, json-api, json-schema, json-schema-generator, openapi, pypy3, python, python-typing, serialization, validation
- Language: Python
- Homepage: https://wyfo.github.io/apischema/
- Size: 6.67 MB
- Stars: 230
- Watchers: 9
- Forks: 18
- Open Issues: 23
-
Metadata Files:
- Readme: README.md
- Funding: .github/FUNDING.yml
- License: LICENSE.txt
Awesome Lists containing this project
README
# apischema
JSON (de)serialization, GraphQL and JSON schema generation using Python typing.
*apischema* makes your life easier when dealing with API data.
## Documentation
[https://wyfo.github.io/apischema/](https://wyfo.github.io/apischema/)
## Install
```shell
pip install apischema
```
It requires only Python 3.8+. *PyPy3* is also fully supported.## Why another library?
(If you wonder how this differs from the *pydantic* library, see the [dedicated section of the documentation](https://wyfo.github.io/apischema/dev/difference_with_pydantic) — there are many differences.)
This library fulfills the following goals:
- stay as close as possible to the standard library (dataclasses, typing, etc.) — as a consequence we do not need plugins for editors/linters/etc.;
- avoid object-oriented limitations — do not require a base class — thus handle easily every type (`Foo`, `list[Bar]`, `NewType(Id, int)`, etc.) the same way.
- be adaptable, provide tools to support any types (ORM, etc.);
- avoid dynamic things like using raw strings for attributes name - play nicely with your IDE.No known alternative achieves all of this, and apischema is also [(a lot) faster](https://wyfo.github.io/apischema/dev/optimizations_and_benchmark#benchmark) than all of them.
On top of that, because APIs are not only JSON, *apischema* is also a complete GraphQL library
> Actually, *apischema* is even adaptable enough to enable support of competitor libraries in a few dozens of line of code ([pydantic support example](https://wyfo.github.io/apischema/dev/examples/pydantic_support) using [conversions feature](https://wyfo.github.io/apischema/dev/conversions))
## Example
```python
from collections.abc import Collection
from dataclasses import dataclass, field
from uuid import UUID, uuid4import pytest
from graphql import print_schemafrom apischema import ValidationError, deserialize, serialize
from apischema.graphql import graphql_schema
from apischema.json_schema import deserialization_schema# Define a schema with standard dataclasses
@dataclass
class Resource:
id: UUID
name: str
tags: set[str] = field(default_factory=set)# Get some data
uuid = uuid4()
data = {"id": str(uuid), "name": "wyfo", "tags": ["some_tag"]}
# Deserialize data
resource = deserialize(Resource, data)
assert resource == Resource(uuid, "wyfo", {"some_tag"})
# Serialize objects
assert serialize(Resource, resource) == data
# Validate during deserialization
with pytest.raises(ValidationError) as err: # pytest checks exception is raised
deserialize(Resource, {"id": "42", "name": "wyfo"})
assert err.value.errors == [
{"loc": ["id"], "err": "badly formed hexadecimal UUID string"}
]
# Generate JSON Schema
assert deserialization_schema(Resource) == {
"$schema": "http://json-schema.org/draft/2020-12/schema#",
"type": "object",
"properties": {
"id": {"type": "string", "format": "uuid"},
"name": {"type": "string"},
"tags": {
"type": "array",
"items": {"type": "string"},
"uniqueItems": True,
"default": [],
},
},
"required": ["id", "name"],
"additionalProperties": False,
}# Define GraphQL operations
def resources(tags: Collection[str] | None = None) -> Collection[Resource] | None:
...# Generate GraphQL schema
schema = graphql_schema(query=[resources], id_types={UUID})
schema_str = """\
type Query {
resources(tags: [String!]): [Resource!]
}type Resource {
id: ID!
name: String!
tags: [String!]!
}"""
assert print_schema(schema) == schema_str
```
*apischema* works out of the box with your data model.> This example and further ones are using *pytest* API because they are in fact run as tests in the library CI
### Run the documentation examples
All documentation examples are written using the last Python minor version — currently 3.10 — in order to provide up-to-date documentation. Because Python 3.10 specificities (like [PEP 585](https://www.python.org/dev/peps/pep-0604/)) are used, this version is "mandatory" to execute the examples as-is.
In addition to *pytest*, some examples use third-party libraries like *SQLAlchemy* or *attrs*. All of this dependencies can be downloaded using the `examples` extra with
```shell
pip install apischema[examples]
```Once dependencies are installed, you can simply copy-paste examples and execute them, using the proper Python version.