From Kyzo Python
Build the three boundary-crossing constructs — foreign model, contract model, ordered union — the only shapes for data crossing in or out of the program. Fires before touching a foreign payload, file format, message, or client reply; before declaring an API surface or response shape; or before writing a try/except, error handler, retry, fallback, or None-check around foreign input.
How this skill is triggered — by the user, by Claude, or both
Slash command
/kyzo-python:python-adapters-successThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
The boundary constructs: how data is trusted crossing in (foreign model, ordered union) and shaped crossing out (contract model). Distinct from `python-values-success`, whose constructs represent truth already inside the program.
The boundary constructs: how data is trusted crossing in (foreign model, ordered union) and shaped crossing out (contract model). Distinct from python-values-success, whose constructs represent truth already inside the program.
A frozen BaseModel of another system's data shape, named for the other system's thing: its aliases hold that system's keys, and its fields are this program's domain meanings. It exists only when the foreign shape differs from the domain shape, and it carries every field the program uses from the foreign data.
class VenueFill(BaseModel):
model_config = ConfigDict(frozen=True, extra="forbid", from_attributes=True)
order_id: OrderId = Field(alias="ordId")
account_id: AccountId = Field(alias="acct")
fill_price: Price = Field(alias="px")
filled_quantity: Quantity = Field(alias="qty")
class VenueFillMessage(BaseModel):
model_config = ConfigDict(frozen=True, extra="forbid")
fill: VenueFill = Field(validation_alias="data")
class VenueStreamMessage(BaseModel):
model_config = ConfigDict(frozen=True, extra="forbid")
fill: VenueFill = Field(validation_alias=AliasPath("data", "payload"))
The declarative inventory: Field(alias=...) for a key rename, validation_alias for data wrapped at one key, AliasPath for data under nested wrapper keys, nested foreign models for nested structure, from_attributes=True for objects, model_validate_json for serialized data.
If the foreign shape already matches the domain model, construct the domain model directly; the constructor does the entire job and no foreign model exists. This program's own API shape is a contract model, never a foreign model. Foreign data that carries no identity and is expected to fail constructs through the ordered union. A live client is held by the consistency model, never on a foreign model.
A mapper, adapter, translator, DTO, or field-copying function restates work the constructor owns: the foreign model lifts whole in one call. A json.loads dict carries unproven data through the program. A before-validator that indexes, renames, routes, or computes is an alias, a path, or a nested model not yet written.
The crossing takes the foreign data whole: model_validate on an arrived object, model_validate_json on arrived bytes, or keyword construction lifting a result's attributes. The foreign model carries every field the program uses, and nothing reads the foreign object after a model has been constructed from it. An omitted foreign key resolves at lifting: a default naming what omission means, or a union variant when omission means a different fact; bare None never crosses in. No coalesce mints data the wire did not carry. A foreign key holding a raw primitive validates into its semantic-scalar field: model_validate wraps the value and applies the scalar's constraint. Type the field as the scalar, never the primitive; never pre-wrap.
A foreign object graph you must walk yourself is a reported gap, but a converter that renders the graph whole as a tagged dict tree (an ast tree dumped to dicts, each tagged by its node kind) is a crossing: model_validate lifts the dict into a discriminated union keyed on the foreign tag, one frozen variant per node kind, with extra="ignore" for keys outside the modeled set. The walk is the converter's, not the program's.
BaseModel, extra="forbid", every field a declared type, named for the foreign thingField(alias=...) for every rename, the aliases holding the foreign keysvalidation_alias and AliasPath for transport wrappers, the wrapper modeled, never indexed pastfrom_attributes=True for objects; model_validate_json for serialized datajson.loads result carried as a dictmode="after" validatorHalt when the foreign shape cannot be lifted by the declarative inventory, when lifting it would need a walk or computation you must write yourself (a converter that renders the graph whole is not that walk), or when the shapes match and a foreign model is still demanded. Report the row and the shape: the crossing is either unnecessary or unmodelable as declared, and the table is not finished.
A frozen BaseModel of this program's own API request or reply, composed of declared types in this program's vocabulary. No alias to another system's key appears on it.
class OrderRequest(BaseModel):
model_config = ConfigDict(frozen=True, extra="forbid")
product: ProductId
side: OrderSide
quantity: Quantity
price: Price
class OrderReceipt(BaseModel):
model_config = ConfigDict(frozen=True, extra="forbid")
order_id: OrderId
A request that does not conform fails construction at the surface; nothing behind the route sees it. The reply leaves whole: the route serializes the contract model itself.
Composition direction separates the edge's two models: the contract model is ours, built of our types and names, projecting outward; the foreign model is theirs, named for their thing, its aliases holding their keys, lifting inward. A composite that is a domain fact rather than a surface shape is a concept model (python-values-success).
One model serving as both our API shape and another system's shape fuses our surface with their shape; build one of each. A hand-built response dict is an unproven shape leaving the program; the reply is the contract model itself, serialized at the route.
BaseModel, extra="forbid", every field a declared type from this context or its peers@computed_field derivations when a derived fact is part of the published shapeinclude, exclude, or by_alias on the reply's serialization; a different wire shape is its own contract modelHalt when the published shape would need a foreign alias, an undeclared type, or include, exclude, or by_alias on its serialization. Report the row and the field: either the shape belongs to a foreign model or the type is not yet modeled, and the table is not finished.
Annotated[A | B, Field(union_mode="left_to_right")] over variants in attempt order, for foreign data that carries no identity and is expected sometimes to fail or to say no. The stronger construction is attempted first, the failure variant is last and composes from the input itself, and construction selects the case.
class TapeText(RootModel[str], frozen=True):
"""The venue tape's frame text as received. Unconstrained on purpose: an unparseable frame is any text."""
root: str
class FrameKind(StrEnum):
TICK = "tick"
UNPARSEABLE = "unparseable"
class Tick(BaseModel):
model_config = ConfigDict(frozen=True, extra="forbid")
kind: Literal[FrameKind.TICK] = FrameKind.TICK
price: Price
quantity: Quantity
class Unparseable(BaseModel):
model_config = ConfigDict(frozen=True, extra="forbid")
kind: Literal[FrameKind.UNPARSEABLE] = FrameKind.UNPARSEABLE
raw: TapeText
@model_validator(mode="before")
@classmethod
def _wrap(cls, data: object) -> object:
return {"raw": data}
Frame = Annotated[Json[Tick] | Unparseable, Field(union_mode="left_to_right")]
FrameConstructor = TypeAdapter(Frame)
class TapeEntry(BaseModel):
model_config = ConfigDict(frozen=True, extra="forbid")
frame: Frame
Fed bytes that parse, Json decodes and Tick constructs; fed garbage, Json refuses and Unparseable composes from the input itself. As a field, frame: Frame admits garbage as a declared value.
A raising client, modeled the same way:
class LedgerKind(StrEnum):
BOOKED = "booked"
UNBOOKED = "unbooked"
class Booked(BaseModel):
model_config = ConfigDict(frozen=True, extra="forbid", from_attributes=True)
kind: Literal[LedgerKind.BOOKED] = LedgerKind.BOOKED
exposure: Exposure
class Unbooked(BaseModel):
model_config = ConfigDict(frozen=True, extra="forbid", from_attributes=True)
kind: Literal[LedgerKind.UNBOOKED] = LedgerKind.UNBOOKED
LedgerReply = Annotated[Booked | Unbooked, Field(union_mode="left_to_right")]
LedgerReplyConstructor = TypeAdapter(LedgerReply)
Fed the reply object, Booked constructs from its attributes. Fed the exception, Booked refuses, and Unbooked constructs from its pinned kind.
One question routes every failure: did the domain say no, or did the proof fail? A construction refusal proves nothing, is never modeled, and propagates; catching ValidationError manufactures the unproven value. A domain no is a value: this construct. An omission that means a fact is the absence doctrine at a foreign lift, not a failure. A transport-setup signal nothing in the domain reacts to belongs to the binding. Identity-carrying data constructs through the plain union's discriminator (python-values-success), never by attempt order.
A try/except producing a default, flag, or partial object manufactures the unproven value construction refused to make. A reply parser inspecting a foreign reply to choose a case restates the selection construction performs. A coalesce (x or default) manufactures a value nothing proved.
The wrap. The one mode="before" validator the architecture admits: a single wrapping line on the failure variant that places the bare input under its field name, legal only with a recorded substrate run showing the declarative inventory refuses the shape. One return, constant keys, the input as every value. A marker handed back where it means a fact constructs an identity-only variant the same way.
The constructor. The constant beside the alias is the alias's declared constructor, the substrate's TypeAdapter, named for the alias it constructs. It defines no structure and decides nothing. As a field on a foreign model, the alias needs no constant: frame: Frame admits garbage as a declared value, the TapeEntry form above.
The capture. Python raises must be captured before construction can receive them. The capture lives in a verb: one call assigned, each declared exception assigned to the same variable, then ordered-union construction from that variable. The capture does not choose a variant, does not construct in an except arm, and an undeclared raise propagates as the refusal it is.
Annotated alias with union_mode="left_to_right", variants in attempt order, failure lastJson[...] as the stronger construction when the input is serializedTypeAdapter constant named for the aliasexcept ValidationError, anywheretry/except producing a default, flag, partial object, or domain variantexcept or a second statement in an except armx or defaultmatch, or isinstance deciding a reply's caseRootModel class created to construct the aliasHalt when a client produces a signal or marker not named by its interface, when the failure variant cannot compose from the input through the wrap, or when ordered selection is demanded for data that carries identity. Report the row and the signal: the wire's shapes are not fully modeled, and the table is not finished.
npx claudepluginhub kyzodb/kyzo-python --plugin kyzo-pythonGuides collaborative design exploration before implementation: explores context, asks clarifying questions, proposes approaches, and writes a design doc for user approval.
Creates structured, bite-sized implementation plans from specs or requirements before writing code. Useful for breaking down multi-step tasks into testable steps with file structure and task boundaries.
Resolves in-progress git merge or rebase conflicts by analyzing history, understanding intent, and preserving both changes where possible. Runs automated checks after resolution.