The Artemis plugin system lets you extend the platform by packaging a Python class that inherits fromDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/artemis-development-group/artemis/llms.txt
Use this file to discover all available pages before exploring further.
Plugin and advertising it via a setup.py entry point. Plugins can contribute templates, static files, JavaScript modules, configuration keys, URL routes, and event-driven hooks without modifying the core codebase.
The Plugin base class
Every plugin is a Python class that inherits fromr2.lib.plugin.Plugin. The base class is defined in r2/r2/lib/plugin.py and provides the structure the loader expects.
plugin.py (base class)
Properties
| Property | Type | Description |
|---|---|---|
name | str | The entry point name as declared in setup.py. Used to identify the plugin in logs and config. |
path | str | Absolute filesystem path to the directory containing the plugin module. |
template_dir | str | Resolves to <path>/templates/. Automatically prepended to Mako’s template search path on load. |
static_dir | str | Resolves to <path>/public/. Used when needs_static_build is True to locate assets for the static build pipeline. |
Class-level attributes
These are declared directly on your subclass, not as instance attributes.| Attribute | Type | Default | Description |
|---|---|---|---|
js | dict | {} | Maps JS bundle names to r2.lib.js.Module instances. Merged into the global module registry on load. |
config | dict | {} | Config spec entries added to g.config via add_spec. Use ini-file keys as keys. |
live_config | dict | {} | Like config, but for values that can change at runtime without a restart. |
needs_static_build | bool | False | Set to True if the plugin has static assets that require a build step. |
needs_translation | bool | True | Set to False to opt out of the translation pipeline for this plugin. |
errors | dict | {} | Maps error code names to r2.lib.errors.ErrorSet entries. Registered into the global error registry when controllers load. |
Methods to override
on_load(g)
Called once during application startup after config is available. Use this to perform any initialization that depends on g (the Pylons app globals).
add_routes(mc)
Called during route setup. mc is a Pylons mapper (Routes Mapper). Use it to add URL routes that your plugin’s controllers handle.
load_controllers()
Called after all plugins are loaded, once i18n is available. Import and register your controllers here.
declare_queues(queues)
Called during queue initialization. Add any AMQP queues your plugin needs.
Writing a plugin
Default plugins
The default Artemis install enables two plugins, set via theARTEMIS_PLUGINS variable in install.cfg:
| Plugin | Purpose |
|---|---|
about | Provides /about pages (rules, contact, jobs, etc.) |
gold | Artemis Gold subscription features |
ARTEMIS_PLUGINS before running the installer:
The HookRegistrar system
Hooks let plugins react to events fired by the core application without modifying core code. The system is defined inr2/r2/lib/hooks.py.
How hooks work
Core code fires a hook at a named point:HookRegistrar:
myplugin/hooks.py
register_all() must be called after all @hooks.on(...) decorators have been evaluated. Typically this means calling it at module level, at the bottom of the file that defines your handlers.HookRegistrar API
HookRegistrar()
Create a new registrar instance. Each plugin should create its own instance to keep registrations isolated.
@hooks.on(name)
Decorator that queues the wrapped function as a handler for hook name. The function is not registered into the global hook until register_all() is called.
hooks.register_all()
Flushes all deferred registrations into the global hook table. Call this once, at module scope, after all @hooks.on decorators:
Firing hooks (core side)
To fire a hook from within the application or from another plugin:Hook.call(**kwargs)
Calls every registered handler in registration order. Returns a list of all handler return values.
Hook.call_until_return(**kwargs)
Calls handlers in registration order and returns the return value of the first handler that returns a non-None value. Useful for provider-style hooks where only one handler should handle the event.
Provider extension points
In addition to the[r2.plugin] group, setup.py defines several provider groups for replacing built-in services. Implement the corresponding interface and register under the appropriate group:
r2.provider.media
Storage backends for uploaded media. Built-in providers:
s3, filesystem.r2.provider.cdn
CDN integration for cache purging. Built-in providers:
fastly, cloudflare, null.r2.provider.auth
Authentication backends. Built-in providers:
cookie, http.r2.provider.support
Support ticket integration. Built-in provider:
zendesk.r2.provider.search
Search backends. Built-in providers:
cloudsearch, solr.r2.provider.image_resizing
On-the-fly image resizing. Built-in providers:
imgix, no_op, unsplashit.r2.provider.email
Outbound email. Built-in providers:
null, mailgun.r2.plugin:
setup.py (provider entry point)