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

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 = user_schema.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

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 = user_schema.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

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 = error_schema.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

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 = content_schema.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.1.tar.gz (32.4 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.1-py3-none-any.whl (19.3 kB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for kat_transform-0.0.1.tar.gz
Algorithm Hash digest
SHA256 2efdf00c8c3689d26bc55945b11e20169212299b50b666bb827d1e6a536b418c
MD5 cf446b6b9426d22f3deb9b750ceb2aa4
BLAKE2b-256 d8e14211bf7f2c76019cd1a471fdd0b7eb963548a494bccbdaf560bd205ddc75

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for kat_transform-0.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 33f51e77d261b2f2df884b67bc8df7560e2d8323278de7ccb23889cbe67122a7
MD5 1302f91ad6a83b88df2b229c5f010b2f
BLAKE2b-256 6721eea883479749bdd5042ed6dc8ea3e58437b31b576843a0b90f587bc775af

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