Structum Exit & Decommissioning Strategy

Promise: Structum is a guest in your architecture, not a jailer.
Related Principle: C-4 Zero Lock-In

This document formalizes the process of removing Structum from your application. Use this guide during architecture reviews to prove that adopting Structum is a reversible decision.


1. The “Residue” Analysis

When you remove Structum, what is left behind?

Because Structum relies on Standard Library Protocols, the “residue” is standard Python code.

Component

Residue

Impact

Core

typing.Protocol definitions

Positive. You keep clean interfaces.

Plugins

None (Libraries are removed)

Neutral. You gain manual control.

Config

config.get("path") calls

Moderate. Needs refactoring to new dict usage.

DI

container.provider calls

High. Needs replacement with manual wiring.


2. Decommissioning Procedure

Step 1: Ejecting the Configuration

If you want to switch to raw os.environ or pydantic-settings.

  1. Replace Provider: Create a simple shim class implementing ConfigInterface that wraps os.environ.

  2. Inject Shim: Pass this new shim to set_config_provider().

  3. Refactor: (Optional) Search/Replace get_config().get() with your new direct access method.

Cost: ~2 hours.

Step 2: Removing Dependency Injection

If you want to switch to manual instantiation.

  1. Delete Container: Remove container.py and StructumContainer.

  2. Manual Wiring: In main.py, manually instantiate your services.

    # Before
    service = container.service()
    
    # After
    db = SQLAlchemyDatabase(...)
    repo = UserRepository(db)
    service = UserService(repo)
    
  3. Preserve Interfaces: Your domain classes (UserService) do not change because they depended on Protocols, not the container.

Cost: Linear to app size (low complexity, high boredom).

Step 3: Removing Observability

If you want to use loguru or raw logging.

  1. Remove Shim: Delete structum.logging imports.

  2. Native Usage: Replace get_logger(__name__) with logging.getLogger(__name__).

  3. Metrics: If using get_metrics(), replace with direct prometheus_client calls.

Cost: ~4 hours (Search & Replace).


3. The “Point of No Return”

There isn’t one.

Structum does not:

  • Subclass your domain objects (like some ORMs).

  • Require a custom runtime runner (like some serverless frameworks).

  • Inject magic globals that break when removed.

You can halt Structum adoption at any phase or revert it completely.


4. Why document this?

Trust is built on the ability to leave, not the requirement to stay.