Skip to content

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_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.email or domain.register(SomeEmail);
  • domain.send_email(...) and domain.get_email_provider(...);
  • configuring a non-default [email_providers] block in domain.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.