๐ Plugins
Flaxon's plugin system lets you extend the framework with modular, reusable components. Learn how to use, install, and build your own plugins.
Official Flaxon Plugins
Use packages published on PyPI, and check each package's repository for its supported Flaxon version and configuration.
New integration packages
These repositories are ready for release but are not on PyPI yet. Install from PyPI only after their first release is published. See the ecosystem guide for accurate setup and usage examples.
๐ Understanding the Plugin System
Flaxon's plugin system is designed to be simple yet powerful. Here's how it works.
๐ Plugin Lifecycle
Plugin Metadata
Every plugin has a name, version, description, and author.
Dependencies
Plugins can declare requires and provides for dependency management.
Hooks
Plugins can register lifecycle hooks: on_load, setup, on_startup, on_shutdown, on_unload.
What Plugins Can Do
Add routes, middleware, CLI commands, health checks, and application state.
๐ Plugin Discovery
Flaxon automatically discovers plugins in:
- The
plugins/directory - A module loaded explicitly with
await app.plugins.load_plugins_from_module(...) - A plugin instance registered with
await app.plugins.load_plugin(...)
๐ ๏ธ Building Your Own Plugin
Create custom Flaxon plugins in 5 minutes.
Step 1: Create the Plugin Class
from flaxon.plugins import Plugin
class MyPlugin(Plugin):
name = "my-plugin"
version = "1.0.0"
description = "A custom Flaxon plugin"
author = "Your Name"
def setup(self, app):
"""Called when the plugin is loaded."""
print("MyPlugin setup!")
app.state.my_plugin = "Hello from MyPlugin!"
def on_load(self):
print("Plugin loaded")
def on_startup(self):
print("Plugin startup")
def on_shutdown(self):
print("Plugin shutdown")
def on_unload(self):
print("Plugin unloaded")
Step 2: Add Routes
class MyPlugin(Plugin):
name = "my-plugin"
version = "1.0.0"
def setup(self, app):
@app.get("/plugin")
async def plugin_route():
return {"plugin": "MyPlugin", "status": "active"}
@app.get("/plugin/health")
async def plugin_health():
return {"status": "healthy", "plugin": "MyPlugin"}
Step 3: Add Middleware
from flaxon.middleware import Middleware
class MyPluginMiddleware(Middleware):
async def __call__(self, scope, receive, send):
print("MyPluginMiddleware processing request")
await self.app(scope, receive, send)
class MyPlugin(Plugin):
name = "my-plugin"
version = "1.0.0"
def setup(self, app):
app.add_middleware(MyPluginMiddleware)
Step 4: Add Configuration
class MyPlugin(Plugin):
name = "my-plugin"
version = "1.0.0"
def __init__(self, config=None):
self.config = config or {}
def setup(self, app):
# Access configuration
debug = self.config.get("debug", False)
api_key = self.config.get("api_key")
if debug:
print("Debug mode enabled")
# Use config in routes
@app.get("/plugin/config")
async def plugin_config():
return {
"debug": debug,
"api_key": "***" if api_key else "not set"
}
Step 5: Register Your Plugin
from flaxon import Flaxon
from my_plugin import MyPlugin
app = Flaxon("my-app")
@app.on_startup
async def load_my_plugin():
# Plugin loading is asynchronous.
await app.plugins.load_plugin(MyPlugin(config={
"debug": True,
"api_key": "your-api-key"
}))
# Your plugin is now active!
@app.get("/")
async def home():
return {"message": "Hello from Flaxon!"}
๐ Complete Plugin Template
"""flaxon-my-plugin - A custom Flaxon plugin."""
from flaxon.plugins import Plugin
class MyPlugin(Plugin):
"""
My custom Flaxon plugin.
Register this plugin from an async startup handler:
@app.on_startup
async def load_plugin():
await app.plugins.load_plugin(MyPlugin(config={"debug": True}))
"""
name = "my-plugin"
version = "1.0.0"
description = "A custom Flaxon plugin"
author = "Your Name"
requires = []
provides = ["my-plugin-service"]
def __init__(self, config=None):
self.config = config or {}
self._app = None
def setup(self, app):
"""Setup the plugin."""
self._app = app
app.state.my_plugin = self
# Add routes
@app.get("/my-plugin")
async def plugin_route():
return {
"plugin": "my-plugin",
"version": self.version,
"config": self.config
}
# Add middleware
app.add_middleware(MyPluginMiddleware)
# Plugin lifecycle hooks are invoked by Flaxon's plugin manager.
def on_load(self):
print(f"[{self.name}] Loaded")
def on_startup(self):
print(f"[{self.name}] Starting up...")
def on_shutdown(self):
print(f"[{self.name}] Shutting down...")
def on_unload(self):
print(f"[{self.name}] Unloaded")
def get_config(self):
return self.config
class MyPluginMiddleware:
"""Custom middleware for MyPlugin."""
def __init__(self, app):
self.app = app
async def __call__(self, scope, receive, send):
print("[MyPluginMiddleware] Request received")
await self.app(scope, receive, send)
- Use
app.stateto share data between plugin components - Plugins can add CLI commands via
app.cli - Use
requiresandprovidesfor dependency management - Always handle errors gracefully in your plugin
- Write tests for your plugin