{"id":18834884,"url":"https://github.com/kapicorp/kadet","last_synced_at":"2026-02-06T18:09:55.828Z","repository":{"id":46834845,"uuid":"337861234","full_name":"kapicorp/kadet","owner":"kapicorp","description":"Easily define and reuse complex Python objects that serialize into JSON or YAML","archived":false,"fork":false,"pushed_at":"2024-07-15T19:40:45.000Z","size":111,"stargazers_count":25,"open_issues_count":6,"forks_count":4,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-07-06T23:16:11.827Z","etag":null,"topics":["json","kapitan","python","yaml"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kapicorp.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSES/Apache-2.0.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-02-10T21:40:39.000Z","updated_at":"2024-09-06T07:56:51.000Z","dependencies_parsed_at":"2024-11-08T02:14:21.056Z","dependency_job_id":"8763c541-8bcc-4ce8-b05d-f98288e07670","html_url":"https://github.com/kapicorp/kadet","commit_stats":{"total_commits":47,"total_committers":5,"mean_commits":9.4,"dds":0.1063829787234043,"last_synced_commit":"b34e78043cb04f0a272f426eb31b7a4821daf5d1"},"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"purl":"pkg:github/kapicorp/kadet","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kapicorp%2Fkadet","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kapicorp%2Fkadet/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kapicorp%2Fkadet/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kapicorp%2Fkadet/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kapicorp","download_url":"https://codeload.github.com/kapicorp/kadet/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kapicorp%2Fkadet/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":265578046,"owners_count":23791280,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["json","kapitan","python","yaml"],"created_at":"2024-11-08T02:14:10.624Z","updated_at":"2026-02-06T18:09:50.785Z","avatar_url":"https://github.com/kapicorp.png","language":"Python","funding_links":[],"categories":["Configuration Management"],"sub_categories":[],"readme":"# kadet\n\nEasily define and reuse complex Python objects that serialize into JSON or YAML.\n\n![GitHub Workflow Status](https://img.shields.io/github/workflow/status/kapicorp/kadet/Python%20lint%20and%20tests)\n\n## Example\n\n```python\nfrom kadet import BaseObj\nfrom pprint import pprint\n\nships = BaseObj()\nships.root.type.container = [\"panamax\", \"suezmax\", \"post-panamax\"]\nships.root.type.carrier = [\"conventional\", \"geared\", \"gearless\"]\nships.root.type.tanker = BaseObj.from_yaml(\"tankers.yml\")\n\npprint(ships.root)\n\n# output\n{'type': {'carrier': ['conventional',\n                      'geared',\n                      'gearless'],\n          'container': ['panamax',\n                        'suezmax',\n                        'post-panamax'],\n          'tanker': ['oil', 'liquified-gas', 'chemical']}}\n```\n\n## Installation\n\nInstall using `pip install kadet`.\n\n## Overview\n\n### BaseObj\n\nBaseObj implements the basic object that serializes into JSON or YAML.\nSetting keys in `self.root` means they will be serialized. Keys can be set as an hierarchy of attributes.\n\nThe `self.body()` method is reserved for setting self.root on instantiation.\n\nThe example below:\n\n```python\nclass MyApp(BaseObj):\n  def body(self):\n    self.root.name = \"myapp\"\n    self.root.inner.foo = \"bar\"\n    self.root.list = [1, 2, 3]\n\nyaml.dump(MyApp().dump())\n```\n\nserializes into:\n\n```yaml\n---\nname: myapp\ninner:\n  foo: bar\nlist:\n  - 1\n  - 2\n  - 3\n```\n\nThe `self.new()` method can be used to define a basic constructor.\n\n`self.need()` checks if a key is set and errors if it isn't (with an optional custom error message).\n`self.optional()` sets a key as optional. Use `default` keyword to set default value when not set.\n\nBoth `self.new()` and `self.body()` method accept the `istype` keyword to validate value type on runtime.\nSupports `typing` types.\n\n`kwargs` that are passed onto a new instance of BaseObj are always accessible via `self.kwargs`\n\n`self.new_with()` is an utility method to call `super().new()` while passing kwargs to the super class.\n\nIn this example, MyApp needs `name` and `foo` to be passed as kwargs.\n\n```python\nclass MyApp(BaseObj):\n  def new(self):\n    self.need(\"name\")\n    self.need(\"foo\", msg=\"please provide a value for foo\")\n    self.optional(\"baz\")\n\n  def body(self):\n    self.root.name = self.kwargs.name\n    self.root.inner.foo = self.kwargs.foo\n    self.root.list = [1, 2, 3]\n\nobj = MyApp(name=\"myapp\", foo=\"bar\")\n```\n\n### Setting a skeleton\n\nDefining a large body with Python can be quite hard and repetitive to read and write.\n\nThe `self.root_file()` method allows importing a YAML/JSON file to set `self.root`.\n\nMyApp's skeleton can be set instead like this:\n\n```yaml\n#skel.yml\n---\nname: myapp\ninner:\n  foo: bar\nlist:\n  - 1\n  - 2\n  - 3\n```\n\n```python\nclass MyApp(BaseObj):\n  def new(self):\n    self.need(\"name\")\n    self.need(\"foo\", msg=\"please provide a value for foo\")\n    self.root_file(\"path/to/skel.yml\")\n```\n\nExtending a MyApp's skeleton is possible just by implementing `self.body()`:\n\n```python\nclass MyApp(BaseObj):\n  def new(self):\n    self.need(\"name\")\n    self.need(\"foo\", msg=\"please provide a value for foo\")\n    self.root_file(\"path/to/skel.yml\")\n\n  def body(self):\n    self.set_replicas()\n    self.root.metadata.labels = {\"app\": \"mylabel\"}\n\n  def set_replicas(self):\n    self.root.spec.replicas = 5\n```\n\n### Inheritance\n\nPython inheritance will work as expected:\n\n```python\n\nclass MyOtherApp(MyApp):\n  def new(self):\n    super().new()  # MyApp's new()\n    self.need(\"size\")\n\n  def body(self):\n    super().body()  #  we want to extend MyApp's body\n    self.root.size = self.kwargs.size\n    del self.root.list  # get rid of \"list\"\n\nobj = MyOtherApp(name=\"otherapp1\", foo=\"bar2\", size=3)\nyaml.dump(obj.dump())\n```\nserializes to:\n\n```yaml\n---\nname: otherapp1\ninner:\n  foo: bar2\nreplicas: 5\nsize: 3\n```\n\n### BaseModel\n\nBaseModel integrates Kadet semantics with [Pydantic](https://github.com/pydantic/pydantic)'s BaseModel together with powerful data validation and type hinting features.\nJust 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`.\n\nThe `self.body()` method is reserved for setting self.root on instantiation.\n\nThe example below:\n\n```python\nclass Boat(BaseModel):\n  name: str  # Required\n  length: int  # Required\n  description: str = \"I am a boat\"  # Default description\n\n  def body(self):\n    self.root.name = self.name\n    self.root.details.length = self.length\n    self.root.details.description = self.description\n\nprint(yaml.dump(Boat(name=\"Boaty\", length=600).dump()))\n\n---\ndetails:\n  description: I am a boat\n  length: 600\nname: Boaty\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkapicorp%2Fkadet","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkapicorp%2Fkadet","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkapicorp%2Fkadet/lists"}