Skip to main content

Framework M Entry Points Reference

Framework M uses Python entry points for discovery and extensibility. This allows packages to register themselves, override core services, or contribute to the UI without modifying the framework itself.

Complete List of Core Groups

These are the primary groups the framework scans for:

GroupPurposeTargetPackage
framework_m.appsMain App registrationModuleframework-m-core
framework_m.frontendMFE Plugin (UI)Moduleframework-m-standard
framework_m.shellActive UI ShellStatic pathframework-m-standard
framework_m.bootstrapStartup stepsBootstrapProtocolframework-m-core
framework_m.cli_infoStatus detection for m infoFunction(Table)framework-m-core
framework_m.overridesDI Provider overridesClass/Factoryframework-m-core
framework_m.containersAdditional DI ContainersContainer Classframework-m-core
framework_m_core.cli_commandsm CLI extensionscyclopts.Appframework-m-core
framework_m.workersBackground worker enginesCallableframework-m-standard
framework_m.readinessCustom checks for readiness probe (/ready)Callableframework-m-standard
framework_m.jobsBackground task modulesModuleframework-m-core

Specialized Adapters

These allow swapping core implementations (e.g., using MX-Mongo instead of Standard-SQLAlchemy):

GroupDefault Implementation
framework_m.adapters.repositoryframework_m_standard.adapters.db:GenericRepository
framework_m.adapters.schema_mapperframework_m_standard.adapters.db:SchemaMapper
framework_m.adapters.unit_of_workframework_m_standard.adapters.db:SessionFactory
framework_m.adapters.permissionframework_m_standard.adapters.auth:CitadelPolicyAdapter
framework_m.adapters.event_busframework_m_standard.adapters.events:InMemoryEventBus
framework_m.adapters.introspectionframework_m_standard.adapters.db:SQLAlchemyIntrospectionAdapter
framework_m.adapters.discoveryframework_m_standard.adapters.discovery:EnvDiscoveryAdapter

Discovery vs. Activation

Framework M uses a deferred loading pattern. While entry points are automatically "discovered" by the Python environment, they are not "activated" until explicitly triggered during the Bootstrapping Lifecycle.

The Orchestration Bridge

The framework_m.bootstrap group is the primary way to activate all other entry points. A standard bootstrap step will call the loader functions (like auto_load_app_containers()) to bring your registered code into the system at the correct time.

Refer to the Bootstrapping Guide and the CLI & Worker Lifecycle Architecture for detailed implementation examples and phase contracts.

Verification

The easiest way to see which entry points are active in your environment is using the studio CLI:

m entrypoints

This command automatically filters for all framework_m.* and framework_m_core.* groups.

Quick Reference: How to Register

To register any of the above, add them to your pyproject.toml.

1. Register a Startup Step (framework_m.bootstrap)

Use this to run code during app initialization (e.g., binding DI).

pyproject.toml:

[project.entry-points."framework_m.bootstrap"]
init_my_service = "my_app.bootstrap:MyServiceInit"

my_app/bootstrap.py:

from typing import Any
from framework_m_core.interfaces.bootstrap import BootstrapProtocol

class MyServiceInit(BootstrapProtocol):
name = "init_my_service"
order = 40 # Runs after DB (10) and Registries (20)

def run(self, container: Any) -> None:
# The framework automatically hydrates apps, containers, and overrides
# via the hydrate_apps() orchestrator before this step runs.
print("✓ My Service Initialized")

2. Register a DI Override (framework_m.overrides)

Replace a core service (like session_factory) with a custom one.

pyproject.toml:

[project.entry-points."framework_m.overrides"]
session_factory = "my_app.overrides:CustomSessionFactory"

3. Register a CLI Command (framework_m_core.cli_commands)

Add a new sub-command to the m CLI.

pyproject.toml:

[project.entry-points."framework_m_core.cli_commands"]
custom_cmd = "my_app.cli:my_function"

[!TIP] Important: For local libraries to be discovered, ensure they are listed in your root pyproject.toml workspace members:

[tool.uv.workspace]
members = ["libs/*", "apps/*"]