Entity¶
An Entity is a named, structured unit of data that the system passes around. It
represents a meaningful piece of information in the domain — a database record, a
configuration object, a sensor reading, a video frame, or any other structured data
that components, repositories, and pipelines work with.
Entities answer one question:
What does the data look like?
Not where it comes from or how it is processed — that's a Repository's job. Entities are the common language of the application.
When to use Entity¶
Use @Entity when a class represents a structured unit of data that:
- is passed between components, tasks, or pipelines
- has a well-defined shape that the rest of the system depends on
- represents a domain concept worth naming explicitly
Typical examples:
- a user record
- an order
- a sensor reading
- a metric snapshot
- a video frame
- a configuration record
Decorator¶
The @Entity decorator registers the class with the framework as a data structure.
It is a marker — the class is returned unchanged.
Without arguments¶
With a name¶
An optional name can be provided to register the entity under something other than the kebab-case form of its class name — useful when the class name doesn't match the domain name you want to look it up by.
Registering under a name that's already taken
Entities are stored in a plain name → class dict, keyed by the normalized
name. If both User and UserV2 above are defined, UserV2 — being
decorated second — silently overwrites User under the "user" key, and
Entity.get("user") returns UserV2. There's no error or warning; keep
explicit names unique across entities you intend to keep.
Defining Entities¶
The canonical form for an Entity is a Python dataclass. Dataclasses are lightweight,
require no dependencies, and work naturally with type hints.
Simple record¶
Nested structure¶
@Entity
@dataclass
class Address:
street: str
city: str
country: str
@Entity
@dataclass
class Order:
id: int
user_id: int
address: Address
total: float
Non-record data¶
Entities are not limited to database-style records. Any structured unit of data the system works with can be an entity:
@Entity
@dataclass
class Frame:
index: int
timestamp: float
width: int
height: int
data: bytes
@Entity
@dataclass
class Reading:
sensor_id: str
timestamp: float
value: float
unit: str
Relationship to Repository¶
An Entity describes the shape of data. A Repository manages it —
storing, retrieving, and querying instances of that entity.
@Entity
@dataclass
class User:
id: int
name: str
email: str
@Repository(User)
class Users:
def get(self, user_id: int) -> User:
...
def save(self, user: User) -> None:
...
The @Repository(User) decorator links the repository to its entity explicitly,
making the relationship visible without requiring inheritance.
Looking up registered entities
Entity is a namespace — Entity.get("user") returns the User class (or
None if unregistered), and dict(Entity.items()) returns every registered
name → class pair.
What Entity is Not¶
-
Not a base class.
Userdoes not inherit fromEntity. The decorator marks it; inheritance is not involved. -
Not tied to a database. An entity represents a structured unit of data — it has no implied persistence mechanism. Where and how it is stored is the responsibility of a
Repository. -
Not a behaviour container. Entities describe data shape. Business logic belongs in a Component, Task, or Pipeline.
Design Notes¶
Keep entities focused. An entity should represent one domain concept. If a class
is growing methods and logic, consider whether that logic belongs in a Component
instead.
Prefer flat structures where possible. Deeply nested entities are harder to query and pass around. If nesting grows complex, consider whether the nested type should be its own entity managed by its own repository.
Name entities after domain concepts. User, Order, Frame, Reading — not
UserData, OrderRecord, or FrameObject. The entity name is the domain language.