# 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)
Metadata
Release files for kat-transform 0.0.6
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| kat_transform-0.0.6.tar.gz | 25.7 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| kat_transform-0.0.6-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 46.1 kB
Release files / kat_transform-0.0.6.tar.gz
| Download URL | kat_transform-0.0.6.tar.gz |
|---|---|
| Size | 25.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
5d75267fcabab4af2ad435ee4a2459e05dd8a9f09991ab242f14f2d5b5c560bf
|
|
BLAKE2b-256 checksum How to use checksums |
b49cc30dbfc531772c17864e38a6caa36d41f644d7b19e47a5104c60aa29cddf
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.7.14
|
Release files / kat_transform-0.0.6-py3-none-any.whl
| Download URL | kat_transform-0.0.6-py3-none-any.whl |
|---|---|
| Size | 20.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
78db373a0d4f60e6021f397aff6347216c63a4e8b347015c1baf8e8d286c1fb3
|
|
BLAKE2b-256 checksum How to use checksums |
bbe516a2a1bb8df4e8bd575d163be5685641a615e6597514d947d6b045000c82
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.7.14
|
Security for kat-transform 0.0.6
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.