Skip to content

Repository files navigation

Odin

Odin provides a declarative framework for defining resources (classes) and their relationships, validation of the fields that make up the resources and mapping between objects (either a resource, or other python structures).

Odin also comes with built in serialisation tools for importing and exporting data from resources.

Docs/HelpReadTheDocsGitter.im
BuildPython package
QualityMaintainabilitySecurityCoverageOnce you go Black...
PackageLatest VersionPyPI - Wheel

Highlights

  • Class based declarative style
  • Class based annotations style! ✨ new in 2.0
  • Fields for building composite resources
  • Field and Resource level validation
  • Easy extension to support custom fields
  • Python 3.8+ and PyPy 1 supported
  • Support for documenting resources with Sphinx
  • Minimal dependencies

1 certain contrib items are not supported. Pint is not installable with PyPy.

Use cases

  • Design, document and validate complex (and simple!) data structures
  • Convert structures to and from different formats such as JSON, YAML, MsgPack, CSV, TOML
  • Validate API inputs
  • Define message formats for communications protocols, like an RPC
  • Map API requests to ORM objects

Quick links

Upcoming features

In development

  • XML Codec (export only)
  • Complete documentation coverage
  • Improvements for CSV Codec (writing, reading multi resource CSV's)

Requires

Optional

  • simplejson - Odin will use simplejson if it is available or fallback to the builtin json library
  • msgpack-python - To enable use of the msgpack codec
  • pyyaml - To enable use of the YAML codec
  • toml - To enable use of the TOML codec

Contrib

  • arrow - Support for Arrow data types.
  • pint - Support for physical quantities using the Pint library.

Development

  • pytest - Testing
  • pytest-cov - Coverage reporting

Example

Definition

importodinclassAuthor(odin.Resource):
name=odin.StringField()
classPublisher(odin.Resource):
name=odin.StringField()
classBook(odin.Resource):
title=odin.StringField()
authors=odin.ArrayOf(Author)
publisher=odin.DictAs(Publisher)
genre=odin.StringField()
num_pages=odin.IntegerField()

Using Annotations

importodinclassAuthor(odin.AnnotatedResource):
name: strclassPublisher(odin.AnnotatedResource):
name: strwebsite: odin.Url|NoneclassBook(odin.AnnotatedResource):
title: strauthors: list[Author]
publisher: Publishergenre: strnum_pages: int

Usage

>>> b = Book(
title="Consider Phlebas",
genre="Space Opera",
publisher=Publisher(name="Macmillan"),
num_pages=471
)
>>> b.authors.append(Author(name="Iain M. Banks"))
>>> from odin.codecs import json_codec
>>> json_codec.dumps(b, indent=4)
{
"$": "Book",
"authors": [
{
"$": "Author",
"name": "Iain M. Banks"
}
],
"genre": "Space Opera",
"num_pages": 471,
"publisher": {
"$": "Publisher",
"name": "Macmillan"
},
"title": "Consider Phlebas"
}

About

Data-structure definition/validation/traversal, mapping and serialisation toolkit for Python

Topics

Resources

Stars

40 stars

Watchers

2 watching

Forks

Releases

Sponsor this project

Packages

Used by

Contributors

Languages