Migrating to 0.17
From 0.16 to 0.17
Protean 0.17 begins consolidating the 1.0 public API surface and retiring the built-in email subsystem. Renamed public options are drop-in: the deprecated spelling keeps working (behind a warning) through the transition window. One framework-internal option that was never part of the public API is removed outright, with no transition window. The email subsystem keeps working too, now behind a deprecation warning, and is scheduled for removal in v1.0.0.
On this page:
event_sourcedreplacesis_event_sourced— canonical boolean option spellingis_fact_eventis now framework-internal — it can no longer be passed as an option- Email subsystem deprecation — the email subsystem is deprecated in favor of application-level notification
event_sourced replaces is_event_sourced
Tier 1. Boolean element options are now bare predicates. The aggregate
option that enables event sourcing is event_sourced; the old
is_event_sourced spelling is a deprecated alias.
@domain.aggregate(event_sourced=True) # was: is_event_sourced=True
class Account:
...
The alias still works but emits a RemovedInProtean10Warning and is reported as
a DEPRECATED_OPTION diagnostic by protean check. It will be removed in
v1.0.0. If both spellings are supplied, event_sourced wins. The internal
meta_.is_event_sourced attribute is unchanged.
is_fact_event is now framework-internal
Internal option removed (no deprecation window). is_fact_event was never a
public option user code should set: the framework assigns it when it generates
fact events for an aggregate marked fact_events=True. Because it was never part
of the public API, it is removed outright rather than deprecated: passing
is_fact_event= to an event or command (via the decorator or domain.register)
now raises ConfigurationError immediately.
Nothing changes for reads: meta_.is_fact_event is still present on every
event and command (defaulting to False), and fact events still carry
meta_.is_fact_event is True. If you were setting the option by hand, drop it
and let fact_events=True on the aggregate drive generation.
Email subsystem deprecation
Tier 1. The built-in email subsystem is deprecated and will be removed in
v1.0.0. Sending email is an infrastructure concern that belongs in an
application-level notification service, not in the domain framework. Every email
entry point still works but now emits a RemovedInProtean10Warning:
- registering an email element, via either
@domain.emailordomain.register(SomeEmail); domain.send_email(...)anddomain.get_email_provider(...);- configuring a non-default
[email_providers]block indomain.toml.
Deprecation warnings are silent by default. Surface them by running Python with
-W default::DeprecationWarning, and run protean check to list every
registered email element as a DEPRECATED_EMAIL info diagnostic (it does not
fail the check).
What to do
Move notification out of the domain. Handle the domain event (or subscribe to the stream) and call your own notification service, which owns the email transport:
@domain.event_handler(part_of=Person)
class SendWelcomeNotification:
@handle(PersonAdded)
def on_person_added(self, event: PersonAdded) -> None:
# `notifications` is your application-level service wrapping whatever
# email/SMS/push transport you use (SendGrid, SES, a queue, ...).
notifications.send_welcome(to=event.email, name=event.first_name)
This keeps the domain focused on what happened (PersonAdded) and leaves the
delivery mechanism to infrastructure you control, so it can evolve independently
of the framework.