[Baypiggies] Entry points help

Glen Jarvis glen at glenjarvis.com
Wed Feb 13 03:21:16 CET 2013


Thanks Malcolm. Yeah, I simplified the structure for my needs. I will need to update struct when we update. But the real question comes into how to use the library properly -- I'm still not sure.

G

On Feb 12, 2013, at 5:18 PM, malcolm <malcolm at hoprocker.net> wrote:

> Hey Glen
> 
> I've got no idea if this matters -- haven't used this before -- but comparing your entry_point structure against then one the SO post, it looks as though you've missed the type definitions by a bit. The poster on SO structured his entry_points like so:
> 
> entry_points = {        # <-- dict
>    'group_name' :  [            # <-- list
>          'ep_func =  module:attr',
>          ..
>      
> Whereas you've structured yours like so:
> 
> entry_points = {        # <-- dict
>     'group_name': dict(           # <-- dict
>             'name' = (tuple),
>             ..
> 
> I also found the SO structure used here: http://reinout.vanrees.org/weblog/2010/01/06/zest-releaser-entry-points.html
> 
> Like I said, I've never toyed with this corner of packaging, but maybe this can shed some light.
> 
> -m
> 
> On Tue, Feb 12, 2013 at 5:00 PM, Glen Jarvis <glen at glenjarvis.com> wrote:
>> I have a directory like this:
>> 
>> baypiggies
>>    - __init__.py
>>    - fruit.py
>>    - meat.py
>>    - mock.py
>>    - runner.py
>> 
>> My runner.py is the main entry point and it is used to dynamically chose which of these other files to import.
>> 
>> # pylint: disable=C0103,R0904
>> 
>> """A sample dynamically loaded example with endpoints
>> 
>> ./runner.py --backend=fruit
>> """
>> 
>> from optparse import OptionParser
>> 
>> 
>> entry_points = {
>>     'fruit': dict(
>>         thump = ('fruit', 'thump'),
>>         eat = ('fruit', 'eat'),
>>         chew = ('fruit', 'chew'),
>>     ),
>>     'meat': dict(
>>         thump = ('meat', 'thump'),
>>         eat = ('meat', 'eat'),
>>         chew = ('meat', 'chew'),
>>     ),
>>     'mock': dict(
>>         thump = ('mock', 'thump'),
>>         eat = ('mock', 'eat'),
>>         chew = ('mock', 'chew'),
>>     ),
>>     'custom1': dict(
>>         thump = ('myns.mypkg.mymodule', 'thump'),
>>         eat = ('myns.mypkg.mymodule', 'eat'),
>>         chew = ('myns.mypkg.mymodule', 'chew'),
>>     ),
>> }
>> 
>> def import_entry_points(entries):
>> 
>>     """Dynamically import the functions for the specified backend
>> 
>>     entry_points is a global dictionary whos keys correspond to each
>>     of the different types of backends that we can support. The variable
>>     options.backend specifies which of the backends that will be used
>>     during this program run.
>> 
>>     The value of entry_points (for options.backend) is another
>>     dictionary which map the functions needed to the modules from where
>>     we will import these modules. We only want to import the backend
>>     modules that will be used (and not have unnecessary dependencies).
>> 
>>     This module will replace the values in this inner dictionary with
>>     the imported functions. This way, the functions are imported and
>>     available when needed.
>>     """
>> 
>>     for entry in entries:
>>         module, name = entries[entry]
>>         _temp = __import__(module, globals(), locals(), [name], 0)
>>         entries[entry] = getattr(_temp, entry)
>> 
>> 
>> def run(backend="mock"):
>>     print "Running, backend: ", backend
>>     import_entry_points(entry_points[backend])
>> 
>>     import pprint
>>     pprint.pprint(entry_points)
>> 
>>     print "THUMPING..."
>>     entry_points[backend]["thump"]()
>> 
>>     print "EATING..."
>>     entry_points[backend]["eat"]()
>> 
>>     print "CHEWING..."
>>     # Chew five times
>>     entry_points[backend]["chew"](5)
>> 
>> if __name__ == "__main__":
>>     parser = OptionParser()
>>     parser.add_option("-b", "--backend", dest="backend",
>>                       default="mock",
>>                       help="Choose which backend to run.")
>> 
>>     (options, args) = parser.parse_args()
>>     run(options.backend)
>> 
>> 
>> 
>> Now, as you can see, the backends are loaded dynamically depending upon the command line options (let's only import what we need).
>> 
>> prompt> python runner.py 
>> Running, backend:  mock
>> {'custom1': {'chew': ('myns.mypkg.mymodule', 'chew'),
>>              'eat': ('myns.mypkg.mymodule', 'eat'),
>>              'thump': ('myns.mypkg.mymodule', 'thump')},
>>  'fruit': {'chew': ('fruit', 'chew'),
>>            'eat': ('fruit', 'eat'),
>>            'thump': ('fruit', 'thump')},
>>  'meat': {'chew': ('meat', 'chew'),
>>           'eat': ('meat', 'eat'),
>>           'thump': ('meat', 'thump')},
>>  'mock': {'chew': <function chew at 0x10c3e1aa0>,
>>           'eat': <function eat at 0x10c3e1a28>,
>>           'thump': <function thump at 0x10c3e19b0>}}
>> THUMPING...
>> Pretend to thump
>> EATING...
>> Pretend to eat
>> CHEWING...
>> Prentend to chew
>> 
>> 
>> And, totally new/different backend if I choose the option:
>> 
>> 
>> Running, backend:  fruit
>> {'custom1': {'chew': ('myns.mypkg.mymodule', 'chew'),
>>              'eat': ('myns.mypkg.mymodule', 'eat'),
>>              'thump': ('myns.mypkg.mymodule', 'thump')},
>>  'fruit': {'chew': <function chew at 0x103a11aa0>,
>>            'eat': <function eat at 0x103a11a28>,
>>            'thump': <function thump at 0x103a119b0>},
>>  'meat': {'chew': ('meat', 'chew'),
>>           'eat': ('meat', 'eat'),
>>           'thump': ('meat', 'thump')},
>>  'mock': {'chew': ('mock', 'chew'),
>>           'eat': ('mock', 'eat'),
>>           'thump': ('mock', 'thump')}}
>> THUMPING...
>> Thumping fruit...
>> EATING...
>> Eating fruit.. very healthy....
>> CHEWING...
>> Fruit chew  0
>> Fruit chew  1
>> Fruit chew  2
>> Fruit chew  3
>> Fruit chew  4
>> 
>> 
>> 
>> Here are examples of my backends:
>> 
>> 
>> 
>> 
>> """An empty mock (Currently not implemented)"""
>> 
>> 
>> def thump():
>> 
>>     print "Pretend to thump"
>> 
>> 
>> def eat():
>> 
>>     print "Pretend to eat"
>> 
>> 
>> def chew(number_of_times):
>> 
>>     print "Prentend to chew"
>> 
>> 
>> 
>> 
>> Here's the mock one (by default):
>> 
>> 
>> def thump():
>> 
>>     print "Pretend to thump"
>> 
>> 
>> def eat():
>> 
>>     print "Pretend to eat"
>> 
>> 
>> def chew(number_of_times):
>> 
>>     print "Prentend to chew"
>> 
>> 
>> 
>> 
>> 
>> So, I'm supposed to be using entry points from the setuptools library (instead of the above). But, I've googled and get stuck. I just don't see how to use it (and use it without doing a setup each time).:
>> 
>> http://stackoverflow.com/questions/774824/explain-python-entry-points/9615473#9615473
>> 
>> Can someone help me by example? I'm confused... 
>> 
>> 
>> Cheers,
>> 
>> 
>> Glen
>> --
>> "Pursue, keep up with, circle round and round your life as a dog does his master's chase. Do what you love. Know your own bone; gnaw at it, bury it, unearth it, and gnaw it still."
>> 
>> --Henry David Thoreau
>> 
>> 
>> _______________________________________________
>> Baypiggies mailing list
>> Baypiggies at python.org
>> To change your subscription options or unsubscribe:
>> http://mail.python.org/mailman/listinfo/baypiggies
> 
> _______________________________________________
> Baypiggies mailing list
> Baypiggies at python.org
> To change your subscription options or unsubscribe:
> http://mail.python.org/mailman/listinfo/baypiggies
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/baypiggies/attachments/20130212/7e1d15ae/attachment.html>


More information about the Baypiggies mailing list