Reputation: 13610
I'd like to know how to edit pyramid registry at runtime. Well i'm not so sure exactly what I have to edit.
I know I can extend pyramid with config.include(...). But once config.make_wsgi_app() is called, there seems to be no way to add routes or new mako directories. Any change to the registery in threadlocals or settings have no effect on how the app behave.
My goal is to add plugin at runtime. Here's a use case.
Someone install my appserver running pyramid...then install some plugins
pip install page_plugin
then in /configs
There is a list of installed plugins and you can select which ones are activated or not. Currently I know of only one way to do that:
Using entry_points I can see my plugins and in the main function of pyramid, I can register the plugins. Using a filestorage I could check every plugins states: [install, installed, uninstall, uninstalled, disabled]
That way I can from a view install/uninstall my plugins.
In order to see any change I have to reboot the server.
states install : will install on next boot installed: is installed and active uninstall: will uninstall on next boot uninstalled: is uninstalled disabled: not uninstalled but not activated
install/uninstall are used to setup the database if needed
I think there is no real other way to do that since there is no "remove_view". I could probably make the server reload. And it would load the new configuration.
[EDIT]
There is no function to remove route or antyhing. SO my guess is that realoding the server is probably the easies and simplest way to do it... and it is probably cleaner to reboot the server than forgetting to unload some stuffs from the plugins.
Upvotes: 2
Views: 1952
Reputation: 23341
It is possible to modify the registry at runtime:
config = Configurator(registry=request.registry)
config.add_route(...)
config.commit()
You have to note, however, that modifying the registry is not a thread-safe operation. You would have to synchronize this yourself. Instead of doing this, I would suggest thinking about your problem in a different way and attempting to create routes that encompass the features that you anticipate extending. Routes can accept patterns (even .*
if you want the rest of the URL), and there is also traversal which is very very dynamic and easy to extend at runtime.
Adding removable views is possible, but I wouldn't do it at the "adding or removing of routes" level. Instead I suggest using custom predicates on your routes that control whether the route is matched or not.
def is_enabled(info, request):
return True if route_should_be_enabled else False
config.add_route('my_plugin_head', '/foo/{bar}', custom_predicates=[is_enabled])
In this way, if is_enabled returns False, the route is never matched and is effectively ignored.
Upvotes: 3