Ooh, I found some of the elusive documentation: <a href="http://pythonhosted.org/distribute/pkg_resources.html?highlight=iter_entry_points#convenience-api">http://pythonhosted.org/distribute/pkg_resources.html?highlight=iter_entry_points#convenience-api</a><div>

<br></div><div>Good luck!<br clear="all"><div><div>--</div>Jake Alheid<br><div><a href="http://about.me/jake" target="_blank">http://about.me/jake</a></div></div>
<br><br><div class="gmail_quote">On Tue, Feb 12, 2013 at 6:47 PM, Glen Jarvis <span dir="ltr"><<a href="mailto:glen@glenjarvis.com" target="_blank">glen@glenjarvis.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

<div dir="auto"><div>I'm still reading this and need to play with your examples. But, I think this is EXACTLY what I needed.</div><div><br></div><div>Thank you!!!!<span class="HOEnZb"><font color="#888888"><br><br>G</font></span></div>

<div><div class="h5"><div><br>On Feb 12, 2013, at 6:41 PM, Jake Alheid <<a href="mailto:shakefu@gmail.com" target="_blank">shakefu@gmail.com</a>> wrote:<br><br></div><blockquote type="cite"><div>If you want 3rd parties to be able to register runners, then entry points is a good way to go. However, since your example looks like you have control over all the files, you might want to look at runpy (<a href="http://docs.python.org/2/library/runpy.html#runpy.run_module" target="_blank">http://docs.python.org/2/library/runpy.html#runpy.run_module</a>) to import your runner's module dictionary, which can then be called. Something like:<div>



<br></div><div><font face="courier new, monospace">def get_runner(name):</font></div><div><font face="courier new, monospace">    return runpy.run_module('baypiggies.' + name)</font></div><div><font face="courier new, monospace"><br>



</font></div><div><font face="courier new, monospace">get_runner('fruit')['chew']()</font></div><div><div><br></div><div>The documentation is really terrible for setuptools... I can't remember what I originally read that helped me grok what was going.<br>



<div><br></div><div>If you really want to use entry points for this, you want to define it in your setup.py, and do something like:</div><div><br></div><div><font face="courier new, monospace">entry_points = {</font></div>



<div><font face="courier new, monospace">    'baypiggies':[</font></div><div><font face="courier new, monospace">        'fruit = baypiggies.fruit',</font></div><div><font face="courier new, monospace">        'meta = baypiggies.meat',</font></div>



<div><font face="courier new, monospace">        'mock = baypiggies.mock',</font></div><div><font face="courier new, monospace">    ],</font></div><div><font face="courier new, monospace">},</font></div><div><br>


</div>
<div>This just registers those namespaces (modules in this case) with setuptools/pkg_resources for later consumption. You consume using iter_entry_points:</div><div><br></div><div><font face="courier new, monospace">def get_runner_module(name):</font></div>



<div><font face="courier new, monospace">    """ Return a module for `name`. """</font></div><div><span style="font-family:'courier new',monospace">    # This looks for the first entry point with `name` in the 'baypiggies'</span></div>



<div><font face="courier new, monospace">    for entry in pkg_resources.iter_entry_points('baypiggies', name):</font></div><div><font face="courier new, monospace">        # Return the loaded module or object, or raise ImportError</font></div>



<div><span style="font-family:'courier new',monospace">        return entry.load()</span></div><div><br></div><div>If you don't want the module in sys.modules, use runpy instead, and replace the last line with:</div>



<div><br></div><div><font face="courier new, monospace">        # Return the module's namespace dictionary</font></div><div><font face="courier new, monospace">        return runpy.run_module(entry.module_name)</font></div>



<div><div><div><br></div><div>Of course, using entry_points will also allow third party packages to register with your runner using the 'baypiggies' entry point. You could allow for that, and get a list of all registered names, like:</div>



<div><br></div><div><font face="courier new, monospace">def get_registered_names():</font></div><div><font face="courier new, monospace">    names = []</font></div><div><font face="courier new, monospace">    for entry in pkg_resources.iter_entry_points('baypiggies'):</font></div>



<div><span style="font-family:'courier new',monospace">        names.append(<a href="http://entry.name" target="_blank">entry.name</a>)</span></div><div><font face="courier new, monospace">    return names</font></div>

<div><br></div>

<div>Hope this helps!</div><div>--</div>Jake Alheid<br><div><a href="http://about.me/jake" target="_blank">http://about.me/jake</a></div></div>
<br><br><div class="gmail_quote">On Tue, Feb 12, 2013 at 5:00 PM, Glen Jarvis <span dir="ltr"><<a href="mailto:glen@glenjarvis.com" target="_blank">glen@glenjarvis.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">



I have a directory like this:<div><br><div>baypiggies<br><div><div>   - __init__.py</div><div>   - fruit.py</div><div>   - meat.py</div><div>   - mock.py</div><div>   - runner.py</div><div><br></div><div>My runner.py is the main entry point and it is used to dynamically chose which of these other files to import.</div>




<div><br></div><div><div># pylint: disable=C0103,R0904</div><div><br></div><div>"""A sample dynamically loaded example with endpoints</div><div><br></div><div>./runner.py --backend=fruit</div><div>"""</div>




<div><br></div><div>from optparse import OptionParser</div><div><br></div><div><br></div><div>entry_points = {</div><div>    'fruit': dict(</div><div>        thump = ('fruit', 'thump'),</div><div>



        eat = ('fruit', 'eat'),</div>
<div>        chew = ('fruit', 'chew'),</div><div>    ),</div><div>    'meat': dict(</div><div>        thump = ('meat', 'thump'),</div><div>        eat = ('meat', 'eat'),</div>




<div>        chew = ('meat', 'chew'),</div><div>    ),</div><div>    'mock': dict(</div><div>        thump = ('mock', 'thump'),</div><div>        eat = ('mock', 'eat'),</div>




<div>        chew = ('mock', 'chew'),</div><div>    ),</div><div>    'custom1': dict(</div><div>        thump = ('myns.mypkg.mymodule', 'thump'),</div><div>        eat = ('myns.mypkg.mymodule', 'eat'),</div>




<div>        chew = ('myns.mypkg.mymodule', 'chew'),</div><div>    ),</div><div>}</div><div><br></div></div><div><div>def import_entry_points(entries):</div><div><br></div><div>    """Dynamically import the functions for the specified backend</div>




<div><br></div><div>    entry_points is a global dictionary whos keys correspond to each</div><div>    of the different types of backends that we can support. The variable</div><div>    options.backend specifies which of the backends that will be used</div>




<div>    during this program run.</div><div><br></div><div>    The value of entry_points (for options.backend) is another</div><div>    dictionary which map the functions needed to the modules from where</div><div>    we will import these modules. We only want to import the backend</div>




<div>    modules that will be used (and not have unnecessary dependencies).</div><div><br></div><div>    This module will replace the values in this inner dictionary with</div><div>    the imported functions. This way, the functions are imported and</div>




<div>    available when needed.</div><div>    """</div><div><br></div><div>    for entry in entries:</div><div>        module, name = entries[entry]</div><div>        _temp = __import__(module, globals(), locals(), [name], 0)</div>




<div>        entries[entry] = getattr(_temp, entry)</div><div><br></div><div><br></div><div>def run(backend="mock"):</div><div>    print "Running, backend: ", backend</div><div>    import_entry_points(entry_points[backend])</div>




<div><br></div><div>    import pprint</div><div>    pprint.pprint(entry_points)</div><div><br></div><div>    print "THUMPING..."</div><div>    entry_points[backend]["thump"]()</div><div><br></div><div>




    print "EATING..."</div><div>    entry_points[backend]["eat"]()</div><div><br></div><div>    print "CHEWING..."</div><div>    # Chew five times</div><div>    entry_points[backend]["chew"](5)</div>




<div><br></div><div>if __name__ == "__main__":</div><div>    parser = OptionParser()</div><div>    parser.add_option("-b", "--backend", dest="backend",</div><div>                      default="mock",</div>




<div>                      help="Choose which backend to run.")</div><div><br></div><div>    (options, args) = parser.parse_args()</div><div>    run(options.backend)</div></div><div><br></div><div><br></div><div>




<br></div><div>Now, as you can see, the backends are loaded dynamically depending upon the command line options (let's only import what we need).</div><div><br></div><div><div>prompt> python runner.py </div><div>Running, backend:  mock</div>




<div>{'custom1': {'chew': ('myns.mypkg.mymodule', 'chew'),</div><div>             'eat': ('myns.mypkg.mymodule', 'eat'),</div><div>             'thump': ('myns.mypkg.mymodule', 'thump')},</div>




<div> 'fruit': {'chew': ('fruit', 'chew'),</div><div>           'eat': ('fruit', 'eat'),</div><div>           'thump': ('fruit', 'thump')},</div>




<div> 'meat': {'chew': ('meat', 'chew'),</div><div>          'eat': ('meat', 'eat'),</div><div>          'thump': ('meat', 'thump')},</div><div>




 'mock': {'chew': <function chew at 0x10c3e1aa0>,</div><div>          'eat': <function eat at 0x10c3e1a28>,</div><div>          'thump': <function thump at 0x10c3e19b0>}}</div>




<div>THUMPING...</div><div>Pretend to thump</div><div>EATING...</div><div>Pretend to eat</div><div>CHEWING...</div><div>Prentend to chew</div></div><div><br></div><div><br></div><div>And, totally new/different backend if I choose the option:</div>




<div><br></div><div><br></div><div><div>Running, backend:  fruit</div><div>{'custom1': {'chew': ('myns.mypkg.mymodule', 'chew'),</div><div>             'eat': ('myns.mypkg.mymodule', 'eat'),</div>




<div>             'thump': ('myns.mypkg.mymodule', 'thump')},</div><div> 'fruit': {'chew': <function chew at 0x103a11aa0>,</div><div>           'eat': <function eat at 0x103a11a28>,</div>




<div>           'thump': <function thump at 0x103a119b0>},</div><div> 'meat': {'chew': ('meat', 'chew'),</div><div>          'eat': ('meat', 'eat'),</div>




<div>          'thump': ('meat', 'thump')},</div><div> 'mock': {'chew': ('mock', 'chew'),</div><div>          'eat': ('mock', 'eat'),</div><div>




          'thump': ('mock', 'thump')}}</div><div>THUMPING...</div><div>Thumping fruit...</div><div>EATING...</div><div>Eating fruit.. very healthy....</div><div>CHEWING...</div><div>Fruit chew  0</div>




<div>Fruit chew  1</div><div>Fruit chew  2</div><div>Fruit chew  3</div><div>Fruit chew  4</div></div><div><br></div><div><br></div><div><br></div><div>Here are examples of my backends:</div><div><br></div><div><br></div>




<div><br></div><div><br></div><div><div>"""An empty mock (Currently not implemented)"""</div><div><br></div><div><br></div><div>def thump():</div><div><br></div><div>    print "Pretend to thump"</div>




<div><br></div><div><br></div><div>def eat():</div><div><br></div><div>    print "Pretend to eat"</div><div><br></div><div><br></div><div>def chew(number_of_times):</div><div><br></div><div>    print "Prentend to chew"</div>




</div><div><br></div><div><br></div><div><br></div><div><br></div><div>Here's the mock one (by default):</div><div><div><br></div><div><br></div><div>def thump():</div><div><br></div><div>    print "Pretend to thump"</div>




<div><br></div><div><br></div><div>def eat():</div><div><br></div><div>    print "Pretend to eat"</div><div><br></div><div><br></div><div>def chew(number_of_times):</div><div><br></div><div>    print "Prentend to chew"</div>




</div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div>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).:</div>




<div><br></div><div><a href="http://stackoverflow.com/questions/774824/explain-python-entry-points/9615473#9615473" target="_blank">http://stackoverflow.com/questions/774824/explain-python-entry-points/9615473#9615473</a></div>



<div><br></div>
<div>Can someone help me by example? I'm confused... </div><div><br></div><div><br></div><div>Cheers,</div><div><br></div><div><br></div><div>Glen</div><div>--</div>







<p>"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."</p>
<p>--Henry David Thoreau</p>
</div></div></div>
<br>_______________________________________________<br>
Baypiggies mailing list<br>
<a href="mailto:Baypiggies@python.org" target="_blank">Baypiggies@python.org</a><br>
To change your subscription options or unsubscribe:<br>
<a href="http://mail.python.org/mailman/listinfo/baypiggies" target="_blank">http://mail.python.org/mailman/listinfo/baypiggies</a><br></blockquote></div><br></div></div></div>
</div></blockquote></div></div></div></blockquote></div><br></div>