<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Mainly Data</title>
	<atom:link href="http://mainlydata.kubadev.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://mainlydata.kubadev.com</link>
	<description>Hopefully Helpful</description>
	<lastBuildDate>Sun, 11 Nov 2012 09:29:31 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.4.2</generator>
		<item>
		<title>repoze.catalog and ZODB beginners example &#8211; part 2</title>
		<link>http://mainlydata.kubadev.com/python/repoze-catalog-and-zodb-beginners-example-part-2/</link>
		<comments>http://mainlydata.kubadev.com/python/repoze-catalog-and-zodb-beginners-example-part-2/#comments</comments>
		<pubDate>Sun, 11 Nov 2012 09:29:31 +0000</pubDate>
		<dc:creator>adminrs</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[zodb repoze.catalog example tutorial]]></category>

		<guid isPermaLink="false">http://mainlydata.kubadev.com/?p=593</guid>
		<description><![CDATA[A beginners example of retrieving objects from ZODB after having indexed them with repoze.catalog. Part two of a two part series.]]></description>
			<content:encoded><![CDATA[<h1>repoze.catalog and ZODB beginners example &#8211; part 2</h1>
<h2>Summary</h2>
<p>The second of two posts which illustrate how to use <a title="repoze.catalog home page" href="http://docs.repoze.org/catalog/">repoze.catalog</a> alongside <a title="ZODB Home Page" href="http://www.zodb.org/">ZODB</a>. The first post can be seen at: &#8220;<a title="part one of this two part blog post" href="http://mainlydata.kubadev.com/python/repoze-catalog-and-zodb-beginners-example-part-1/">repoze.catalog and ZODB beginners example &#8211; part 1</a>&#8221; .</p>
<h2>Where we&#8217;re up to</h2>
<p>In the <a title="repoze catalog and zodb beginners example part 1" href="http://mainlydata.kubadev.com/python/repoze-catalog-and-zodb-beginners-example-part-1/">first post</a> I explained how you can have objects stored within a ZODB database indexed by repoze.catalog and why that was sometimes a good idea. In this post I&#8217;m going to demonstrate searching for the previously stored objects using repoze.catalog&#8217;s search facilities. If you haven&#8217;t read the <a title="repoze.catalog and ZODB beginners example – part 1" href="http://mainlydata.kubadev.com/python/repoze-catalog-and-zodb-beginners-example-part-1/">first post </a>I suggest you read that now because what follows assumes you have.</p>
<h2>Finding ZODB objects with repoze.catalog</h2>
<p>As discussed in the <a title="part one of this two part blog post" href="http://mainlydata.kubadev.com/python/repoze-catalog-and-zodb-beginners-example-part-1/">first post </a>repoze.catalog allows you to index arbitrary properties of the objects you save into a ZODB database and then do complex searches on those properties to extract only the objects you&#8217;re interested in.</p>
<p>The example I&#8217;m showing here demonstrates how we can search through those objects we added in the example of the last post using a number of criteria.</p>
<h2>Example Code</h2>
<p>Here&#8217;s my example code and underneath I&#8217;ll expand a little more on what each part does:</p>
<pre class="brush: python; title: ; notranslate">
'''
Demonstrates how to use repoze.catalog to find objects
being stored in ZODB. This example has the catalog and ZODB
within the same repository
'''
from myzodb import MyZODB
from persistent import Persistent

from repoze.catalog.catalog import FileStorageCatalogFactory
from repoze.catalog.catalog import ConnectionManager
from repoze.catalog.query import InRange, Lt

class City(Persistent):
    '''Represents a City by name and population'''
    def __init__(self, cityname, citypop):
        self.name = cityname
        self.population = citypop
    def __str__(self):
        return &quot;%s  (Pop: %s)&quot; % \
                (self.name, \
                str(self.population))

def print_all_city_instances(myzodbinst):
    '''
    Pull everything keyed under 'cities' out of the
    ZODB instance (without any regard to the
    repoze.catalog cataloguing and print them
    '''
    print &quot;&quot;
    print &quot;About to dump all City Instances:&quot;
    for acity in myzodbinst.dbroot['cities'].itervalues():
        print acity
    print &quot;&quot;

def print_city_query_results(myzodbinst, res):
    '''
    Use the list of integers returned by a
    repoze.catalog query to pull elements
    keyed underneath 'cities' in the ZODB
    instance which we are using repoze.catalog
    to catalogue
    '''
    print &quot;&quot;
    print &quot;Objects stored in ZODB corresponding&quot;
    print &quot;to the repoze.catalog resultset:&quot;
    for idx in res:
        print myzodbinst.dbroot['cities'][idx]
    print &quot;&quot;

if __name__ == '__main__':
    #Setup access to the repoze.catalog instance
    factory = FileStorageCatalogFactory('../data/mdcatalog.db',
                                        'mycatalog')
    manager = ConnectionManager()
    catalog = factory(manager)
    #Setup access to the ZODB instance containing data
    #catalogued by the repoze.catalog instance
    myzodbinstance = MyZODB('../data/mdzdb.fs')
    #Demonstrate we really have all the Cities
    print_all_city_instances(myzodbinstance)
    #Demonstrate use of `Lt` on the `population` index
    print &quot;&quot;
    print &quot;*&quot; * 60
    print &quot;Looking for 'less than' value on the `population` index&quot;
    print &quot;Populations less than 1,000,000&quot;
    numdocs, results = catalog.query(Lt('populations', 1000000))
    print &quot;Raw Result: &quot;
    print (numdocs, [ x for x in results ])
    print_city_query_results(myzodbinstance, results)

    #Demonstrate use of `InRange` on the `population` index
    print &quot;&quot;
    print &quot;*&quot; * 60
    print &quot;Looking for 'InRange' values on the `population` index&quot;
    print &quot;Populations between 1,000,000 and 4,000,000&quot;
    numdocs, results = catalog.query(InRange('populations',
                                              1000000, 4000000))
    print &quot;Raw Result: &quot;
    print (numdocs, [ x for x in results ])
    print_city_query_results(myzodbinstance, results)
</pre>
<h2>Example Step by Step</h2>
<p>Here&#8217;s a breakdown on what&#8217;s happening in the above example</p>
<h3>Initialize repoze.catalog</h3>
<pre class="brush: python; title: ; notranslate">
factory = FileStorageCatalogFactory('../data/mdcatalog.db', 'mycatalog')
manager = ConnectionManager()
catalog = factory(manager)
</pre>
<p>Here we connect to our repoze.catalog repository and instantiate a `catalog` object</p>
<h3>Make our ZODB database ready for use</h3>
<pre class="brush: python; title: ; notranslate">
myzodbinstance = MyZODB('../data/mdzdb.fs')
</pre>
<p>`MyZODB` is a convenience class which wraps up the instantiation of a ZODB database instance and provides : `storage`; `db`;`connection`; and `dbroot` properties to help the programmer interact with the ZODB database, connection, storage objects. `MyZODB` also provides a close method to cleanly close the ZODB database, connection and storage.</p>
<p>`MyZODB` is not explicitly included in the above example but it looks like this :</p>
<pre class="brush: python; title: ; notranslate">
from ZODB import FileStorage, DB
class MyZODB(object):
    '''Manage the state of a ZODB FileStorage connection'''
    def __init__(self, path):
        self.storage = FileStorage.FileStorage(path)
        self.db = DB(self.storage)
        self.connection = self.db.open()
        self.dbroot = self.connection.root()
    def close(self):
        self.connection.close()
        self.db.close()
        self.storage.close()&lt;/pre&gt;
</pre>
<h3>Dump contents of ZODB without using repoze.catalog</h3>
<p>The first data access we do in the above example is just a simple dump of every object, held under the key &#8216;cities&#8217;, in our ZODB database. Notice we are not using repoze.catalog at all at this point. By viewing this data we can be sure that the subsequent queries using repoze.catalog do what we think they do.</p>
<p>So we call the function `print_all_city_instances`</p>
<pre class="brush: python; title: ; notranslate">
print_all_city_instances(myzodbinstance)
</pre>
<p>which iterates over the &#8216;cities&#8217; element of the `dbroot` property of the ZODB `connection` to allow us to see everything that&#8217;s in the ZODB database.</p>
<pre class="brush: python; title: ; notranslate">
for acity in myzodbinst.dbroot['cities'].itervalues():
    print acity
</pre>
<p>Our output looks like this :</p>
<pre class="brush: plain; title: ; notranslate">
About to dump all City Instances:
Windhoek  (Pop: 322500)
Pretoria  (Pop: 525387)
Nairobi  (Pop: 3138295)
Maputo  (Pop: 1244227)
Jakarta  (Pop: 10187595)
Canberra  (Pop: 358222)
Wellington  (Pop: 393400)
Santiago  (Pop: 5428590)
Buenos Aires  (Pop: 2891082)
</pre>
<h3>Demonstrating the `Lt` function of repoze.catalog</h3>
<p>The next thing that happens in the sample is to make use of the `<a title="Comparator methods from repoze.catalog.query" href="http://docs.repoze.org/catalog/api.html#comparators">Lt</a>` function offered by repoze.catalog</p>
<pre class="brush: python; title: ; notranslate">
numdocs, results = catalog.query(Lt('populations', 1000000))
</pre>
<p>In the <a title="part one of this two part blog post" href="http://mainlydata.kubadev.com/python/repoze-catalog-and-zodb-beginners-example-part-1/">previous post</a> when we initialized our repoze.catalog we created a `populations` index which was associated with the `population` property of our `City` class (take a look at the previous post if you&#8217;ve forgotten the details).</p>
<p>Our use of the `<a title="Comparator methods from repoze.catalog.query" href="http://docs.repoze.org/catalog/api.html#comparators">Lt</a>` method asks repoze.catalog to find all `City` instances stored in our ZODB database with a population of less than 1,000,000. As you can see we get two objects returned which I&#8217;ve named `numdocs` and `results`.</p>
<p>`numdocs` is an integer showing how many instances have been found which meet the criteria.</p>
<p>`results` is a list of integers which are keys used when storing into ZODB those objects which satisfy the search criteria.</p>
<p>We then use our function</p>
<pre class="brush: python; title: ; notranslate">
print_city_query_results(myzodbinstance, results)
</pre>
<p>to output the objects found. The resulting output looks like this :</p>
<pre class="brush: plain; title: ; notranslate">
Objects stored in ZODB corresponding
to the repoze.catalog resultset:
Windhoek  (Pop: 322500)
Pretoria  (Pop: 525387)
Canberra  (Pop: 358222)
Wellington  (Pop: 393400)

</pre>
<p>It&#8217;s worth mentioning that whilst there are many comporator methods offered by repoze.catalog.query not all of them are applicable to all index types. In this example of the `Lt` method we are searching on an index, &#8216;populations&#8217; of type <a title="CatalogTextIndex doco" href="http://docs.repoze.org/catalog/api.html?highlight=catalogtextindex#repoze.catalog.indexes.text.CatalogTextIndex">CatalogTextIndex</a> which does offer the `Lt` method but not all do.</p>
<h3>Demonstrating the `InRange` function of repoze.catalog</h3>
<p>Finally in the sample we show off the `InRange` function offered by repoze.catalog</p>
<pre class="brush: python; title: ; notranslate">
 numdocs, results = catalog.query(InRange('populations',
                                          1000000, 4000000))

</pre>
<p>As with the previous example we utilise the previously created catalog index &#8216;populations&#8217; to find instances of `City` &#8211; in this case those instances that have their `population` property set to a value between 1,000,000 and 4,000,000.</p>
<p>We do this by using the  `InRange` method offered by repoze.catalog. As with the `Lt` example above we get two objects returned which I&#8217;ve named `numdocs` and `results`.</p>
<p>`numdocs` is an integer showing how many instances have been found which meet the criteria.</p>
<p>`results` is a list of integers which are keys used when storing into ZODB those objects which satisfy the search critiera.</p>
<p>We then use our function</p>
<pre class="brush: python; title: ; notranslate">
print_city_query_results(myzodbinstance, results)
</pre>
<p>to output the objects found. The resulting output looks like this :</p>
<pre class="brush: plain; title: ; notranslate">
Objects stored in ZODB corresponding
to the repoze.catalog resultset:
Nairobi  (Pop: 3138295)
Maputo  (Pop: 1244227)
Buenos Aires  (Pop: 2891082)

</pre>
<h2>Credit where credits due</h2>
<p>As with part one of this two part post the example I&#8217;ve shown here owes some parts to <a title="'indexing' example code from repoze.org website" href="http://docs.repoze.org/catalog/usage.html#indexing">one of the examples</a> on the repoze.catalog website and the structure of the `myZODB` was taken from the article cited above,  &#8216;<a title="How to use an object database with a Python, a dynamic object-oriented language" href="http://www.ibm.com/developerworks/aix/library/au-zodb/">Example Driven ZODB</a>&#8216; .</p>
]]></content:encoded>
			<wfw:commentRss>http://mainlydata.kubadev.com/python/repoze-catalog-and-zodb-beginners-example-part-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>repoze.catalog and ZODB beginners example &#8211; part 1</title>
		<link>http://mainlydata.kubadev.com/python/repoze-catalog-and-zodb-beginners-example-part-1/</link>
		<comments>http://mainlydata.kubadev.com/python/repoze-catalog-and-zodb-beginners-example-part-1/#comments</comments>
		<pubDate>Mon, 05 Nov 2012 06:50:56 +0000</pubDate>
		<dc:creator>adminrs</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[zodb repoze.catalog example tutorial]]></category>

		<guid isPermaLink="false">http://mainlydata.kubadev.com/?p=548</guid>
		<description><![CDATA[A beginners example of using ZODB and repoze.catalog to store objects into ZODB and have them indexed by repoze.catalog]]></description>
			<content:encoded><![CDATA[<h1>repoze.catalog and ZODB beginners example &#8211; part 1</h1>
<h2>Summary</h2>
<p>The first of two posts which illustrate how to use repoze.catalog alongside ZODB</p>
<h2>What&#8217;s ZODB ?</h2>
<p>To quote the <a title="ZODB Home Page" href="http://www.zodb.org/">ZODB</a> home page :</p>
<blockquote><p>&#8220;The ZODB is a native object database, that stores your objects while allowing you to work with any paradigms that can be expressed in Python. Thereby your code becomes simpler, more robust and easier to understand&#8221;</p></blockquote>
<h2>What&#8217;s repoze.catalog ?</h2>
<p><a title="repoze.catalog home page" href="http://docs.repoze.org/catalog/">repoze.catalog</a> is one of a number of frameworks which can be used to supply indexing for ZODB for those circumstances where accessing objects stored in ZODB would otherwise be unacceptably slow</p>
<h2>Intended Audience</h2>
<p>I&#8217;m assuming that readers of this post have a basic familiarity with ZODB. If you don&#8217;t there are lots of good resources out there of which &#8216;<a title="How to use an object database with a Python, a dynamic object-oriented language" href="http://www.ibm.com/developerworks/aix/library/au-zodb/">Example Driven ZODB</a>&#8216; is a good example.</p>
<h2>What&#8217;s the purpose of this post ?</h2>
<p>For any reasonably experienced Python programmer using ZODB and repoze.catalog is pretty straightforward. Unfortunately a new user of repoze.catalog cannot find an example on the repoze.catalog site which shows both how to catalog items and save them into ZODB. This is understandable as repoze.catalog is not only for use with ZODB but I thought it was worthwhile doing a specific example for that scenario and that&#8217;s what on this page.</p>
<h2>Where repoze.catalog helps ZODB</h2>
<p>Because of the nature of ZODB it&#8217;s easy to access objects by the value they&#8217;re keyed on but otherwise it&#8217;s a question of a sequential search.</p>
<p>So instances of a class that look like this :</p>
<pre class="brush: python; title: ; notranslate">
class Country(Persistent):
    def __init__(self, pop):
        self.name = name
        self.population = pop
</pre>
<p>Might be saved into the `root` property of a ZODB `connection` object like this :</p>
<pre class="brush: python; title: ; notranslate">
root['un']['nz'] = Country('New Zealand', 4000000)
</pre>
<p>But subsequently if we wanted to obtain `Country` instances on the basis of population the key doesn&#8217;t help us at all and a scan of all `Country` objects would be necessary, like this :</p>
<pre class="brush: python; title: ; notranslate">
for cou in root['un'].itervalues():
    if cou.population &gt; 1000000:
        print cou.name
</pre>
<p>When we use repoze.catalog to catalogue a ZODB database we specify properties of objects that will be saved in ZODB and which interest us and by which will subsequently want to find the objects.</p>
<p>repoze.catalog allows us quickly and easily search for objects with property values that interest us.</p>
<h2>Example Code</h2>
<p>Here&#8217;s my example code and underneath I&#8217;ll expand a little more on what each part does:</p>
<pre class="brush: python; title: ; notranslate">
'''
Demonstrates how to use repoze.catalog to catalogue objects
being stored in ZODB. This example has the catalog and ZODB
database as seperate repositories
'''
from repoze.catalog.catalog import FileStorageCatalogFactory
from repoze.catalog.catalog import ConnectionManager

from repoze.catalog.indexes.field import CatalogFieldIndex
from repoze.catalog.indexes.text import CatalogTextIndex

import transaction
from persistent import Persistent
from BTrees.OOBTree import OOBTree

from myzodb import MyZODB

factory = FileStorageCatalogFactory('../data/mdcatalog.db', 'mycatalog')

_initialized = False

def initialize_catalog():
    '''
    Create a repoze.catalog instance and specify
    indices of intereset

    NB: Use of global variable
    '''
    global _initialized
    if not _initialized:
        # create a catalog
        manager = ConnectionManager()
        catalog = factory(manager)
        # set up indexes
        catalog['names'] = CatalogTextIndex('name')
        catalog['populations'] = CatalogFieldIndex('population')
        # commit the indexes
        manager.commit()
        manager.close()
        _initialized = True

class City(Persistent):
    '''Represents a City by name and population'''
    def __init__(self, cityname, citypop):
        self.name = cityname
        self.population = citypop
    def __str__(self):
        return &quot;%s  (Pop: %s)&quot; % \
                (self.name, \
                str(self.population))

if __name__ == '__main__':
    initialize_catalog()
    manager = ConnectionManager()
    catalog = factory(manager)
    myzodbinstance = MyZODB('../data/mdzdb.fs')
    myzodbinstance.dbroot['cities'] = OOBTree()

    #For ease of demonstration set up a local dict
    #containing a number of `City` instances keyed
    #by a unique integer
    cities = {
        1:City('Windhoek', 322500),
        2:City('Pretoria', 525387),
        3:City('Nairobi', 3138295),
        4:City('Maputo', 1244227),
        5:City('Jakarta', 10187595),
        6:City('Canberra', 358222),
        7:City('Wellington', 393400),
        8:City('Santiago', 5428590),
        9:City('Buenos Aires', 2891082),
    }
    #Iterate over our local dict and for each
    #element generate the catlog entry for
    #repoze.catalog and add the corresponding
    #instance to the ZODB database we are
    #cataloguing
    for docid, doc in cities.items():
        catalog.index_doc(docid, doc)
        myzodbinstance.dbroot['cities'][docid] = doc
        transaction.commit()

    myzodbinstance.close()
</pre>
<h2>Example Step by Step</h2>
<p>Here&#8217;s a breakdown on what&#8217;s happening in the above example</p>
<h3>Initialize repoze.catalog</h3>
<pre class="brush: python; title: ; notranslate">
initialize_catalog()
manager = ConnectionManager()
catalog = factory(manager)
</pre>
<p>The `initialize_catalog` function creates a repoze.catalog instance and initializes two indices : `names` and `populations`. These index the `name` and `population` properties of any objects indexed with the repoze.catalog instance just created</p>
<h3>Make our ZODB database ready for use</h3>
<pre class="brush: python; title: ; notranslate">
myzodbinstance = MyZODB('../data/mdzdb.fs')
</pre>
<p>`MyZODB` is a convenience class which wraps up the instantiation of a ZODB database instance and provides : `storage`; `db`;`connection`; and `dbroot` properties to help the programmer interact with the ZODB database, connection, storage objects. `MyZODB` also provides a close method to cleanly close the ZODB database, connection and storage.</p>
<p>`MyZODB` is not explicitly included in the above example but it looks like this :</p>
<pre class="brush: python; title: ; notranslate">
from ZODB import FileStorage, DB
class MyZODB(object):
    '''Manage the state of a ZODB FileStorage connection'''
    def __init__(self, path):
        self.storage = FileStorage.FileStorage(path)
        self.db = DB(self.storage)
        self.connection = self.db.open()
        self.dbroot = self.connection.root()
    def close(self):
        self.connection.close()
        self.db.close()
        self.storage.close()&lt;/pre&gt;
</pre>
<h3>Create a sub-tree in ZODB for our `City` objects</h3>
<p>Now we have an instance of `MyZODB` we can treat the `dbroot` property (which corresponds to the ZODB `dbroot` property of the ZODB `connection` object) as a plain old dictionary and assign a value to it under some key of our choosing, for our example because we&#8217;re going to save a set of `City` objects we&#8217;ve chosen &#8216;cities&#8217;.</p>
<p>At this stage we just assign an instance of `<a title="Read about `OOBTree` here under the 'Related Modules' heading" href="http://www.zodb.org/documentation/guide/modules.html">OOBTree</a>` to that &#8216;cities&#8217; key. An OOBTree instance acts like a dictionary but, when a lot of elements are within it, works much more efficiently for the purposes of ZODB.</p>
<pre class="brush: python; title: ; notranslate">
myzodbinstance.dbroot['cities'] = OOBTree()
</pre>
<h3>Create a set of `City` objects</h3>
<p>Now we pause for a moment and make ourselves a set of `City` objects and put them into a dictionary for later use.</p>
<p>What&#8217;s significant here is that the key used to save each `City` instance is a unique integer which has no specific meaning in itself, we&#8217;ll see why in a moment.</p>
<pre class="brush: python; title: ; notranslate">
cities = {
1:City('Windhoek', 322500),
2:City('Pretoria', 525387),
3:City('Nairobi', 3138295),
4:City('Maputo', 1244227),
5:City('Jakarta', 10187595),
6:City('Canberra', 358222),
7:City('Wellington', 393400),
8:City('Santiago', 5428590),
9:City('Buenos Aires', 2891082),
}
</pre>
<h3>Save `City` objects to ZODB and index them</h3>
<p>Now at last we&#8217;re going to do what we&#8217;ve come for.</p>
<p>We iterate over our set of `City` instances and for each one we make use of the `<a title="'index_doc' documentation" href="http://docs.repoze.org/catalog/api.html#repoze.catalog.catalog.Catalog.index_doc">index_doc</a>` method of <a title="`repoze.catalog` object methods documentation" href="http://docs.repoze.org/catalog/api.html#">repoze.catalog</a> . Notice that the two arguments are the integer we&#8217;ve arbitarily associated with each `City` instance, &#8216;docid&#8217; in this example, and the `City` instance itself, &#8216;doc&#8217; in this example. By using the `index_doc` method we update the catalog entries maintained by repoze.catalog</p>
<p>In the same interation we assign the `City` object instance, &#8216;doc&#8217; to our `OOBTree` (stored under the &#8216;cities&#8217; key of `dbroot`) using as an index the same integer we&#8217;ve just passed to the `index_doc` call.</p>
<p>Finally we make use of the ZODB Transaction manager to commit our changes. Because repoze.catalog is actually a ZODB database inside our single transaction is sufficient to commit both the catalog update and the actual update of the ZODB database.</p>
<pre class="brush: python; title: ; notranslate">
for docid, doc in cities.items():
    catalog.index_doc(docid, doc)
    myzodbinstance.dbroot['cities'][docid] = doc
    transaction.commit()
</pre>
<h2>Credit where credits due</h2>
<p>The example I&#8217;ve shown here owes some parts to <a title="'indexing' example code from repoze.org website" href="http://docs.repoze.org/catalog/usage.html#indexing">one of the examples</a> on the repoze.catalog website. The structure of the `myZODB` was taken from the article cited above,  &#8216;<a title="How to use an object database with a Python, a dynamic object-oriented language" href="http://www.ibm.com/developerworks/aix/library/au-zodb/">Example Driven ZODB</a>&#8216; . Lastly I got some useful advice in response to a question I posed on <a title="StackOverflow question about ZODB transactions" href="http://stackoverflow.com/questions/13154943/zodb-repoze-catalog-saving-objects-and-catalog-in-same-database">StackOverflow</a> and I&#8217;m grateful to the people who provided answers .</p>
<h2>In Closing</h2>
<p>That&#8217;s all there is to it ! In many small scale instances there&#8217;s no need to do anything other than use ZODB as it comes and not worry about indexing &#8211; machines are fast and many applications deal with relatively small data sets however if you do need it repoze.catalog (or one of the other, similar, cataloguing tools) is a useful way to squeeze more speed out of ZODB.</p>
<p>This has been a very long blog post by my standards so I&#8217;m going to show how to access the data indexed under repoze.catalog (and prove that it all actually works !) in a blog post next week.</p>
]]></content:encoded>
			<wfw:commentRss>http://mainlydata.kubadev.com/python/repoze-catalog-and-zodb-beginners-example-part-1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Droopy : Very simple HTTP file uploads</title>
		<link>http://mainlydata.kubadev.com/python/droopy-very-simple-http-file-uploads/</link>
		<comments>http://mainlydata.kubadev.com/python/droopy-very-simple-http-file-uploads/#comments</comments>
		<pubDate>Fri, 19 Oct 2012 01:53:15 +0000</pubDate>
		<dc:creator>adminrs</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[droopy]]></category>
		<category><![CDATA[file-upload]]></category>
		<category><![CDATA[http]]></category>

		<guid isPermaLink="false">http://mainlydata.kubadev.com/?p=517</guid>
		<description><![CDATA[droopy is a single python script which provides a simple web-server for uploading files to the host - here are some examples of how to use it.]]></description>
			<content:encoded><![CDATA[<h1>Droopy : Very simple HTTP file uploads</h1>
<h2>Summary</h2>
<p>Droopy is a mini web server which makes allowing file uploads very easy</p>
<h2>I just want to upload this file !</h2>
<p>I&#8217;ve been writing a system which shares processing tasks across two machines.</p>
<p>Part of this involved shipping an image file from one machine to the other; doing some stuff to the file and then; bringing the file back again.</p>
<p>I was looking around for easy ways to move the files and I found <a title="Droopy: easy file receiving" href="http://stackp.online.fr/?p=28">droopy</a> .</p>
<p>To quote the author, Pierre  Duqeusne, &#8220;<a href="http://stackp.online.fr/wp-content/uploads/droopy">Droopy</a> is a mini Web server whose sole purpose is to let others upload files to your computer&#8221;. It&#8217;s a single python script so as long you&#8217;ve got Python installed starting the server is as simple as this<br />
<code><br />
python droopy --message "Upload the bb images here" --picture 0.jpg --dl 8080<br />
</code><br />
And you&#8217;re ready to upload files immediately</p>
<div class="wp-caption alignnone" style="width: 590px;"><img title="" src="http://mainlydata.kubadev.com/wp-content/uploads/2012/10/droopy.png" alt="" /></div>
<p><em>Image in screendump courtesy of <a title="CC Image couresy of paloetic" href="http://www.flickr.com/photos/paloetic/4501754462/sizes/m/">paloetic via flickr</a> </em></p>
<p>Because of the `&#8211;dl` argument used to launch droopy in my example above you also have the option to download files from the same director you&#8217;re uploading to.</p>
<h2>How I used it</h2>
<h3>Uploading Files using Requests and Droopy</h3>
<p>My solution was written in python so uploading files to the droopy server was very easy using the excellent <a title="Requests: HTTP for Humans" href="http://docs.python-requests.org/en/latest/">requests</a> library</p>
<pre class="brush: python; title: ; notranslate">
def uploadfile(filepath, uploadurl, fileformelementname=&quot;upfile&quot;):
    '''
    This will invoke an upload to the webserver
    on the VM
    '''

    files = {fileformelementname : open(filepath,'rb')}
    r = requests.post(uploadurl, files=files)
    return r.status_code

uploadStatus = uploadfile(currentFile.fullpath, UPLOADURL, &quot;upfile&quot;)
</pre>
<h3>Download Files using urllib and Droopy</h3>
<p>I can&#8217;t now remember why but I decided to do the download using <a title="The urllib library doco on the python.org website" href="http://docs.python.org/library/urllib.html">urllib</a> instead of Requests</p>
<pre class="brush: python; title: ; notranslate">
def downloadfile(filename, dloadurl, outputdirectory):
    '''
    Pull the converted file off the droopy server
    '''

    fullurl = urljoin(dloadurl, filename)
    fulloutputpath = os.path.join(outputdirectory, 'divided', filename)

    urllib.urlretrieve(fullurl, fulloutputpath)

downloadfile(currentFile.outputName, DOWNLOADURL, IMGDIR)
</pre>
<h2>Summary</h2>
<p>Droopy provides a very useful, very simple web server for both uploading and downloading files. Combined with Python it makes a very useful facility for moving files around under programmtic control.</p>
<h2>Versions</h2>
<p>All of the above was done on Python 2.7.x.</p>
]]></content:encoded>
			<wfw:commentRss>http://mainlydata.kubadev.com/python/droopy-very-simple-http-file-uploads/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using Lillypond to show the &#8216;sim&#8217; notation in a score</title>
		<link>http://mainlydata.kubadev.com/uncategorized/using-lillypond-to-show-the-sim-notation-in-a-score/</link>
		<comments>http://mainlydata.kubadev.com/uncategorized/using-lillypond-to-show-the-sim-notation-in-a-score/#comments</comments>
		<pubDate>Fri, 21 Sep 2012 11:00:58 +0000</pubDate>
		<dc:creator>adminrs</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[frescobaldi]]></category>
		<category><![CDATA[lilypond]]></category>
		<category><![CDATA[sim]]></category>

		<guid isPermaLink="false">http://mainlydata.kubadev.com/?p=511</guid>
		<description><![CDATA[A guide to creating the 'sim' notation in your music score when using the Lilypond music notation]]></description>
			<content:encoded><![CDATA[<h1>How can you include &#8216;sim&#8217; in your score ?</h1>
<h2>Summary</h2>
<p>How to define the &#8216;sim&#8217; notation when using Lilypond to engrave a score. This is a little off topic for my blog but I found it difficult to find this information myself so I&#8217;m hoping others will find it here.</p>
<h2>Lilypond and Frescobaldi</h2>
<p><a title="&quot;music notation for everyone&quot;" href="http://lilypond.org/">Lilypond</a> is a file format allowing you to define a musical score using simple text notation; Lilypond is also the program which takes that text notation and outputs a score in, for instance, Acrobat PDF format. It&#8217;s a pretty amazing technology.</p>
<p>In using Lilypond I&#8217;ve found it very useful to use the <a title="Frescobaldi: Edit LilyPond sheet music with ease!" href="http://www.frescobaldi.org/">Frescobaldi sheet music text editor</a> which provides support for writing files in the Lilypond format.</p>
<h2>What I&#8217;ve done</h2>
<p>My music theory knowledge isn&#8217;t great but I&#8217;ve really enjoyed using Lilypond and Frescobaldi to engrave a score for a relative of mine. It&#8217;s just an amazing technology and the output is beautiful.</p>
<p>It took a little time to get to grips with some of the ideas although the <a title="Index of Lilypond manuals" href="http://lilypond.org/manuals.html">Lilypond manuals</a> are very good. I did however find one little thing I couldn&#8217;t work out how to do and that is the subject of this, rather top heavy post.</p>
<h2>&#8216;sim&#8217; notation on a score</h2>
<p>Sometimes in scores you want the text &#8216;sim.&#8217; to appear as shown below in the screen dump.</p>
<div class="wp-caption alignnone" style="width: 299px;"><img title="" src="http://mainlydata.kubadev.com/wp-content/uploads/2012/09/sim-screen-capture.Png" alt="" /></div>
<p>I looked all over the documentation and there just didn&#8217;t seem to be a way of including that. However I visited the Lilypond IRC channel (#lilypond@irc.freenode.net) which you can visit directly by going to the <a title="Lilypond web page with link to irc channel" href="http://lilypond.org/web/documentation">support page</a> and paging down a little.</p>
<p>The good folk on there were able to point me in the right direction. By appending</p>
<pre>_\markup{\large \italic "sim."}</pre>
<p>to the note I wished &#8216;sim&#8217; to appear under the right thing was done.</p>
<p>Just to make that a little clearer here are a few bars which include the annotation to create the &#8216;sim&#8217;</p>
<div class="wp-caption alignnone" style="width: 327px;"><img title="" src="http://mainlydata.kubadev.com/wp-content/uploads/2012/09/sim-in-lilypond-notation.png" alt="" /></div>
<p>As you might imagine the</p>
<pre>\large</pre>
<p>only controls how large the &#8216;sim&#8217; appear on the score and I fiddled around with this a little until I found an adjective which produced text that matched the rest of the score. There are a number of options for altering the size of text displayed as can be seen in the <a title="Formatting Text : Selecting Font and Font Size" href="http://lilypond.org/doc/v2.12/Documentation/user/lilypond/Formatting-text#Selecting-font-and-font-size">Selecting font and font size</a> part of the Lilypond manual.</p>
]]></content:encoded>
			<wfw:commentRss>http://mainlydata.kubadev.com/uncategorized/using-lillypond-to-show-the-sim-notation-in-a-score/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Crazy little thing called : SimpleHTTPServer</title>
		<link>http://mainlydata.kubadev.com/python/crazy-little-thing-called-simplehttpserver/</link>
		<comments>http://mainlydata.kubadev.com/python/crazy-little-thing-called-simplehttpserver/#comments</comments>
		<pubDate>Tue, 12 Jun 2012 01:29:47 +0000</pubDate>
		<dc:creator>adminrs</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[http]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://mainlydata.kubadev.com/?p=503</guid>
		<description><![CDATA[In Python the SimpleHTTPServer module allows you to produce a one line webserver]]></description>
			<content:encoded><![CDATA[<h1>Crazy little thing called : SimpleHTTPServer</h1>
<h2>Summary</h2>
<p>Python brings you a one line web-server !</p>
<h2>Simplest webserver ever !</h2>
<p>I was logged onto a tiny VPS I use sometimes and thinking it would be useful to have a web-server to help move a few files off it. The thought of installing a &#8216;real&#8217; web-server seemed a bit much for what would five minutes of use so I started thinking about Python (of course !).</p>
<p>It turns out that you can fire up a (completely unsecured and rather wild-west) web server like this :<br />
<code></code></p>
<p><code>python -m SimpleHTTPServer</code></p>
<p>When you type that command the current directory becomes the root of a web-resource, accessible via port 8000 &#8211; rather than the default port 80 we usually use for HTTP, and any files, and sub-directories, in the current directory can be accessed like this</p>
<p><code>http://mylittlevps.kubadev.com:8000/thefileIwant.txt</code></p>
<p>and, for stuff in sub-directories, like this</p>
<p><code>http://mylittlevps.kubadev.com:8000/foo/bar/anotherfileIwant.txt</code></p>
<h2>Don&#8217;t say you weren&#8217;t warned</h2>
<p>There are of course all sort of circumstances where doing this would be a <strong>REALLY BAD IDEA &#8482;</strong> but all the same it&#8217;s nice to know it&#8217;s there if you need it !</p>
]]></content:encoded>
			<wfw:commentRss>http://mainlydata.kubadev.com/python/crazy-little-thing-called-simplehttpserver/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>optparse: simulating &#8216;&#8211;help&#8217;</title>
		<link>http://mainlydata.kubadev.com/python/optparse-simulating-help/</link>
		<comments>http://mainlydata.kubadev.com/python/optparse-simulating-help/#comments</comments>
		<pubDate>Mon, 21 May 2012 03:02:44 +0000</pubDate>
		<dc:creator>adminrs</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[--help]]></category>
		<category><![CDATA[-h]]></category>
		<category><![CDATA[arguments]]></category>
		<category><![CDATA[command-line]]></category>

		<guid isPermaLink="false">http://mainlydata.kubadev.com/?p=494</guid>
		<description><![CDATA[Using pythons optparser to print a summary of script options under program control]]></description>
			<content:encoded><![CDATA[<h1>optparse: simulating &#8216;&#8211;help&#8217;</h1>
<h2>Summary</h2>
<p>Getting optparse to show a summary of script options under program control.</p>
<h2>What do you use optparse for ?</h2>
<p>optparse is a Python standard library for parsing command-line options.</p>
<p>optparse provides a relatively simple way of</p>
<p>* defining a set of command line arguments which the user may enter<br />
* parsing the command line entered and storing the results of the parse</p>
<h2>I need help !</h2>
<p>By default optparse will respond to a either of :</p>
<pre>&lt;yourscript&gt; -h</pre>
<p>or</p>
<pre>&lt;yourscript&gt; --help</pre>
<p>by printing a summary of your scripts options.</p>
<h2>What I learned today</h2>
<p>In the script I was working on today I wanted to respond to the user not entering any argument at all by printing a summary of all options available (in other words as if they user had entered &#8216;&#8211;help&#8217; or &#8216;-h&#8217; as an argument).</p>
<p>There is a way you can do this but for some reason it&#8217;s not in the list of OptionParser methods shown in the documentation.</p>
<h3>print_help()</h3>
<p>If you call the method &#8216;print_help&#8217; as shown in the code below optparse will respond by by printing the same text that would be shown if the user were to enter an argument of &#8216;&#8211;help&#8217;.</p>
<pre>parser = OptionParser(description=desc, usage=usage)
parser.add_option(  "-i", "--inbox", action="store",  dest="inbox",
metavar="INBOX", help="Location of INBOX")
parser.add_option(  "-o", "--outpath", action="store", dest="outpath",
metavar="PATH", help="PATH to output csv file")
parser.add_option(  "-v", "--verbose", action="store_true",
dest="verbose", help="Show each file processed")

(options, args) = parser.parse_args()

if (options.inbox is None) and (options.outpath is None):
  parser.print_help()
  exit(-1)
elif not os.path.exists(options.inbox):
  parser.error('inbox location does not exist')
elif not os.path.exists(os.path.dirname(options.outpath)):
  parser.error('path to ouput location does not exist')

return options</pre>
]]></content:encoded>
			<wfw:commentRss>http://mainlydata.kubadev.com/python/optparse-simulating-help/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using Paramiko to control an EC2 instance</title>
		<link>http://mainlydata.kubadev.com/python/using-paramiko-to-control-an-ec2-instance/</link>
		<comments>http://mainlydata.kubadev.com/python/using-paramiko-to-control-an-ec2-instance/#comments</comments>
		<pubDate>Thu, 19 Apr 2012 12:51:56 +0000</pubDate>
		<dc:creator>adminrs</dc:creator>
				<category><![CDATA[EC2]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[paramiko]]></category>
		<category><![CDATA[puttygen]]></category>
		<category><![CDATA[ssh]]></category>
		<category><![CDATA[windows]]></category>

		<guid isPermaLink="false">http://mainlydata.kubadev.com/?p=466</guid>
		<description><![CDATA[Using the Python library Paramiko to 'remote control' an EC2 instance ]]></description>
			<content:encoded><![CDATA[<p><em>An example of using Paramiko to issue commands to an EC2 instance</em></p>
<h2>Summary</h2>
<p>An example of using the Python library Paramiko to &#8216;remote control&#8217; an EC2 instance .</p>
<h2>&#8220;Do that, Do this&#8221;</h2>
<p>Recently I&#8217;ve been looking into the use of the <a title="Bellatrix is a set of (magic) tools to automate the management of Amazon EC2 services" href="http://pypi.python.org/pypi/bellatrix">Bellatrix</a> library to start, control and stop <a title="Amazon Elastic Compute Cloud info from Wikipedia" href="http://en.wikipedia.org/wiki/Amazon_Elastic_Compute_Cloud">Amazon EC2 instances</a> (my posts about that are <a title="Bellatrix + Windows Users – Two things to remember" href="http://mainlydata.kubadev.com/ec2/bellatrix-windows-users-two-things-to-remember/">here</a> and <a title="Bellatrix Provisioning Commands" href="http://mainlydata.kubadev.com/ec2/bellatrix-provisioning-commands/">here</a>).</p>
<p>Spinning off the side of that I&#8217;ve taken a look at the <a title="Paramiko home page" href="http://www.lag.net/paramiko/">Paramiko module</a> which &#8220;implements the SSH2 protocol for secure (encrypted and authenticated) connections to remote machines&#8221;.</p>
<p>There&#8217;s a good article on beginning to use Paramiko <a title="Good beginners tutorial on using Paramiko" href="http://jessenoller.com/2009/02/05/ssh-programming-with-paramiko-completely-different/">&#8220;SSH Programming with Paramiko&#8221;</a> by <a title="Jesse's Blog on &quot;Python, Programming and other things&quot;" href="http://jessenoller.com/">Jesse Noller</a> which I found very helpful but there&#8217;s enough stuff I had to change to deal with using EC2 and the controlling Python script running on Windows that I thought it would be worth recording my sample script.</p>
<h2>Installing Paramiko</h2>
<p>So first off I&#8217;d seen the comments about Paramiko maybe needing a special compilation step for installation to Windows but I&#8217;m pleased to say that&#8217;s not true, I <a title="Paramiko download area" href="http://www.lag.net/paramiko/download/">downloaded</a> 1.7.7.1 to my Windows Vista machine, did a quick&#8230;</p>
<pre>python setup.py install</pre>
<p>&#8230; and it all went very smoothly, just to be sure I tried out an import &#8230;</p>
<pre>&gt;&gt;&gt; import paramiko</pre>
<p>&#8230; no problem.</p>
<h2>Starting the EC2 instance</h2>
<p>I now needed a server to talk to so I used Bellatrix to spin up a micro instance of Ubuntu like this :</p>
<pre>python "C:\bin\installed\Python2.6\Scripts\bellatrix" start --security_groups mySecGrp ami-3e9b4957 mykeypair</pre>
<p>The arguments you can see here are :</p>
<ul>
<li>&#8220;mySecGrp&#8221; is a <a title="A good tutorial on understand EC2 Security Groups and Firewalls" href="http://cloud-computing.learningtree.com/2010/09/24/understanding-amazon-ec2-security-groups-and-firewalls/">Security Group</a> I&#8217;ve previously setup via the AWS Management Console;</li>
<li>&#8216;ami-3e9b4957&#8242; is the AMI of <a title="Wikipedia on Lucid Lynx" href="http://en.wikipedia.org/wiki/Lucid_Lynx#Ubuntu_10.04_LTS_.28Lucid_Lynx.29">Ubuntu 10.04 (Lucid Lynx)</a>; and</li>
<li> &#8217;mykeypair&#8217; is the name of a Key Pair that, again, I&#8217;ve previously setup via the AWS Management Console.</li>
</ul>
<p>When you run that command you get an output that looks like this :</p>
<pre>C:\Users\Richard Shea&gt;python "C:\bin\installed\Python2.6\Scripts\bellatrix" start --security_groups mySecGrp ami-3e9b4957 mykeypair
2012-04-19 21:27:03,135 INFO starting EC2 instance...
2012-04-19 21:27:03,180 INFO ami:ami-3e9b4957 type:t1.micro key_name:mykeypair security_groups:mySecGrp new size:None
2012-04-19 21:27:07,657 INFO starting image: ami-3e9b4957 key mykeypair type t1.micro shutdown_behavior terminate new size None
2012-04-19 21:27:08,555 INFO we got 1 instance (should be only one).
2012-04-19 21:27:08,556 INFO tagging instance:i-f1234567 key:Name value:Bellatrix started me
2012-04-19 21:27:12,361 INFO instance:i-f1234567 was successfully tagged with: key:Name value:Bellatrix started me
2012-04-19 21:27:12,361 INFO getting the dns name for instance: i-f1234567 time out is: 300 seconds...
2012-04-19 21:27:34,173 INFO DNS name for i-f1234567 is ec2-10-20-30-40.compute-1.amazonaws.com
2012-04-19 21:27:34,173 INFO waiting until instance: i-f1234567 is ready. Time out is: 300 seconds...
2012-04-19 21:27:34,174 INFO Instance i-f1234567 is running</pre>
<p>And the key thing here is that we now now have access to the host name of the EC2 instance we&#8217;ve just spun up:</p>
<pre>ec2-10-20-30-40.compute-1.amazonaws.com</pre>
<h2>Talking to the EC2 instance</h2>
<p>We&#8217;re now ready to send commands to our new instance. Making use of some of Jesses code I was able to write :</p>
<pre>import paramiko
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect('ec2-107-22-80-32.compute-1.amazonaws.com',
            username='ubuntu',
            key_filename='''mykeypair-ssh2-rsa.openssh''')
stdin, stdout, stderr = ssh.exec_command("uptime;ls -l;touch mickymouse;ls -l;uptime")
stdin.flush()
data = stdout.read().splitlines()
for line in data:
    print line
ssh.close()</pre>
<p>Anyone who&#8217;s got this far can probably see what&#8217;s happening here, but just to be sure :</p>
<ol>
<li>having instantiated an instance of paramiko.SSHClient we&#8217;re able to use our private key file and the address of our EC2 server to start an SSH session.</li>
<li>We then use the exec_command method to submit a string of commands and get back three references to files corresponding to : standard input, standard output and standard error.</li>
<li>By reading through the standard output file we can print locally the output from the commands executed on the EC2 instance.</li>
</ol>
<h3>The Key Thing</h3>
<p>As you can see to identify ourselves to the remote server we&#8217;re doing a key exchange. Our private key is &#8216;mykeypair-ssh2-rsa.openssh&#8217;. A point worth mentioning here is that generally I logon to EC2 instances using the excellent <a title="PuTTY is a free implementation of Telnet and SSH for Windows and Unix platforms, along with an xterm terminal emulator" href="http://www.chiark.greenend.org.uk/~sgtatham/putty/">PuTTY</a> . The private key files used by default by PuTTY are not in the same format as the ones required by Paramiko so as a result when I first tried this I found Paramiko fell over complaining my &#8216;key_filename&#8217; argument was &#8216;not a valid dsa private key file&#8217;.</p>
<h3>PuttyGen to the rescue</h3>
<p>Well the great thing is that PuTTY actually comes with a tool <a title="PuttyGen documention" href="http://the.earth.li/~sgtatham/putty/0.62/htmldoc/Chapter8.html#pubkey-puttygen">PuttyGen</a> which will import a standard PuTTY key file (foo.ppk) &#8211; you need to do &#8216;Conversions&#8217; | &#8216;Import Key&#8217; and then &#8216;Conversions&#8217; | &#8216;Export OpenSSH Key&#8217;</p>
<h3>Ubuntu Specific</h3>
<p>Bear in mind that the way the SSHClient connect method is used above is suitable for an Ubuntu instance as it is by default however you can&#8217;t rely on all *nix instance working just that way.</p>
<h2>Seeing the Output</h2>
<p>Just to close out I&#8217;ll show you the output</p>
<pre>12:39:45 up  3:12,  0 users,  load average: 0.08, 0.02, 0.01
total 0
total 0
-rw-r--r-- 1 ubuntu ubuntu 0 2012-04-19 12:39 mickymouse
12:39:45 up  3:12,  0 users,  load average: 0.08, 0.02, 0.01</pre>
<h2>Powerful Stuff</h2>
<p>The combination of Bellatrix allowing you to spin up EC2 instances with a single command and Paramiko allowing you send arbitary commands to those servers is powerful stuff and I&#8217;m impressed at the work done by their respective developers. Of course Bellatrix can do &#8216;for free&#8217; what I&#8217;ve used Paramiko to do here are part of it&#8217;s <a title="Bellatrix Provisioning Commands" href="http://mainlydata.kubadev.com/ec2/bellatrix-provisioning-commands/">Provisioning commands</a> but it was an interesting exercise for me to do my own version of that.</p>
]]></content:encoded>
			<wfw:commentRss>http://mainlydata.kubadev.com/python/using-paramiko-to-control-an-ec2-instance/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Bellatrix Provisioning Commands</title>
		<link>http://mainlydata.kubadev.com/ec2/bellatrix-provisioning-commands/</link>
		<comments>http://mainlydata.kubadev.com/ec2/bellatrix-provisioning-commands/#comments</comments>
		<pubDate>Tue, 17 Apr 2012 11:27:03 +0000</pubDate>
		<dc:creator>adminrs</dc:creator>
				<category><![CDATA[EC2]]></category>
		<category><![CDATA[Bellatrix]]></category>

		<guid isPermaLink="false">http://mainlydata.kubadev.com/?p=452</guid>
		<description><![CDATA[A condensed version of the Bellatrix provisioning documentation (with links to the full version)]]></description>
			<content:encoded><![CDATA[<p><em>A quick guide to built-in Bellatrix provisioning commands<br />
</em></p>
<h2>Summary</h2>
<p>A table of <a title="Bellatrix is a set of (magic) tools to automate the management of Amazon EC2 services." href="http://pypi.python.org/pypi/bellatrix">Bellatrix</a> provisioning commands as at 1.1.2</p>
<h2>Bellatrix Provisioning</h2>
<p>As mentioned in <a title="Bellatrix tips for Windows users" href="http://mainlydata.kubadev.com/ec2/bellatrix-windows-users-two-things-to-remember/">my previous post</a> Bellatrix allows you to start and provision Amazon Web Services EC2 instances.In this context &#8216;provision&#8217; refers to the process of installing software, creating directories, changing file permissions etc.</p>
<p>The built in commands are documented <a title="Provisioning Commands" href="http://bellatrix.readthedocs.org/en/latest/source/ref/bellatrix.lib.html#module-bellatrix.lib.cmds">here</a> in the official doco but before I found that I&#8217;d ripped the <a title="cmds.py defines the available provisioning commands" href="https://bitbucket.org/adeccico/bellatrix/src/tip/bellatrix/lib/cmds.py">cmds.py</a> file apart and produced the following table. It&#8217;s a little more succinct than the official version so I think it&#8217;s worth publishing here.</p>
<h2>Version Alert</h2>
<p>For obvious reasons this type of thing is prone to Bellatrix changing. This page is valid as of the 1.1.2 version of Bellatrix.</p>
<h2>Provisioning Commands</h2>
<table border="1" cellspacing="1" cellpadding="1">
<thead>
<tr class="row-1 odd">
<th class="column-1">Command</th>
<th class="column-2">Description</th>
</tr>
</thead>
<tbody>
<tr class="row-2 even">
<td class="column-1">apt_get_install</td>
<td class="column-2">Return the &#8220;sudo apt-get install&#8221; command</td>
</tr>
<tr class="row-3 odd">
<td class="column-1">apt_get_update</td>
<td class="column-2">Executes apt-get update.</td>
</tr>
<tr class="row-4 even">
<td class="column-1">chmod</td>
<td class="column-2">Applies the chmod command</td>
</tr>
<tr class="row-5 odd">
<td class="column-1">createSoftLink</td>
<td class="column-2">Creates a new soft link</td>
</tr>
<tr class="row-6 even">
<td class="column-1">copy</td>
<td class="column-2">Copy a file using -f so it doesn&#8217;t fail if the destination exists</td>
</tr>
<tr class="row-7 odd">
<td class="column-1">create_django_project</td>
<td class="column-2">Creates a Django project</td>
</tr>
<tr class="row-8 even">
<td class="column-1">createVirtualEnv</td>
<td class="column-2">Generate a new Python virtual environment using virtualenv</td>
</tr>
<tr class="row-9 odd">
<td class="column-1">executeInVirtualEnv</td>
<td class="column-2">Execute a command within a virtualenv environmen</td>
</tr>
<tr class="row-10 even">
<td class="column-1">flatCommands</td>
<td class="column-2">Given a list of commands it will return a single one concatenated by &#8216;&amp;&amp;&#8217; so they will be executed in sequence until any of them fail</td>
</tr>
<tr class="row-11 odd">
<td class="column-1">install_pip</td>
<td class="column-2">Install pip using apt-get install</td>
</tr>
<tr class="row-12 even">
<td class="column-1">install_nginx</td>
<td class="column-2">Install Nginx in Ubuntu using the repo they provide as described in http://wiki.nginx.org/Install#Ubuntu_PPA</td>
</tr>
<tr class="row-13 odd">
<td class="column-1">installPackageInVirtualEnv</td>
<td class="column-2">Install a Python package into a virtualenv</td>
</tr>
<tr class="row-14 even">
<td class="column-1">mkdir</td>
<td class="column-2">Created a new directory. &#8220;-p&#8221; flag is used so the command generates the same result regardless whether the directory exists or not.</td>
</tr>
<tr class="row-15 odd">
<td class="column-1">pip_install</td>
<td class="column-2">Install a Python package using pip</td>
</tr>
<tr class="row-16 even">
<td class="column-1">sudo</td>
<td class="column-2">Execute a list of commands using sudo</td>
</tr>
<tr class="row-17 odd">
<td class="column-1">wget</td>
<td class="column-2">Downloads a web resource using wget</td>
</tr>
</tbody>
</table>
]]></content:encoded>
			<wfw:commentRss>http://mainlydata.kubadev.com/ec2/bellatrix-provisioning-commands/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Bellatrix + Windows Users &#8211; Two things to remember</title>
		<link>http://mainlydata.kubadev.com/ec2/bellatrix-windows-users-two-things-to-remember/</link>
		<comments>http://mainlydata.kubadev.com/ec2/bellatrix-windows-users-two-things-to-remember/#comments</comments>
		<pubDate>Mon, 16 Apr 2012 13:09:50 +0000</pubDate>
		<dc:creator>adminrs</dc:creator>
				<category><![CDATA[EC2]]></category>
		<category><![CDATA[Bellatrix]]></category>

		<guid isPermaLink="false">http://mainlydata.kubadev.com/?p=440</guid>
		<description><![CDATA[Bellatrix automates the management of Amazon EC2 services - there's a couple of small things Windows users should know when trying to use it]]></description>
			<content:encoded><![CDATA[<h1>Bellatrix &#8211; Windows Idiosyncracies</h1>
<h2>Summary</h2>
<p>Two things you might find useful if you&#8217;re starting to use <a title="Bellatrix is a set of (magic) tools to automate the management of Amazon EC2 services" href="http://pypi.python.org/pypi/bellatrix">Bellatrix</a> on Windows.</p>
<h2>What&#8217;s Bellatrix Again ?</h2>
<p>Bellatrix allows you browse and control <a title="Amazon Elastic Compute Cloud info from Wikipedia" href="http://en.wikipedia.org/wiki/Amazon_Elastic_Compute_Cloud">Amazon EC2 instances</a> using simple commands on your local machine.</p>
<p>For instance :</p>
<pre>bellatrix start ami key_name</pre>
<p>run on your machine will launch an EC2 instance within Amazon Web Services based on the named <a title="List of available Amazon Machine Images" href="https://aws.amazon.com/amis/">ami (Amazon Machine Image)</a> and allow you to contact it using the key_name you have specified.</p>
<p>You&#8217;ve been able to do something like this with the Python package <a title="Boto is a Python package that provides interfaces to Amazon Web Services" href="https://github.com/boto/boto#readme">Boto</a> for some time but Bellatrix provides a lot of ready to use commands rather than having to write your own scripts.</p>
<h2>Bellatrix on Windows Then ?</h2>
<h3>Location of Home</h3>
<p>I&#8217;m a bit embarrassed to write this but in the Bellatrix doco which describes <a title="Bellatrix doco detailing how to set your AWS credentatials" href="http://bellatrix.readthedocs.org/en/latest/commands_use_tut.html#setting-your-aws-credentials">what config files you need and where to place them</a> it refers to</p>
<pre>&lt;your_home&gt;</pre>
<p>I&#8217;m familiar with the idea of &#8216;Home&#8217; on a unix box but in a Windows enviroment ? I wasn&#8217;t really sure what it meant (I&#8217;ve only been using Windows for 15 years so you can see where the confusion crept in). I managed to persuade myself it was referring to the Bellatrix directory within the Python site-packages directory !</p>
<p>Well here&#8217;s the news for the Windows users out there who are as &#8216;home-challenged&#8217; as I am. It turns out you should putting those config files in a directory located at :</p>
<pre><a title="List of Windows Enviroment Variables" href="http://en.wikipedia.org/wiki/Environment_variable#System_path_variables">%HOMEPATH%</a>\.bellatrix</pre>
<p>which for me is</p>
<pre>C:\Users\Richard Shea\.bellatrix</pre>
<h3>Yes but what about the dots ?</h3>
<p>Which brings me onto another windows specific thing &#8211; how do you produce a directory with a dot as its first character ? I started off trying to do it via File Explorer and discovered something strange. File Explorer won&#8217;t let you specify a directory name that starts with a dot &#8230; unless you specify the directory name as having a trailing dot as well &#8230; if you do that File Explorer quietly throws away the trailing dot and you have the name you wanted in the first place ! Weird &#8230; or perhaps &#8220;only on Windows&#8221;</p>
<h2>In closing</h2>
<p>Anyway the good news is I&#8217;ve got it up and running and listing my instances ! Next step is to to use Bellatrix to start an EC2 instance and provision it as a <a title="Nagare - a web framework with an alternative view of how things should be done" href="http://www.nagare.org/trac/wiki/NagareDescription">Nagare</a> environment. There&#8217;ll be a blog post about that by the time I&#8217;ve done, I&#8217;m sure !</p>
]]></content:encoded>
			<wfw:commentRss>http://mainlydata.kubadev.com/ec2/bellatrix-windows-users-two-things-to-remember/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Datejs &#8211; Date.isAfter &#8211; no such function ?</title>
		<link>http://mainlydata.kubadev.com/javascript/datejs-date-isafter-no-such-function/</link>
		<comments>http://mainlydata.kubadev.com/javascript/datejs-date-isafter-no-such-function/#comments</comments>
		<pubDate>Thu, 29 Sep 2011 10:17:24 +0000</pubDate>
		<dc:creator>adminrs</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Datejs]]></category>

		<guid isPermaLink="false">http://mainlydata.kubadev.com/?p=409</guid>
		<description><![CDATA[Datejs is a great library but make sure you don't get misled into using the wrong version]]></description>
			<content:encoded><![CDATA[<h1>date.js &#8211; missing methods</h1>
<h2>Summary</h2>
<p>Save yourself a lot of pain and ensure you&#8217;re using the right version of  <a title="Datejs is an open-source JavaScript Date Library." href="http://www.datejs.com/">Datejs</a>.</p>
<h2>Datejs &#8211; It&#8217;s great !</h2>
<div class="wp-caption alignnone" style="width: 597px;"><a href="http://www.datejs.com"><img title="Datejs, an open-source Javascript Date Library" src="http://mainlydata.kubadev.com/wp-content/uploads/2011/09/DateJSLogo.Png" alt="" /></a></div>
<p>Let me start by saying that Datejs, an open-source JavaScript Date Library, is great ! It provides a lot of much needed functionality to the area of dates in Javascript.</p>
<h2>Weirdly missing methods</h2>
<p>Having said that what I want to highlight is that if you use the standard download links offered by the website (as shown below) you&#8217;ll get a version of Datejs which is not the most current one.</p>
<div class="wp-caption alignnone" style="width: 363px;"><img title="Datejs, an open-source Javascript Date Library" src="http://mainlydata.kubadev.com/wp-content/uploads/2011/09/DateJSDownloadButtonSTOP.png" alt="" /></div>
<p>What&#8217;s more it seems that the version you will get contains a number of defects.</p>
<p>I can vouch for this as I&#8217;ve spent a couple of hours today wondering  why the &#8216;.isAfter&#8217; and the &#8216;.compare&#8217; methods didn&#8217;t seem to exist in  the form they are documented ! Very frustrating !</p>
<h2>What You Should Do</h2>
<div class="wp-caption alignnone" style="width: 529px;"><img title="Version and build date from date.js" src="http://mainlydata.kubadev.com/wp-content/uploads/2011/09/DateJSVersionNumber.png" alt="" /></div>
<p>Instead of using the download link on the first page to get the date.js file go here instead : <a href="http://www.datejs.com/build/date.js">http://www.datejs.com/build/date.js</a>. The version number is the same, &#8220;1.0 Alpha-1&#8243;, but the build date is &#8220;2008-05-13&#8243;.</p>
<p>At least at the time of writing &#8211; it&#8217;s the &#8220;2008-05-13&#8243; build you want.</p>
<h2>Credit Where Credits Due</h2>
<p>I&#8217;m grateful to Ben McIntyre <a href="http://groups.google.com/group/datejs/browse_thread/thread/bd345def20d7e4b8#">whose post on the Datejs forums</a> alerted me to this problem, I only wish I&#8217;d seen it earlier !</p>
]]></content:encoded>
			<wfw:commentRss>http://mainlydata.kubadev.com/javascript/datejs-date-isafter-no-such-function/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
