Plugins / Modularity

  • Thread starter =?iso-8859-1?q?Robin_K=E5veland?=
  • Start date
?

=?iso-8859-1?q?Robin_K=E5veland?=

Hi there. I'm basically in the process of writing my first substantial
application in Python, and I've made a couple of (I'd like to say)
design decisions so it won't just be a jumble. So, I've divided my
program into three sub-packages, core, plugins and utilities.

The core will be needed for the program to be run, but I've put it in
a package by itself to make things more tidy.
The utilities will be things that are handy to have (I'm thinking
packages written by others that will make my work easier), but aren't
necessary for the program to run. I'm not sure if this is needed yet,
but I want to have the option in case it turns out to be useful.

The plugins will basically be a package with modules adding
functionality to the program, so to make it more extensible, and let
others have a very simple way of extending the functionality without
having to read a lot of source code and documentation. Adding a plugin
should be really simple, preferrably you shouldn't have to modify any
existing source, just put a .py file into the directory. This is where
I'm sort of stuck. Does anyone know a way I can achieve this?

This poses a couple of challenges for me, given the structure of my
project and that I have no clue about how to do it. I'm thinking here
that every plugin will have a main callable, which will recieve a
Request object which can be queried for information, and an Action
object which can be used to affect the state of the program to some
degree. These will ideally be very simple (And for the moment, they
obviously are).

What I want, is a moment to 'contact' every module in the plugins
package, and send these two objects to it's main callable. I also want
to add a way for the program to load and reload plugin modules on the
fly, so I can modify them without having to shut it down.

Does anyone have some links for me? Alternatively any ideas?

Thanks in advance.
 
D

danmcleran

Hi there. I'm basically in the process of writing my first substantial
application in Python, and I've made a couple of (I'd like to say)
design decisions so it won't just be a jumble. So, I've divided my
program into three sub-packages, core, plugins and utilities.

The core will be needed for the program to be run, but I've put it in
a package by itself to make things more tidy.
The utilities will be things that are handy to have (I'm thinking
packages written by others that will make my work easier), but aren't
necessary for the program to run. I'm not sure if this is needed yet,
but I want to have the option in case it turns out to be useful.

The plugins will basically be a package with modules adding
functionality to the program, so to make it more extensible, and let
others have a very simple way of extending the functionality without
having to read a lot of source code and documentation. Adding a plugin
should be really simple, preferrably you shouldn't have to modify any
existing source, just put a .py file into the directory. This is where
I'm sort of stuck. Does anyone know a way I can achieve this?

This poses a couple of challenges for me, given the structure of my
project and that I have no clue about how to do it. I'm thinking here
that every plugin will have a main callable, which will recieve a
Request object which can be queried for information, and an Action
object which can be used to affect the state of the program to some
degree. These will ideally be very simple (And for the moment, they
obviously are).

What I want, is a moment to 'contact' every module in the plugins
package, and send these two objects to it's main callable. I also want
to add a way for the program to load and reload plugin modules on the
fly, so I can modify them without having to shut it down.

Does anyone have some links for me? Alternatively any ideas?

Thanks in advance.

I've just completed the initial launch basically this kind of software
framework. They way I did it was to parse xml files and load modules
and classes dynamically. After instantiating the classes, I call a
certain method that I expect to be present so that each class can
register any functionality it provides with a central registry within
the system. Overall, I've been very pleased with the way it turned
out. It's very easy to add functionality to the system, you simply add
an xml file along with some Python modules and you don't need to
change any existing code. I can provide some examples for you if you
like. Here's a little snippet from a Python script that loads modules
and classes:

def loadModule(moduleName):
"""
Loads modules from within nested packages
Reload ensures Python code is re-compiled.
"""
mod = __import__(moduleName)
components = moduleName.split('.')

for component in components[1:]:
mod = getattr(mod, component)
mod = reload(mod)

return mod

def loadClass(moduleName, className):
"""
Load a class from a module.
Note: This does not create a class instance, it only loads the
code.
"""
module = loadModule(moduleName = moduleName)
c = getattr(module, className)

return c

You can try this out by passing in a string with with module and/or
class path and see that the module and/or class. Note that loadClass
does not create a class instance, so you'll have to instantiate it if
you want to, like this:

o = loadClass(modulePath,className)() #instantiates class that was
loaded dynamically
 
?

=?iso-8859-1?q?Robin_K=E5veland?=

Hi there. I'm basically in the process of writing my first substantial
application in Python, and I've made a couple of (I'd like to say)
design decisions so it won't just be a jumble. So, I've divided my
program into three sub-packages, core, plugins and utilities.
The core will be needed for the program to be run, but I've put it in
a package by itself to make things more tidy.
The utilities will be things that are handy to have (I'm thinking
packages written by others that will make my work easier), but aren't
necessary for the program to run. I'm not sure if this is needed yet,
but I want to have the option in case it turns out to be useful.
The plugins will basically be a package with modules adding
functionality to the program, so to make it more extensible, and let
others have a very simple way of extending the functionality without
having to read a lot of source code and documentation. Adding a plugin
should be really simple, preferrably you shouldn't have to modify any
existing source, just put a .py file into the directory. This is where
I'm sort of stuck. Does anyone know a way I can achieve this?
This poses a couple of challenges for me, given the structure of my
project and that I have no clue about how to do it. I'm thinking here
that every plugin will have a main callable, which will recieve a
Request object which can be queried for information, and an Action
object which can be used to affect the state of the program to some
degree. These will ideally be very simple (And for the moment, they
obviously are).
What I want, is a moment to 'contact' every module in the plugins
package, and send these two objects to it's main callable. I also want
to add a way for the program to load and reload plugin modules on the
fly, so I can modify them without having to shut it down.
Does anyone have some links for me? Alternatively any ideas?
Thanks in advance.

I've just completed the initial launch basically this kind of software
framework. They way I did it was to parse xml files and load modules
and classes dynamically. After instantiating the classes, I call a
certain method that I expect to be present so that each class can
register any functionality it provides with a central registry within
the system. Overall, I've been very pleased with the way it turned
out. It's very easy to add functionality to the system, you simply add
an xml file along with some Python modules and you don't need to
change any existing code. I can provide some examples for you if you
like. Here's a little snippet from a Python script that loads modules
and classes:

def loadModule(moduleName):
"""
Loads modules from within nested packages
Reload ensures Python code is re-compiled.
"""
mod = __import__(moduleName)
components = moduleName.split('.')

for component in components[1:]:
mod = getattr(mod, component)
mod = reload(mod)

return mod

def loadClass(moduleName, className):
"""
Load a class from a module.
Note: This does not create a class instance, it only loads the
code.
"""
module = loadModule(moduleName = moduleName)
c = getattr(module, className)

return c

You can try this out by passing in a string with with module and/or
class path and see that the module and/or class. Note that loadClass
does not create a class instance, so you'll have to instantiate it if
you want to, like this:

o = loadClass(modulePath,className)() #instantiates class that was
loaded dynamically

Ah, fantastic! I didn't know about __import__, this is basically
exactly what I need. I think I will manage, thanks a lot!
 
D

danmcleran

I've just completed the initial launch basically this kind of software
framework. They way I did it was to parse xml files and load modules
and classes dynamically. After instantiating the classes, I call a
certain method that I expect to be present so that each class can
register any functionality it provides with a central registry within
the system. Overall, I've been very pleased with the way it turned
out. It's very easy to add functionality to the system, you simply add
an xml file along with some Python modules and you don't need to
change any existing code. I can provide some examples for you if you
like. Here's a little snippet from a Python script that loads modules
and classes:
def loadModule(moduleName):
"""
Loads modules from within nested packages
Reload ensures Python code is re-compiled.
"""
mod = __import__(moduleName)
components = moduleName.split('.')
for component in components[1:]:
mod = getattr(mod, component)
mod = reload(mod)
return mod
def loadClass(moduleName, className):
"""
Load a class from a module.
Note: This does not create a class instance, it only loads the
code.
"""
module = loadModule(moduleName = moduleName)
c = getattr(module, className)
You can try this out by passing in a string with with module and/or
class path and see that the module and/or class. Note that loadClass
does not create a class instance, so you'll have to instantiate it if
you want to, like this:
o = loadClass(modulePath,className)() #instantiates class that was
loaded dynamically

Ah, fantastic! I didn't know about __import__, this is basically
exactly what I need. I think I will manage, thanks a lot!

No problem, good luck.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,967
Messages
2,570,148
Members
46,694
Latest member
LetaCadwal

Latest Threads

Top