Skip to main content

Easily define and reuse complex Python objects that serialize into JSON or YAML.

Project description

kadet

Easily define and reuse complex Python objects that serialize into JSON or YAML.

GitHub Workflow Status

Example

from kadet import BaseObj
from pprint import pprint

ships = BaseObj()
ships.root.type.container = ["panamax", "suezmax", "post-panamax"]
ships.root.type.carrier = ["conventional", "geared", "gearless"]
ships.root.type.tanker = BaseObj.from_yaml("tankers.yml")

pprint(ships.root)

# output
{'type': {'carrier': ['conventional',
                      'geared',
                      'gearless'],
          'container': ['panamax',
                        'suezmax',
                        'post-panamax'],
          'tanker': ['oil', 'liquified-gas', 'chemical']}}

Installation

Install using pip install kadet.

Overview

BaseObj

BaseObj implements the basic object that serializes into JSON or YAML. Setting keys in self.root means they will be serialized. Keys can be set as an hierarchy of attributes.

The self.body() method is reserved for setting self.root on instantiation.

The example below:

class MyApp(BaseObj):
  def body(self):
    self.root.name = "myapp"
    self.root.inner.foo = "bar"
    self.root.list = [1, 2, 3]

yaml.dump(MyApp().dump())

serializes into:

---
name: myapp
inner:
  foo: bar
list:
  - 1
  - 2
  - 3

The self.new() method can be used to define a basic constructor.

self.need() checks if a key is set and errors if it isn't (with an optional custom error message). self.optional() sets a key as optional. Use default keyword to set default value when not set.

Both self.new() and self.body() method accept the istype keyword to validate value type on runtime. Supports typing types.

kwargs that are passed onto a new instance of BaseObj are always accessible via self.kwargs

self.new_with() is an utility method to call super().new() while passing kwargs to the super class.

In this example, MyApp needs name and foo to be passed as kwargs.

class MyApp(BaseObj):
  def new(self):
    self.need("name")
    self.need("foo", msg="please provide a value for foo")
    self.optional("baz")

  def body(self):
    self.root.name = self.kwargs.name
    self.root.inner.foo = self.kwargs.foo
    self.root.list = [1, 2, 3]

obj = MyApp(name="myapp", foo="bar")

Setting a skeleton

Defining a large body with Python can be quite hard and repetitive to read and write.

The self.root_file() method allows importing a YAML/JSON file to set self.root.

MyApp's skeleton can be set instead like this:

#skel.yml
---
name: myapp
inner:
  foo: bar
list:
  - 1
  - 2
  - 3
class MyApp(BaseObj):
  def new(self):
    self.need("name")
    self.need("foo", msg="please provide a value for foo")
    self.root_file("path/to/skel.yml")

Extending a MyApp's skeleton is possible just by implementing self.body():

class MyApp(BaseObj):
  def new(self):
    self.need("name")
    self.need("foo", msg="please provide a value for foo")
    self.root_file("path/to/skel.yml")

  def body(self):
    self.set_replicas()
    self.root.metadata.labels = {"app": "mylabel"}

  def set_replicas(self):
    self.root.spec.replicas = 5

Inheritance

Python inheritance will work as expected:

class MyOtherApp(MyApp):
  def new(self):
    super().new()  # MyApp's new()
    self.need("size")

  def body(self):
    super().body()  #  we want to extend MyApp's body
    self.root.size = self.kwargs.size
    del self.root.list  # get rid of "list"

obj = MyOtherApp(name="otherapp1", foo="bar2", size=3)
yaml.dump(obj.dump())

serializes to:

---
name: otherapp1
inner:
  foo: bar2
replicas: 5
size: 3

BaseModel

BaseModel integrates Kadet semantics with Pydantic's BaseModel together with powerful data validation and type hinting features. Just like in BaseObj, keys in self.root will be serialized, but kwargs is no longer necessary as BaseModel's parameters are set as attributes in self.

The self.body() method is reserved for setting self.root on instantiation.

The example below:

class Boat(BaseModel):
  name: str  # Required
  length: int  # Required
  description: str = "I am a boat"  # Default description

  def body(self):
    self.root.name = self.name
    self.root.details.length = self.length
    self.root.details.description = self.description

print(yaml.dump(Boat(name="Boaty", length=600).dump()))

---
details:
  description: I am a boat
  length: 600
name: Boaty

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

kadet-0.3.0.tar.gz (8.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

kadet-0.3.0-py3-none-any.whl (8.9 kB view details)

Uploaded Python 3

File details

Details for the file kadet-0.3.0.tar.gz.

File metadata

  • Download URL: kadet-0.3.0.tar.gz
  • Upload date:
  • Size: 8.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.8.2 CPython/3.12.2 Linux/6.5.0-1016-azure

File hashes

Hashes for kadet-0.3.0.tar.gz
Algorithm Hash digest
SHA256 babdf4cd2c5453920af2c1d060315793901317ea57bc17d1ad8a6440c633ebbc
MD5 6d487614c5c1a2c5ca8fc3bb998685a7
BLAKE2b-256 72bc9346ecc1eade4161cb0ac598f83636385f34e9ecc616012de8a1d67b3054

See more details on using hashes here.

File details

Details for the file kadet-0.3.0-py3-none-any.whl.

File metadata

  • Download URL: kadet-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 8.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.8.2 CPython/3.12.2 Linux/6.5.0-1016-azure

File hashes

Hashes for kadet-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 029d69edf1e1b33aac1e21a859e239728fce18b5f75600c794d3eb846b88dbbb
MD5 a50e264516ee850ebb87f4a31b9584ad
BLAKE2b-256 a0e94e7cccf8621559bfc6dac8c2293b613ff746c055932e8096002765c2c0bf

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page