<?xml version="1.0" encoding="iso-8859-1"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
<channel>
<title>Comments on article "Python plugins continued : resources management"</title>
<link>http://base-art.net/Articles/65/</link>
<description>&lt;p&gt;Plugin developers often want to supply data files (web templates,
images, etc) with their package, let's see how to do this using
setuptools resource management system.&lt;/p&gt;
&lt;p&gt;If there are still some lazy people reading this, get an updated
version of the &lt;a class="reference" href="http://base-art.net/static/sample_plugin_system-0.1.tgz"&gt;code&lt;/a&gt;. So, on your plugin's setup.py, add a
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;package_data&lt;/span&gt;&lt;/tt&gt; argument to setup():&lt;/p&gt;
&lt;pre class="literal-block"&gt;
setup(
  # ...
  package_data = {
     'foo_plugin': ['data/*.tmpl'],
  },
  # ...
)
&lt;/pre&gt;
&lt;p&gt;Create a &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;data&lt;/span&gt;&lt;/tt&gt; directory in foo's plugin directory, and create some files:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
$ mkdir plugins/foo/data
$ echo &amp;quot;Hello this is foo\n&amp;quot; &amp;gt; plugins/foo/data/foobar.tmpl
&lt;/pre&gt;
&lt;p&gt;Don't forget to re-run &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;python&lt;/span&gt; &lt;span class="pre"&gt;setup.py&lt;/span&gt; &lt;span class="pre"&gt;develop&lt;/span&gt;&lt;/tt&gt; in the foo plugin
directory. The next step is to fetch those data files via our plugin_loader:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
for entrypoint in pkg_resources.iter_entry_points(&amp;quot;my.plugins&amp;quot;):
    plugin_class = entrypoint.load()
    print 'Plugin %s: %s' % (repr(entrypoint.name), repr(plugin_class))

    requirement = pkg_resources.Requirement.parse(plugin_class.__name__)
    tmpl = 'data/foobar.tmpl'
      
    data_contents = pkg_resources.resource_listdir(requirement, 'data')
    print 'data contents : %s' % repr(data_contents)

    # let's find and read a data file in our plugin
    if pkg_resources.resource_exists(requirement, tmpl):    
        foo_bar = pkg_resources.resource_string(requirement, tmpl)

        # contents of foobar.tmpl as a string
        print 'tmpl contents : %s' % repr(foo_bar)
    else:
        print '%s not found :-(' % repr(tmpl)
&lt;/pre&gt;
&lt;p&gt;Given the plugin's name, we tell pkg_resources to find the plugin's
resources given their relative location from the plugin point of
view. That's fun, no ? You don't need to care about a global variable
storing the full path of the data files, or whatever crappy monkey-code !&lt;/p&gt;
&lt;p&gt;I promise, next time i'll start playing with plugin API management,
probably with interfaces :-)&lt;/p&gt;
</description>
<language>en</language>
<copyright>The contents of this blog are available for non-commercial use only.</copyright>
<generator>Alinea http://pythonfr.org/alinea/</generator>


<item>
<title>Phil on Python plugins continued : resources management</title>
<link>http://base-art.net/Comments/184/</link>
<guid isPermaLink="true">http://base-art.net/Comments/184/</guid>
<description><![CDATA[
&lt;p&gt;Thanks for the tip Phillip ! The code looks better using this ;) I'll continue to play with setuptools, it's really helpful and a great step for Python packages distribution :)&lt;/p&gt;

]]></description>
<dc:creator>Phil</dc:creator>
<dc:date>2006-02-03T08:52:35Z</dc:date>
</item>

<item>
<title>Phillip J. Eby on Python plugins continued : resources management</title>
<link>http://base-art.net/Comments/183/</link>
<guid isPermaLink="true">http://base-art.net/Comments/183/</guid>
<description><![CDATA[
&lt;p&gt;Quick tip: if you use &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;entrypoint.module_name&lt;/span&gt;&lt;/tt&gt; as the first argument to the various &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;resource_foo()&lt;/span&gt;&lt;/tt&gt; APIs, your code won't be dependent on the plugin class' name being the same as the plugin egg's project name, and you won't have to mess around with &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;Requirement.parse()&lt;/span&gt;&lt;/tt&gt; for the use cases shown.  Instead, it will always look for resources relative to the package containing the plugin:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
for entrypoint in pkg_resources.iter_entry_points(&amp;quot;my.plugins&amp;quot;):
   plugin_class = entrypoint.load()
   print 'Plugin %s: %s' % (repr(entrypoint.name), repr(plugin_class))

   tmpl = 'data/foobar.tmpl'
     
   data_contents = pkg_resources.resource_listdir(entrypoint.module_name, 'data')
   print 'data contents : %s' % repr(data_contents)

   # let's find and read a data file in our plugin
   if pkg_resources.resource_exists(entrypoint.module_name, tmpl):    
       foo_bar = pkg_resources.resource_string(entrypoint.module_name, tmpl)

       # contents of foobar.tmpl as a string
       print 'tmpl contents : %s' % repr(foo_bar)
   else:
       print '%s not found :-(' % repr(tmpl)
&lt;/pre&gt;
&lt;p&gt;Also, instead of bundling data with packages, you can bundle it in the egg-info directories and get access to it with &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;entrypoint.dist.get_metadata()&lt;/span&gt;&lt;/tt&gt; and the like.  But that might be out of scope for this tutorial.&lt;/p&gt;
&lt;p&gt;Nice series, by the way, keep up the good work!&lt;/p&gt;

]]></description>
<dc:creator>Phillip J. Eby</dc:creator>
<dc:date>2006-02-02T22:15:59Z</dc:date>
</item>


</channel>
</rss>
