# 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_fieldsuses FunDI dependency injection under the hood. Allgetterfunctions 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)
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.6.tar.gz
(25.7 kB
view details)
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file kat_transform-0.0.6.tar.gz.
File metadata
- Download URL: kat_transform-0.0.6.tar.gz
- Upload date:
- Size: 25.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
uv/0.7.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5d75267fcabab4af2ad435ee4a2459e05dd8a9f09991ab242f14f2d5b5c560bf
|
|
| MD5 |
b590fbf49c8e9f6a2d395d1373049423
|
|
| BLAKE2b-256 |
b49cc30dbfc531772c17864e38a6caa36d41f644d7b19e47a5104c60aa29cddf
|
File details
Details for the file kat_transform-0.0.6-py3-none-any.whl.
File metadata
- Download URL: kat_transform-0.0.6-py3-none-any.whl
- Upload date:
- Size: 20.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
uv/0.7.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
78db373a0d4f60e6021f397aff6347216c63a4e8b347015c1baf8e8d286c1fb3
|
|
| MD5 |
466c3ade7af8b893fa7b3da071b81b2e
|
|
| BLAKE2b-256 |
bbe516a2a1bb8df4e8bd575d163be5685641a615e6597514d947d6b045000c82
|