ML Implementation Guide
Concrete Python patterns for trace-first logging, clean architecture, and error handling.
ML Implementation Guide (Python)
This guide translates WordLoop's overarching Engineering Principles into explicit, copy-pasteable Python code for the wordloop-ml service.
1. Concrete Trace-First Development
We rely on OpenTelemetry for all observability. Because Python requires explicit context propagation in background tasks, we must properly extract and inject W3C Baggage.
Initializing a Span
A new operation must start a span. In FastAPI, this is often handled automatically, but for background pipeline tasks, you must explicitly declare it.
Passing Context
When publishing to Pub/Sub or calling another service, you must explicitly inject the current trace context into the HTTP headers or message attributes.
2. Concrete Error Handling
We use explicit Python Exception subclasses defined in our pure Domain to prevent external SDK errors from polluting our business logic.
Defining Sentinels
Define business rule errors in src/wordloop/core/exceptions.py. They should inherit from a base WordLoopError:
Wrapping & Mapping Errors in Providers
An Adapter (Provider) interacting with the AssemblyAI SDK or OpenAI SDK must catch the library-specific error and raise a pure Domain exception.
3. Concrete Dependency Injection
We use Python's Protocol from the typing module to define Interfaces (Ports).
The Port (Defined by the Core)
The protocol belongs in src/wordloop/core/gateways/ and strictly uses Domain language, completely ignorant of AssemblyAI or Postgres.
The Wiring (Entrypoint)
Constructor injection is used. FastAPI's Depends system automatically resolves these during the request lifecycle.
4. Idiomatic Python & Standards
We do not aim to rewrite foundational guidance on writing excellent Python code. Instead, we adhere to established industry baselines and mapping them to our internal engineering principles.
We expect all Wordloop ML engineers to understand:
- PEP 8 for fundamental language syntax.
- Google Python Style Guide for enterprise-level structure and docstring consensus.
Below is concrete guidance on how overarching Python idioms manifest as system-enforced architectural invariants.
Strict Typing over Duck Typing (Clean Architecture)
The Python Idiom: Using strong static typing (mypy) instead of traditional dynamic duck-typing.
The Principle Connection: Clean Architecture (Ports and Adapters) relies heavily on explicit Contracts/Ports across boundaries. We enforce the use of typing.Protocol and strict type hints on all domain models to ensure dependency inversion is compile-time verifiable.
Context Managers for Resource Leaks (Resilience)
The Python Idiom: Using with and @contextmanager for resource lifecycle management.
The Principle Connection: We practice robust Error Handling & Resilience. If an ML SDK or file stream throws an exception, failing to clean up memory or connections results in persistent leaks and eventual cluster death.
Always utilize Context Managers when handling stateful resources. This guarantees the __exit__ cleanup executes even if your domain logic crashes.