Skip to main content

Transform python data using declarative schemas

Project description

# kat-transform

Kittie's attempt to declaratively transform Python objects into serializable dictionaries. Minimal, composable, Pydantic-free. Just fields, dataclasses, and a pinch of magic.

Features

  • Declarative schema definition
  • Field-level transformation
  • Nested schemas
  • Dependency-injected getters via FunDI
  • No runtime overhead, no metaclasses, no opinionated data modeling
  • Multiple getters(with fallback: "created_at" -> "created")
  • Custom field metadata and schema metadata

Basic Usage:

from dataclasses import dataclass
from datetime import datetime

from kat_transform import schema, field, transform

user_schema = schema(
    "User",
    field(str, "username"),
    field(int, "id")
)

@dataclass
class User:
    username: str,
    id: int

user = User("Kuyugama", -1)

raw = user_schema.get(user)
transformed = transform(raw)

assert transformed == {"username": "Kuyugama", "id": -1}

print(transformed)

Deep dive

Transform on the Fly

from dataclasses import dataclass
from datetime import datetime

from kat_transform import schema, field, transform

user_schema = schema(
    "User",
    field(str, "username", transform=lambda x: x.lower()),
    field(int, "created", transform=lambda x: int(x.timestamp()), getter=("created_at", "created")),
    field(int, "id")
)

@dataclass
class User:
    username: str,
    created_at: datetime
    id: int

user = User("Kuyugama", datetime(day=17, month=3, year=2026), -1)

raw = user_schema.get(user)
transformed = transform(raw)

assert transformed == {"username": "kuyugama", "created": 1773612000, "id": -1}

print(transformed)

DI-based getters (aka fields from the void)

from dataclasses import dataclass
from datetime import datetime

from kat_transform import schema, field, resolve_fields, transform

error_schema = schema(
    "Error",
    field(str, "message"),
    field(str, "category"),
    field(str, "code"),
    field(str, "cat", transform=lambda x: f"https://http.cat/{x}", getter=lambda response: response["status_code"])
)

@dataclass
class Error:
    message: str
    category: str
    code: str

error = Error("User not found", "users", "not-found")

raw = error_schema.get(error)

resolved = resolve_fields({"response": {"status_code": 404}}, raw)

transformed = transform(resolved)

assert transformed == {"message": "User not found", "category": "users", "code": "not-found", "cat": "https://http.cat/404"}

print(transformed)

resolve_fields uses FunDI dependency injection under the hood. All getter functions should be valid FunDI dependencies.

Nested schemas? Awww, gotcha!

from dataclasses import dataclass
from datetime import datetime

from kat_transform import schema, field, resolve_fields, transform

user_schema = schema(
    "User",
    field(str, "username", transform=lambda x: x.lower()),
    field(int, "id"),
)

content_schema = schema(
    "Content",
    field(user_schema, "owner"),
    field(str, "title", transform=lambda x: x.title()),
)


@dataclass
class User:
    username: str
    id: int


@dataclass
class Content:
  owner: User
  title: str


user = User("Kuyugama", 1)

content = Content(user, "Clever flower")

raw = content_schema.get(content)

transformed = transform(raw)

assert transformed == {"owner": {"username": "kuyugama", "id": 1}, "title": "Clever Flower"}

print(transformed)

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

kat_transform-0.0.4.tar.gz (149.5 kB view details)

Uploaded Source

Built Distribution

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

kat_transform-0.0.4-py3-none-any.whl (20.0 kB view details)

Uploaded Python 3

File details

Details for the file kat_transform-0.0.4.tar.gz.

File metadata

  • Download URL: kat_transform-0.0.4.tar.gz
  • Upload date:
  • Size: 149.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.7.9

File hashes

Hashes for kat_transform-0.0.4.tar.gz
Algorithm Hash digest
SHA256 3715d6bf493e7cd2794a5161b9f4b5a24597b2fc620a02f3638449c977f7473d
MD5 b876871409f17f6bd17bcac2ddb0ef20
BLAKE2b-256 8c3611595c2fb3e4a4ca2878f5fe69a756c75f2f8b1acfbd0939637977517eca

See more details on using hashes here.

File details

Details for the file kat_transform-0.0.4-py3-none-any.whl.

File metadata

File hashes

Hashes for kat_transform-0.0.4-py3-none-any.whl
Algorithm Hash digest
SHA256 3d9fa25e4af96a862a15f065bf7311918960eafda158565f3edcb4af66fe3138
MD5 4572c3fd651659d7ff68369aada66832
BLAKE2b-256 9420c85b4ec1a789bb91423ffde0df00eddf13b21135f81dc66642b4d81c6aab

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