InitO#
A zero-dependency Python library that eliminates data-class boilerplate.
Decorate a class and InitO writes the mechanical methods it needs — constructor,
repr, equality, hashing, accessors, and builders — as real methods, generated
once when the class is defined, never at construction or attribute-access time.
Your objects stay ordinary Python instances and run as fast as code you’d write
by hand.
from inito import Data
@Data
class User:
name: str
age: int = 0
user = User("Ada", age=30)
print(user) # User(name='Ada', age=30)
print(user.get_name()) # Ada
user.set_age(31)
print(user == User("Ada", 31)) # True
By hand, User is ~20 lines of __init__, __repr__, __eq__, __hash__, and
accessors. With InitO it’s the three lines above — and the generated methods are
the same code you’d have written, benchmarked at parity with
handwritten classes and dataclasses.
pip install inito # or: uv add inito
Requires Python 3.9+ (tested through 3.14). No runtime dependencies.
Install InitO and tour every decorator in a few minutes.
The boilerplate problem InitO solves — and how it stays fast.
A dedicated page per decorator, plus DI, recipes, and migration.
Wire object graphs with @Service/@Singleton/@Inject and a Container.
Real-world, copy-pasteable patterns combining several decorators.
Every decorator, option, and exception, generated from the source.
Why InitO#
Real methods, generated once. Each decorator builds true Python functions from your fields at decoration time and attaches them — no
__getattr__, proxies, descriptors, or runtime interception. At runtime your objects are ordinary instances, so construction, attribute access,==, andhash()run at handwritten speed.Zero runtime dependencies. InitO imports nothing outside the standard library, so it installs cleanly into any project and any environment.
À la carte.
@Datais the all-in-one, but every capability is also a standalone decorator (@Getter,@ToString,@EqualsAndHashCode, …) — you never pay for what you don’t ask for.Typed for both checkers. A bundled mypy plugin makes
mypy --strictsee every generated member, andinito-stubgendoes the same for pyright / Pylance.Batteries included. Genuine immutability (
@Value), fluent builders (@Builder), environment-backed configuration (@Config), and a small dependency-injection layer — same generate-once, zero-dependency design throughout.
Decorators at a glance#
Decorator |
Generates |
Guide |
|---|---|---|
|
constructor · |
|
|
like |
|
|
|
|
|
|
|
|
|
|
|
an |
|
|
fluent |
|
|
load fields from environment variables, autowired by type |
|
|
|
|
|
dependency injection via a |
Every PascalCase decorator has a lowercase alias (data, builder, value, …)
bound to the same object — use whichever reads better.
Dependency injection#
A small, lazy, thread-safe DI layer: declare a class’s
dependencies as fields, and a Container wires them — no markers, no provider
objects. @RequiredArgsConstructor even writes the constructor for you.
from inito import Inject, RequiredArgsConstructor, Service, Singleton
@Singleton
class Database:
rows = {1: "Ada"}
@Service
@RequiredArgsConstructor
class UserService:
db: Database # autowired from the container
@Inject
def main(service: UserService) -> None:
print(service.db.rows[1]) # Ada
main()
It also supports scopes (singleton, transient,
thread-local), qualifiers
for multiple implementations, config injection,
factories for on-demand
construction with call-time arguments,
resource lifecycle with
ordered teardown (@Resource, with container),
scopes (Scope.SCOPED + container.scope()),
async resolution (await container.aget()),
FastAPI Injected[T], and
test overrides.
Type checking#
InitO attaches members at decoration time, so type-checkers need a hint — and it
ships one for both. Enable the mypy plugin
for mypy --strict, or run inito-stubgen to generate .pyi
stubs that give pyright / Pylance the same full visibility.
Works with your framework#
Zero dependencies and plain methods on plain classes mean InitO drops into any
project. On a Pydantic / SQLAlchemy / Django model, use the additive
decorators and let the framework own construction; the DI layer resolves safely
from async handlers. See Using InitO with your
framework — with runnable examples for FastAPI, Django, Sanic,
aiohttp, Redis, boto3, and more.
When to use InitO#
Reach for InitO on the classes that are mostly data — DTOs, domain/value objects, configuration, and service objects. It removes the mechanical methods they need without changing what they are: after decoration they’re still plain Python classes you can subclass, pickle, and construct directly. It composes with, rather than replaces, validation/ORM layers like Pydantic and SQLAlchemy.