schemantic


Nameschemantic JSON
Version 1.0.0 PyPI version JSON
download
home_page
SummaryManipulate model schemas utilizing homologous, grouped, or cultured paradigms
upload_time2023-10-02 15:34:11
maintainer
docs_urlNone
authorcaniko
requires_python>=3.10,<4.0
licenseBSD-4
keywords
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # Schemantic

Create schemas from models or classes with homologous, grouped, or cultured paradigms.

Best with `pydantic.BaseModel` instances, but works with any Python class and `dataclass`/`pydantic.dataclass`!

## Classes of schemas

### Homolog
```python
from pydantic import BaseModel
from ordered_set import OrderedSet
from schemantic.schema import HomologSchema

class Thief(BaseModel):
    stolen_goods: int
    steals_only: str

my_homolog = HomologSchema.from_model(Thief, instance_names=OrderedSet(["copycat", "pink_panther"]))
```

### Grouped
You can manage multiple schemas as a group:

```python
from pydantic import BaseModel
from schemantic.schema import GroupSchema

class Baker(BaseModel):
    baked_goods: int
    citizen_of: str

class Cop(BaseModel):
    years_of_service: int
    citizen_of: str

group_schema = GroupSchema.from_originating_types([Baker, Cop], )
```

### Culture
You can also manage multiple types of schemas under one culture:

```python
from ordered_set import OrderedSet
from schemantic.schema import CultureSchema

CultureSchema(source_schemas=OrderedSet([homolog_schema, group_schema]))
```

## Methods
`HomologSchema`, `GroupSchema`, and `CultureSchema` have the following methods.

### `.schema()`
Creates a dictionary, which represents the schema of the origin class/model.

```python
my_homolog.schema()
```
Output:
```yaml
"class_name": "Thief"
"common": {
    steals_only: "jewelry"
}
"copycat": {}
"pink_panther": {}
"required": ["stolen_goods", "steals_only"]
"field_to_info": {"stolen_goods": "integer"}
```

### `.dump()`
Dump the dictionary from `.schema()` to a yaml or toml file.
```python
my_schema.dump("my/path/schema.yaml")
# There is also toml support
my_schema.dump("my/path/schema.toml")
```

### `.parse()`
```yaml
"class_name": "Thief"
"common": {
    steals_only: "jewelry"
}
"copycat": {
    stolen_goods: 10
}
"pink_panther": {
    stolen_goods: 14
}
"required": ["stolen_goods", "steals_only"]
"field_to_info": {"stolen_goods": "integer"}
```
```python
parsed = my_homolog.parse_schema("my/path/schema.yaml")

# parsed["copycat"].stolen_goods == 10
# parsed["pink_panther"].stolen_goods == 14

# Both -> steals_only == "jewelry"
```

## Class configuration
Use `schemantic.project` module to control schemantic processing from the origin class/model side.

Classes and dataclasses
```python
from dataclasses import dataclass
from typing import Optional, Union

from schemantic.project import SchemanticProjectMixin


@dataclass
class TestDataclass(SchemanticProjectMixin):
    must_be: int
    we: str = "n"

    n: None = None
    age: Optional[int] = None
    new_age: Union[int, str, None] = None

    exclude_me: Optional[int] = None
    _exclude_me_too: Optional[float] = None

    @classmethod
    @property
    def fields_to_exclude_from_single_schema(cls) -> set[str]:
        upstream = super().fields_to_exclude_from_single_schema
        upstream.update(("exclude_me",))
        return upstream
```

This will exclude `exclude_me` (defined in `fields_to_exclude_from_single_schema`) and `_exclude_me_too` (private).

Same for `pydantic.BaseModel`:
```python
from typing import Optional, Union

from pydantic import BaseModel, computed_field

from schemantic.project import SchemanticProjectModelMixin


class TestModel(SchemanticProjectModelMixin, BaseModel):
    must_be: int
    we: str = "n"

    n: None = None
    age: Optional[int] = None
    new_age: Union[int, str, None] = None

    exclude_me: Optional[int] = None
    _exclude_me_too: Optional[float] = None

    @classmethod  # type: ignore[misc]
    @computed_field(return_type=set[str])
    @property
    def fields_to_exclude_from_single_schema(cls) -> set[str]:
        upstream = super().fields_to_exclude_from_single_schema
        upstream.update(("exclude_me",))
        return upstream
```

### Install
```shell
pip install schemantic
```

For `toml` or `yaml` dumping and parsing
```shell
pip install schemantic[toml]
pip install schemantic[yaml]
```

            

Raw data

            {
    "_id": null,
    "home_page": "",
    "name": "schemantic",
    "maintainer": "",
    "docs_url": null,
    "requires_python": ">=3.10,<4.0",
    "maintainer_email": "",
    "keywords": "",
    "author": "caniko",
    "author_email": "python@rotas.mozmail.com",
    "download_url": "https://files.pythonhosted.org/packages/13/fd/bbc07ce3feeb590af1fd4c6779d779e7bf4832ec3172475379b0f30d4780/schemantic-1.0.0.tar.gz",
    "platform": null,
    "description": "# Schemantic\n\nCreate schemas from models or classes with homologous, grouped, or cultured paradigms.\n\nBest with `pydantic.BaseModel` instances, but works with any Python class and `dataclass`/`pydantic.dataclass`!\n\n## Classes of schemas\n\n### Homolog\n```python\nfrom pydantic import BaseModel\nfrom ordered_set import OrderedSet\nfrom schemantic.schema import HomologSchema\n\nclass Thief(BaseModel):\n    stolen_goods: int\n    steals_only: str\n\nmy_homolog = HomologSchema.from_model(Thief, instance_names=OrderedSet([\"copycat\", \"pink_panther\"]))\n```\n\n### Grouped\nYou can manage multiple schemas as a group:\n\n```python\nfrom pydantic import BaseModel\nfrom schemantic.schema import GroupSchema\n\nclass Baker(BaseModel):\n    baked_goods: int\n    citizen_of: str\n\nclass Cop(BaseModel):\n    years_of_service: int\n    citizen_of: str\n\ngroup_schema = GroupSchema.from_originating_types([Baker, Cop], )\n```\n\n### Culture\nYou can also manage multiple types of schemas under one culture:\n\n```python\nfrom ordered_set import OrderedSet\nfrom schemantic.schema import CultureSchema\n\nCultureSchema(source_schemas=OrderedSet([homolog_schema, group_schema]))\n```\n\n## Methods\n`HomologSchema`, `GroupSchema`, and `CultureSchema` have the following methods.\n\n### `.schema()`\nCreates a dictionary, which represents the schema of the origin class/model.\n\n```python\nmy_homolog.schema()\n```\nOutput:\n```yaml\n\"class_name\": \"Thief\"\n\"common\": {\n    steals_only: \"jewelry\"\n}\n\"copycat\": {}\n\"pink_panther\": {}\n\"required\": [\"stolen_goods\", \"steals_only\"]\n\"field_to_info\": {\"stolen_goods\": \"integer\"}\n```\n\n### `.dump()`\nDump the dictionary from `.schema()` to a yaml or toml file.\n```python\nmy_schema.dump(\"my/path/schema.yaml\")\n# There is also toml support\nmy_schema.dump(\"my/path/schema.toml\")\n```\n\n### `.parse()`\n```yaml\n\"class_name\": \"Thief\"\n\"common\": {\n    steals_only: \"jewelry\"\n}\n\"copycat\": {\n    stolen_goods: 10\n}\n\"pink_panther\": {\n    stolen_goods: 14\n}\n\"required\": [\"stolen_goods\", \"steals_only\"]\n\"field_to_info\": {\"stolen_goods\": \"integer\"}\n```\n```python\nparsed = my_homolog.parse_schema(\"my/path/schema.yaml\")\n\n# parsed[\"copycat\"].stolen_goods == 10\n# parsed[\"pink_panther\"].stolen_goods == 14\n\n# Both -> steals_only == \"jewelry\"\n```\n\n## Class configuration\nUse `schemantic.project` module to control schemantic processing from the origin class/model side.\n\nClasses and dataclasses\n```python\nfrom dataclasses import dataclass\nfrom typing import Optional, Union\n\nfrom schemantic.project import SchemanticProjectMixin\n\n\n@dataclass\nclass TestDataclass(SchemanticProjectMixin):\n    must_be: int\n    we: str = \"n\"\n\n    n: None = None\n    age: Optional[int] = None\n    new_age: Union[int, str, None] = None\n\n    exclude_me: Optional[int] = None\n    _exclude_me_too: Optional[float] = None\n\n    @classmethod\n    @property\n    def fields_to_exclude_from_single_schema(cls) -> set[str]:\n        upstream = super().fields_to_exclude_from_single_schema\n        upstream.update((\"exclude_me\",))\n        return upstream\n```\n\nThis will exclude `exclude_me` (defined in `fields_to_exclude_from_single_schema`) and `_exclude_me_too` (private).\n\nSame for `pydantic.BaseModel`:\n```python\nfrom typing import Optional, Union\n\nfrom pydantic import BaseModel, computed_field\n\nfrom schemantic.project import SchemanticProjectModelMixin\n\n\nclass TestModel(SchemanticProjectModelMixin, BaseModel):\n    must_be: int\n    we: str = \"n\"\n\n    n: None = None\n    age: Optional[int] = None\n    new_age: Union[int, str, None] = None\n\n    exclude_me: Optional[int] = None\n    _exclude_me_too: Optional[float] = None\n\n    @classmethod  # type: ignore[misc]\n    @computed_field(return_type=set[str])\n    @property\n    def fields_to_exclude_from_single_schema(cls) -> set[str]:\n        upstream = super().fields_to_exclude_from_single_schema\n        upstream.update((\"exclude_me\",))\n        return upstream\n```\n\n### Install\n```shell\npip install schemantic\n```\n\nFor `toml` or `yaml` dumping and parsing\n```shell\npip install schemantic[toml]\npip install schemantic[yaml]\n```\n",
    "bugtrack_url": null,
    "license": "BSD-4",
    "summary": "Manipulate model schemas utilizing homologous, grouped, or cultured paradigms",
    "version": "1.0.0",
    "project_urls": null,
    "split_keywords": [],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "4acdab6daebd11e76296ab7c4523089a5c3052e7fa173e1650d6e26a33c6787a",
                "md5": "706c7884aee696bdc86a20e60cd13784",
                "sha256": "d6d72358dc5e20dfb198596c05ce84d0676ab9ad9b340d868b22e16334340868"
            },
            "downloads": -1,
            "filename": "schemantic-1.0.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "706c7884aee696bdc86a20e60cd13784",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.10,<4.0",
            "size": 14779,
            "upload_time": "2023-10-02T15:34:09",
            "upload_time_iso_8601": "2023-10-02T15:34:09.296615Z",
            "url": "https://files.pythonhosted.org/packages/4a/cd/ab6daebd11e76296ab7c4523089a5c3052e7fa173e1650d6e26a33c6787a/schemantic-1.0.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "13fdbbc07ce3feeb590af1fd4c6779d779e7bf4832ec3172475379b0f30d4780",
                "md5": "3504f578a6578b671950174c6a8e7b4c",
                "sha256": "a3409295b6a590d4c42d9e25ff9114977552a773098a210f5030567f55d01f7d"
            },
            "downloads": -1,
            "filename": "schemantic-1.0.0.tar.gz",
            "has_sig": false,
            "md5_digest": "3504f578a6578b671950174c6a8e7b4c",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.10,<4.0",
            "size": 12350,
            "upload_time": "2023-10-02T15:34:11",
            "upload_time_iso_8601": "2023-10-02T15:34:11.012737Z",
            "url": "https://files.pythonhosted.org/packages/13/fd/bbc07ce3feeb590af1fd4c6779d779e7bf4832ec3172475379b0f30d4780/schemantic-1.0.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2023-10-02 15:34:11",
    "github": false,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "lcname": "schemantic"
}
        
Elapsed time: 0.12554s