typical


Nametypical JSON
Version 2.8.1 PyPI version JSON
download
home_pagehttps://github.com/seandstewart/typical
SummaryTypical: Python's Typing Toolkit.
upload_time2023-04-26 17:04:18
maintainer
docs_urlNone
authorSean Stewart
requires_python>=3.7,<4.0
licenseMIT
keywords typing data annotations validation json-schema
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage
            # typical: Python's Typing Toolkit
[![image](https://img.shields.io/pypi/v/typical.svg)](https://pypi.org/project/typical/)
[![image](https://img.shields.io/pypi/l/typical.svg)](https://pypi.org/project/typical/)
[![image](https://img.shields.io/pypi/pyversions/typical.svg)](https://pypi.org/project/typical/)
[![image](https://img.shields.io/github/languages/code-size/seandstewart/typical.svg?style=flat)](https://github.com/seandstewart/typical)
[![Test & Lint](https://github.com/seandstewart/typical/workflows/Test%20&%20Lint/badge.svg)](https://github.com/seandstewart/typical/actions)
[![Coverage](https://codecov.io/gh/seandstewart/typical/branch/master/graph/badge.svg)](https://codecov.io/gh/seandstewart/typical)
[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/ambv/black)
[![Netlify Status](https://api.netlify.com/api/v1/badges/982a0ced-bb7f-4391-87e8-1957071d2f66/deploy-status)](https://app.netlify.com/sites/typical-python/deploys)

![How Typical](static/typical.png)

## Introduction

Typical is a library devoted to runtime analysis, inference,
validation, and enforcement of Python types,
[PEP 484](https://www.python.org/dev/peps/pep-0484/) Type Hints, and
custom user-defined data-types.

Typical is fully compliant with the following Python Typing PEPs:

- [PEP 484 -- Type Hints](https://www.python.org/dev/peps/pep-0484/)
- [PEP 563 -- Postponed Evaluation of Annotations](https://www.python.org/dev/peps/pep-0563/)
- [PEP 585 -- Type Hinting Generics In Standard Collections](https://www.python.org/dev/peps/pep-0585/)
- [PEP 586 -- Literal Types](https://www.python.org/dev/peps/pep-0586/)
- [PEP 589 -- TypedDict: Type Hints for Dictionaries with a Fixed Set of Keys](https://www.python.org/dev/peps/pep-0589/)
- [PEP 604 -- Allow writing union types as X | Y](https://www.python.org/dev/peps/pep-0604/)

It provides a high-level Protocol API, Functional API, and Object API to suit most any
occasion.

## Getting Started

Installation is as simple as `pip install -U typical`.
## Help

The latest documentation is hosted at
[python-typical.org](https://python-typical.org/).

> Starting with version 2.0, All documentation is hand-crafted
> markdown & versioned documentation can be found at typical's
> [Git Repo](https://github.com/seandstewart/typical/tree/master/docs).
> (Versioned documentation is still in-the-works directly on our
> domain.)

## A Typical Use-Case

The decorator that started it all:

### `typic.al(...)`

```python
import typic


@typic.al
def hard_math(a: int, b: int, *c: int) -> int:
    return a + b + sum(c)

hard_math(1, "3")
#> 4


@typic.al(strict=True)
def strict_math(a: int, b: int, *c: int) -> int:
    return a + b + sum(c)

strict_math(1, 2, 3, "4")
#> Traceback (most recent call last):
#>  ...
#> typic.constraints.error.ConstraintValueError: Given value <'4'> fails constraints: (type=int, nullable=False, coerce=False)
  
```

Typical has both a high-level *Object API* and high-level
*Functional API*. In general, any method registered to one API is also
available to the other.

### The Protocol API

```python
import dataclasses
from typing import Iterable

import typic


@typic.constrained(ge=1)
class ID(int):
    ...


@typic.constrained(max_length=280)
class Tweet(str):
    ...


@dataclasses.dataclass # or typing.TypedDict or typing.NamedTuple or annotated class...
class Tweeter:
    id: ID
    tweets: Iterable[Tweet]


json = '{"id":1,"tweets":["I don\'t understand Twitter"]}'
protocol = typic.protocol(Tweeter)

t = protocol.transmute(json)
print(t)
#> Tweeter(id=1, tweets=["I don't understand Twitter"])

print(protocol.tojson(t))
#> '{"id":1,"tweets":["I don\'t understand Twitter"]}'

protocol.validate({"id": 0, "tweets": []})
#> Traceback (most recent call last):
#>  ...
#> typic.constraints.error.ConstraintValueError: Tweeter.id: value <0> fails constraints: (type=int, nullable=False, coerce=False, ge=1)
```

### The Functional API

```python
import dataclasses
from typing import Iterable

import typic


@typic.constrained(ge=1)
class ID(int):
    ...


@typic.constrained(max_length=280)
class Tweet(str):
    ...


@dataclasses.dataclass # or typing.TypedDict or typing.NamedTuple or annotated class...
class Tweeter:
    id: ID
    tweets: Iterable[Tweet]


json = '{"id":1,"tweets":["I don\'t understand Twitter"]}'

t = typic.transmute(Tweeter, json)
print(t)
#> Tweeter(id=1, tweets=["I don't understand Twitter"])

print(typic.tojson(t))
#> '{"id":1,"tweets":["I don\'t understand Twitter"]}'

typic.validate(Tweeter, {"id": 0, "tweets": []})
#> Traceback (most recent call last):
#>  ...
#> typic.constraints.error.ConstraintValueError: Tweeter.id: value <0> fails constraints: (type=int, nullable=False, coerce=False, ge=1)
```

### The Object API

```python
from typing import Iterable

import typic


@typic.constrained(ge=1)
class ID(int):
    ...


@typic.constrained(max_length=280)
class Tweet(str):
    ...


@typic.klass
class Tweeter:
    id: ID
    tweets: Iterable[Tweet]
    

json = '{"id":1,"tweets":["I don\'t understand Twitter"]}'
t = Tweeter.transmute(json)

print(t)
#> Tweeter(id=1, tweets=["I don't understand Twitter"])

print(t.tojson())
#> '{"id":1,"tweets":["I don\'t understand Twitter"]}'

Tweeter.validate({"id": 0, "tweets": []})
#> Traceback (most recent call last):
#>  ...
#> typic.constraints.error.ConstraintValueError: Given value <0> fails constraints: (type=int, nullable=False, coerce=False, ge=1)
```


## Changelog

See our
[Releases](https://github.com/seandstewart/typical/releases).

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/seandstewart/typical",
    "name": "typical",
    "maintainer": "",
    "docs_url": null,
    "requires_python": ">=3.7,<4.0",
    "maintainer_email": "",
    "keywords": "typing,data,annotations,validation,json-schema",
    "author": "Sean Stewart",
    "author_email": "sean_stewart@me.com",
    "download_url": "https://files.pythonhosted.org/packages/c4/dd/76c8fc5d054235f942f492c3761a72fd7a79592e03bbae6930b345a09491/typical-2.8.1.tar.gz",
    "platform": null,
    "description": "# typical: Python's Typing Toolkit\n[![image](https://img.shields.io/pypi/v/typical.svg)](https://pypi.org/project/typical/)\n[![image](https://img.shields.io/pypi/l/typical.svg)](https://pypi.org/project/typical/)\n[![image](https://img.shields.io/pypi/pyversions/typical.svg)](https://pypi.org/project/typical/)\n[![image](https://img.shields.io/github/languages/code-size/seandstewart/typical.svg?style=flat)](https://github.com/seandstewart/typical)\n[![Test & Lint](https://github.com/seandstewart/typical/workflows/Test%20&%20Lint/badge.svg)](https://github.com/seandstewart/typical/actions)\n[![Coverage](https://codecov.io/gh/seandstewart/typical/branch/master/graph/badge.svg)](https://codecov.io/gh/seandstewart/typical)\n[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/ambv/black)\n[![Netlify Status](https://api.netlify.com/api/v1/badges/982a0ced-bb7f-4391-87e8-1957071d2f66/deploy-status)](https://app.netlify.com/sites/typical-python/deploys)\n\n![How Typical](static/typical.png)\n\n## Introduction\n\nTypical is a library devoted to runtime analysis, inference,\nvalidation, and enforcement of Python types,\n[PEP 484](https://www.python.org/dev/peps/pep-0484/) Type Hints, and\ncustom user-defined data-types.\n\nTypical is fully compliant with the following Python Typing PEPs:\n\n- [PEP 484 -- Type Hints](https://www.python.org/dev/peps/pep-0484/)\n- [PEP 563 -- Postponed Evaluation of Annotations](https://www.python.org/dev/peps/pep-0563/)\n- [PEP 585 -- Type Hinting Generics In Standard Collections](https://www.python.org/dev/peps/pep-0585/)\n- [PEP 586 -- Literal Types](https://www.python.org/dev/peps/pep-0586/)\n- [PEP 589 -- TypedDict: Type Hints for Dictionaries with a Fixed Set of Keys](https://www.python.org/dev/peps/pep-0589/)\n- [PEP 604 -- Allow writing union types as X | Y](https://www.python.org/dev/peps/pep-0604/)\n\nIt provides a high-level Protocol API, Functional API, and Object API to suit most any\noccasion.\n\n## Getting Started\n\nInstallation is as simple as `pip install -U typical`.\n## Help\n\nThe latest documentation is hosted at\n[python-typical.org](https://python-typical.org/).\n\n> Starting with version 2.0, All documentation is hand-crafted\n> markdown & versioned documentation can be found at typical's\n> [Git Repo](https://github.com/seandstewart/typical/tree/master/docs).\n> (Versioned documentation is still in-the-works directly on our\n> domain.)\n\n## A Typical Use-Case\n\nThe decorator that started it all:\n\n### `typic.al(...)`\n\n```python\nimport typic\n\n\n@typic.al\ndef hard_math(a: int, b: int, *c: int) -> int:\n    return a + b + sum(c)\n\nhard_math(1, \"3\")\n#> 4\n\n\n@typic.al(strict=True)\ndef strict_math(a: int, b: int, *c: int) -> int:\n    return a + b + sum(c)\n\nstrict_math(1, 2, 3, \"4\")\n#> Traceback (most recent call last):\n#>  ...\n#> typic.constraints.error.ConstraintValueError: Given value <'4'> fails constraints: (type=int, nullable=False, coerce=False)\n  \n```\n\nTypical has both a high-level *Object API* and high-level\n*Functional API*. In general, any method registered to one API is also\navailable to the other.\n\n### The Protocol API\n\n```python\nimport dataclasses\nfrom typing import Iterable\n\nimport typic\n\n\n@typic.constrained(ge=1)\nclass ID(int):\n    ...\n\n\n@typic.constrained(max_length=280)\nclass Tweet(str):\n    ...\n\n\n@dataclasses.dataclass # or typing.TypedDict or typing.NamedTuple or annotated class...\nclass Tweeter:\n    id: ID\n    tweets: Iterable[Tweet]\n\n\njson = '{\"id\":1,\"tweets\":[\"I don\\'t understand Twitter\"]}'\nprotocol = typic.protocol(Tweeter)\n\nt = protocol.transmute(json)\nprint(t)\n#> Tweeter(id=1, tweets=[\"I don't understand Twitter\"])\n\nprint(protocol.tojson(t))\n#> '{\"id\":1,\"tweets\":[\"I don\\'t understand Twitter\"]}'\n\nprotocol.validate({\"id\": 0, \"tweets\": []})\n#> Traceback (most recent call last):\n#>  ...\n#> typic.constraints.error.ConstraintValueError: Tweeter.id: value <0> fails constraints: (type=int, nullable=False, coerce=False, ge=1)\n```\n\n### The Functional API\n\n```python\nimport dataclasses\nfrom typing import Iterable\n\nimport typic\n\n\n@typic.constrained(ge=1)\nclass ID(int):\n    ...\n\n\n@typic.constrained(max_length=280)\nclass Tweet(str):\n    ...\n\n\n@dataclasses.dataclass # or typing.TypedDict or typing.NamedTuple or annotated class...\nclass Tweeter:\n    id: ID\n    tweets: Iterable[Tweet]\n\n\njson = '{\"id\":1,\"tweets\":[\"I don\\'t understand Twitter\"]}'\n\nt = typic.transmute(Tweeter, json)\nprint(t)\n#> Tweeter(id=1, tweets=[\"I don't understand Twitter\"])\n\nprint(typic.tojson(t))\n#> '{\"id\":1,\"tweets\":[\"I don\\'t understand Twitter\"]}'\n\ntypic.validate(Tweeter, {\"id\": 0, \"tweets\": []})\n#> Traceback (most recent call last):\n#>  ...\n#> typic.constraints.error.ConstraintValueError: Tweeter.id: value <0> fails constraints: (type=int, nullable=False, coerce=False, ge=1)\n```\n\n### The Object API\n\n```python\nfrom typing import Iterable\n\nimport typic\n\n\n@typic.constrained(ge=1)\nclass ID(int):\n    ...\n\n\n@typic.constrained(max_length=280)\nclass Tweet(str):\n    ...\n\n\n@typic.klass\nclass Tweeter:\n    id: ID\n    tweets: Iterable[Tweet]\n    \n\njson = '{\"id\":1,\"tweets\":[\"I don\\'t understand Twitter\"]}'\nt = Tweeter.transmute(json)\n\nprint(t)\n#> Tweeter(id=1, tweets=[\"I don't understand Twitter\"])\n\nprint(t.tojson())\n#> '{\"id\":1,\"tweets\":[\"I don\\'t understand Twitter\"]}'\n\nTweeter.validate({\"id\": 0, \"tweets\": []})\n#> Traceback (most recent call last):\n#>  ...\n#> typic.constraints.error.ConstraintValueError: Given value <0> fails constraints: (type=int, nullable=False, coerce=False, ge=1)\n```\n\n\n## Changelog\n\nSee our\n[Releases](https://github.com/seandstewart/typical/releases).\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "Typical: Python's Typing Toolkit.",
    "version": "2.8.1",
    "project_urls": {
        "Homepage": "https://github.com/seandstewart/typical",
        "Repository": "https://github.com/seandstewart/typical"
    },
    "split_keywords": [
        "typing",
        "data",
        "annotations",
        "validation",
        "json-schema"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "b2ce9240da521ead90cbb805f05ef483de23c9b959e7e544a79a898d0fcb86ad",
                "md5": "b4e61687a6525bd88dae3942191148f9",
                "sha256": "c33f27e6b5a547d2c516e0ae42be4c690a7ee51b3849fcf08eab331c3232386b"
            },
            "downloads": -1,
            "filename": "typical-2.8.1-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "b4e61687a6525bd88dae3942191148f9",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.7,<4.0",
            "size": 107834,
            "upload_time": "2023-04-26T17:04:15",
            "upload_time_iso_8601": "2023-04-26T17:04:15.191053Z",
            "url": "https://files.pythonhosted.org/packages/b2/ce/9240da521ead90cbb805f05ef483de23c9b959e7e544a79a898d0fcb86ad/typical-2.8.1-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "c4dd76c8fc5d054235f942f492c3761a72fd7a79592e03bbae6930b345a09491",
                "md5": "56a488cb72fb8a594b4e0bc5bcb05f43",
                "sha256": "9d9a892ea78078a2b173508fdda4993d36eb989c3bded5300515ff100fe3d362"
            },
            "downloads": -1,
            "filename": "typical-2.8.1.tar.gz",
            "has_sig": false,
            "md5_digest": "56a488cb72fb8a594b4e0bc5bcb05f43",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.7,<4.0",
            "size": 90907,
            "upload_time": "2023-04-26T17:04:18",
            "upload_time_iso_8601": "2023-04-26T17:04:18.746205Z",
            "url": "https://files.pythonhosted.org/packages/c4/dd/76c8fc5d054235f942f492c3761a72fd7a79592e03bbae6930b345a09491/typical-2.8.1.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2023-04-26 17:04:18",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "seandstewart",
    "github_project": "typical",
    "travis_ci": false,
    "coveralls": true,
    "github_actions": true,
    "requirements": [],
    "lcname": "typical"
}
        
Elapsed time: 0.24275s