<?xml version="1.0" encoding="UTF-8"?><!-- generator="wordpress.com" -->
<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/"
	>

<channel>
	<title>gae &amp;laquo; WordPress.com Tag Feed</title>
	<link>http://en.wordpress.com/tag/gae/</link>
	<description>Feed of posts on WordPress.com tagged "gae"</description>
	<pubDate>Sun, 29 Nov 2009 09:56:09 +0000</pubDate>

	<generator>http://en.wordpress.com/tags/</generator>
	<language>en</language>

<item>
<title><![CDATA[Удаление всех записей из таблицы.]]></title>
<link>http://appengine.com.ua/2009/11/23/kill-them-all/</link>
<pubDate>Mon, 23 Nov 2009 02:04:38 +0000</pubDate>
<dc:creator>dchaplinsky</dc:creator>
<guid>http://appengine.com.ua/2009/11/23/kill-them-all/</guid>
<description><![CDATA[Удивительное рядом: db.delete(Score.all()) исполняется на полторы секунды ДОЛЬШЕ чем лобовой способ:]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>Удивительное рядом:</p>
<pre><code>           db.delete(Score.all())</code></pre>
<p>исполняется на полторы секунды <strong>ДОЛЬШЕ</strong> чем лобовой способ:</p>
<pre><code>
             for score in Score.all():
                 score.delete()
</code></pre>
<p>На датасете из 1000 элементов в локальном варианте GAE. Я бы подумал, что это флюктуация, но результат воспроизводится с завидным постоянством.</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Поиск строк по префиксу в BigTable]]></title>
<link>http://appengine.com.ua/2009/11/23/prefix-trick/</link>
<pubDate>Mon, 23 Nov 2009 00:13:13 +0000</pubDate>
<dc:creator>dchaplinsky</dc:creator>
<guid>http://appengine.com.ua/2009/11/23/prefix-trick/</guid>
<description><![CDATA[Нативный GAE дэйтастор не умеет фильтровать строки по префиксу, как это делает, например mysql SELEC]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>Нативный GAE дэйтастор не умеет фильтровать строки по префиксу, как это делает, например mysql </p>
<pre><code>SELECT * FROM foo WHERE bar LIKE 'prefix%';</code></pre>
<p>Взамен этого в <a href="http://code.google.com/appengine/docs/python/datastore/queriesandindexes.html#Introducing_Indexes">мануале</a> предлагается следущий трюк:</p>
<pre><code>db.GqlQuery("SELECT * FROM foo WHERE bar &#62;= :1 AND bar &#60; :2&#34;,
 &#34;prefix&#34;, u&#34;prefix&#34; + u&#34;\ufffd&#34;)</code></pre>
<p>То есть, выбрать все значения которые лежат между префиксом и префиксом + наибольший unicode символ. В отсортированом по этому полю дэйтасете это даст как раз выборку по префиксу.</p>
<p>Учитывая, что он создает индексы для подобных выборок автоматически, должно быть довольно быстро.</p>
<p>Трюк, конечно, из разряда удаления гланд через анус (кроме того, непонятно, как матчить строки по постфиксу, или просто по вхождению), с другой стороны, надо попробовать такое в MySQL, может побыстрее нэйтивного лайка будет. Хотя, не исключено, что он именно так и реализован внутренне <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
<p>Stay tuned, сегодня–завтра будет пост по расчетам медиан на крупных выборках с профайлингом и т.п.</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[GAE: Storing serializable objects in datastore]]></title>
<link>http://thesweeheng.wordpress.com/2009/11/16/gae-storing-serializable-objects-in-datastore/</link>
<pubDate>Mon, 16 Nov 2009 14:00:52 +0000</pubDate>
<dc:creator>thesweeheng</dc:creator>
<guid>http://thesweeheng.wordpress.com/2009/11/16/gae-storing-serializable-objects-in-datastore/</guid>
<description><![CDATA[Google AppEngine&#8217;s datastore supports a variety of simple Types and Property Classes by defaul]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>Google AppEngine&#8217;s datastore supports a variety of simple <a href="http://code.google.com/appengine/docs/python/datastore/typesandpropertyclasses.html" target="_blank">Types and Property Classes</a> by default. However if we want to store something like a dictionary, we typically have to serialize it and store it as a Blob. On fetching we will de-serialize it. While this approach works, it is repetitive and somewhat error-prone.</p>
<p>Wouldn&#8217;t it be great if there is a SerializableProperty class that can handle this automatically for us? It doesn&#8217;t exist but according to this <a href="http://code.google.com/appengine/articles/extending_models.html">article</a>, it is easy to create our own customized Property classes. So here is a simple implementation of SerializableProperty that worked for me:</p>
<blockquote>
<pre>import cPickle as pickle
import zlib
from google.appengine.ext import db

class SerializableProperty(db.Property):
  """
  A SerializableProperty will be pickled and compressed before it is
  saved as a Blob in the datastore. On fetch, it would be decompressed
  and unpickled. It allows us to save serializable objects (e.g. dicts)
  in the datastore.

  The sequence of transformations applied can be customized by calling
  the set_transforms() method.
  """

  data_type = db.Blob
  _tfm = [lambda x: pickle.dumps(x,2), zlib.compress]
  _itfm = [zlib.decompress, pickle.loads]

  def set_transforms(self, tfm, itfm):
    self._tfm = tfm
    self._itfm = itfm

  def get_value_for_datastore(self, model_instance):
    value = super(SerializableProperty,
        self).get_value_for_datastore(model_instance)
    if value is not None:
      value = self.data_type(reduce(lambda x,f: f(x), self._tfm, value))
    return value

  def make_value_from_datastore(self, value):
    if value is not None:
      value = reduce(lambda x,f: f(x), self._itfm, value)
    return value
</pre>
</blockquote>
<p>Usage is as simple as this:</p>
<blockquote>
<pre>class MyModel(db.Model):
  data = SerializableProperty()

entity = MyModel(data = {"key": "value"}, key_name="somekey")
entity.put()
entity = MyModel.get_by_key_name("somekey")
print entity.data
</pre>
</blockquote>
<p>Hope that helps!</p>
<p><strong>Update</strong> (20091126): I&#8217;ve changed db.Blob to self.data_type as suggested by Peritus in <a href="http://thesweeheng.wordpress.com/2009/11/16/gae-storing-serializable-objects-in-datastore/#comment-68" target="_blank">Comment</a>. The same comment also suggested a JSONSerializableProperty subclass:</p>
<blockquote>
<pre>import simplejson as json
class JSONSerializableProperty(SerializableProperty):
  data_type = db.Text
  _tfm = [json.dumps]
  _itfm = [json.loads]</pre>
</blockquote>
<p>Thanks Peritus!</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Il Mito]]></title>
<link>http://gaetanocelso.wordpress.com/2009/11/09/il-mito/</link>
<pubDate>Mon, 09 Nov 2009 16:19:29 +0000</pubDate>
<dc:creator>gaetanocelso</dc:creator>
<guid>http://gaetanocelso.wordpress.com/2009/11/09/il-mito/</guid>
<description><![CDATA[Gae: anche conosciuto come il Mito. Straordinario e stravagante&#8230;]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>Gae: anche conosciuto come il Mito. Straordinario e stravagante&#8230;</p>
<p><a href="http://gaetanocelso.files.wordpress.com/2009/11/l_2048_1536_f2f81edf-4470-403e-b950-49620342bfd5.jpeg"><img src="http://gaetanocelso.files.wordpress.com/2009/11/l_2048_1536_f2f81edf-4470-403e-b950-49620342bfd5.jpeg?w=300&#038;h=225" alt="" width="300" height="225" class="alignnone size-full wp-image-364" /></a></p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[YoDay Application]]></title>
<link>http://aarendar.wordpress.com/2009/11/08/yoday-application/</link>
<pubDate>Sun, 08 Nov 2009 17:29:41 +0000</pubDate>
<dc:creator>Alexander Arendar</dc:creator>
<guid>http://aarendar.wordpress.com/2009/11/08/yoday-application/</guid>
<description><![CDATA[The very first version of my site: http://your-day.appspot.com/home.jsp It&#8217;s like a Twitter bu]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>The very first version of my site: <a title="YoDay" href="http://your-day.appspot.com/home.jsp" target="_blank">http://your-day.appspot.com/home.jsp</a></p>
<p>It&#8217;s like a Twitter but pictorial.</p>
<p>You can log in there with your gmail account.</p>
<p>Current set of features is very basic now:</p>
<p>- search for users (search by &#8220;Alex&#8221; to find me)<br />
- follow/unfollow a user<br />
- simple statistics<br />
- filling your timeline</p>
<p>I will work on it further on but it is really interesting to know your feedback.</p>
<p>It looks like this:</p>
<p><img class="alignnone size-full wp-image-294" title="yoday" src="http://aarendar.wordpress.com/files/2009/11/yoday.jpg" alt="yoday" width="510" height="258" /></p>
<p>Ah, and please use FF browser for now since I have not yet tested it under anything else. Myabe it works under IE/Chrome/etc. as well, just don&#8217;t know <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Any feedback in comments would be great to have.</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Bottle : Authentication]]></title>
<link>http://appmecha.wordpress.com/2009/10/29/bottle-mw-auth/</link>
<pubDate>Thu, 29 Oct 2009 16:08:48 +0000</pubDate>
<dc:creator>delagoya</dc:creator>
<guid>http://appmecha.wordpress.com/2009/10/29/bottle-mw-auth/</guid>
<description><![CDATA[Continuing on with our middleware series, we now cover authentication. There are a ton of authentica]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>Continuing on with our middleware series, we now cover authentication. There are a ton of authentication and authorization WSGI middleware, as well an basic authnetication example used in the WSGI documentation. Some are out of date, and a lot of others are tightly integrated with other parts of a particular frameworks request handling.  It would have been easy enough to RollYO basic authentication, but I really hate reinventing a wheel I don&#8217;t have to.</p>
<p>I decided to investigate AuthKit, part of Pylons, to service my authentication needs, and struggled through a lack of documentation and fairly large code base, all for your pleasure.</p>
<h3>Authentication with AuthKit</h3>
<p>AuthKit assumes a lot of the setup for your middleware follows Pylons conventions. It was a struggle for me to make heads or tails of the examples, not being familiar with Pylons application configuration and how requests were routed. The secret sauce to actually make AuthKit work with bottle is to realize that there are actually multiple levels of AuthKit middleware that you have to invoke to get the authorization chain to even start up. Here is how you go about it in Bottle:</p>
<pre class="brush: python;">
from authkit import authenticate, authorize
from authkit.permissions import RemoteUser

from bottle import *

# bottle exposed function
@default() # maps to root URL
def hello():
    return &#34;hello&#34;

# get the default bottle application
app = default_app()

# set up an authorization permission for
# basic authentication of a remote user
app = authorize.middleware(app, RemoteUser())

# A simple authentication function
def basic_auth(environ, username, password):
    return username ==  password

# now activate the authentication
auth_config = {
    'authkit.setup.method':'basic',
    'authkit.basic.realm':'Test Realm',
    'authkit.basic.authenticate.function':basic_auth,
    'authkit.setup.enable':'True'
}
app = authenticate.middleware(app,app_conf=auth_config)

# run the application
run(app=app)
</pre>
<p>To make this work for App Engine, you need to include the AuthKit sources and account for deploying Bottle applicatios on GAE, covered in the Bottle docs and other posts.</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Bottle : Request Method Overriding]]></title>
<link>http://appmecha.wordpress.com/2009/10/29/bottle-mw-method-override/</link>
<pubDate>Thu, 29 Oct 2009 15:27:43 +0000</pubDate>
<dc:creator>delagoya</dc:creator>
<guid>http://appmecha.wordpress.com/2009/10/29/bottle-mw-method-override/</guid>
<description><![CDATA[Bottle is a great little Web application framework, but in it&#8217;s quest for simplicity, it left ]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>Bottle is a great little Web application framework, but in it&#8217;s quest for simplicity, it left out a couple of key components that are needed for cu3w0rx: HTTP method overriding and basic authentication. Luckily Python&#8217;s WSGI middleware can fulfill this role.</p>
<h3>WSGI Middleware</h3>
<p>WSGI middleware is a handy way to add functionality to an application by adding layers to the request/response chain in between the client request and your application. Incidently, Ruby&#8217;s Rack project took inspiration from WSGI middleware.</p>
<h3>Method Overriding</h3>
<p>A while back I bemoaned the fact that CherryPy&#8217;s RoutedDispatcher could not handle PUT and DELETE requests from forms submitted by your typical web browser, which most often only does GET and POST requests. I submitted a patch to the CherryPy project, but I now believe that this is the wrong approach, and that middleware can handle altering the REQUEST_METHOD header in response to a submitted form with a hidden &#8220;_method&#8221; parameter, as is the accepted convention. Here is some middleware for the server side application which will resige on GAE:</p>
<pre class="brush: python;">
# method_overide.py
# WSGI middleware to set the HTTP REQUEST_METHOD header from a submitted form
# that contains a &#34;_method&#34; hidden variable.

class MethodOverride(object):
  def __init__(self, app):
    self.app = app

  def __call__(self, environ, start_response):
    method = webapp.Request(environ).get('_method')
    if method:
      environ['REQUEST_METHOD'] = method.upper()
    return self.app(environ, start_response)
</pre>
<p>And here is how you would insert it in between your bottle application:</p>
<pre class="brush: python;">
from bottle import *
from google.appengine.ext.webapp import util
from method_override import MethodOverride

@route(&#34;/test_put&#34;,method=&#34;PUT&#34;)
def testput():
  return &#34;PUT success&#34;

@route(&#34;/test_delete&#34;,method=&#34;DELETE&#34;)
def testdelete():
  return &#34;DELETE success&#34;

# run in GAE
def main():
  app= default_app()
  # insert the method override middleware
  app = MethodOverride(default_app())

  util.run_wsgi_app(app)

if __name__ == '__main__':
  main()
</pre>
<p>Now forms that define the REQUEST_METHOD as a hidden param &#8220;_method&#8221; will be routed to the correct function.</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Por el Canon Municipal]]></title>
<link>http://tetraedro.wordpress.com/2009/10/28/por-el-canon-municipal/</link>
<pubDate>Wed, 28 Oct 2009 20:19:21 +0000</pubDate>
<dc:creator>pontifex</dc:creator>
<guid>http://tetraedro.wordpress.com/2009/10/28/por-el-canon-municipal/</guid>
<description><![CDATA[Muy acertada la propuesta que hacen en Halón Disparado. Un canon como el de la $GA€ pero para los po]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>Muy acertada la <a title="Halon Disparado" href="http://halondisparado.com/?p=3345">propuesta que hacen en Halón Disparado</a>. Un canon como el de la $GA€ pero para los políticos:</p>
<blockquote><p>Propongo, pues, la implantación del Canon Municipal, que supondrá que todos los alcaldes (y concejales de urbanismo) de España deben pasar X días en la cárcel, para compensar los posibles delitos de corrupción que hayan cometido o estén en disposición de cometer. El número de días podría calcularse en función del presupuesto del Ayuntamiento y de los metros cuadrados recalificados a urbano en su legislatura.</p></blockquote>
<p>Seguro que Bartomeu Muñoz, alcalde socialista de Santa Coloma de Gramenet, entiende y comparte el espíritu de esta propuesta, no en vano fue <a title="Telecinco" href="http://www.telecinco.es/informativos/nacional/noticia/100010948/Bartomeu+Munoz+el+presunto+alcalde+corrupto+premiado+por+la+SGAE">premiado por la $GA€</a> por ser &#8220;el político más comprometido en la lucha contra la piratería&#8221;. Seguro que este individuo, imputado ahora por cargos de cohecho y malversación de fondos, habría pagado gustoso el &#8220;Canon Municipal&#8221; para evitarse los actuales problemillas con la justicia.</p>
<p>Y ahora que lo pienso, el premio que le concedió la $GA€ ¿sería merecido o un <em>quid pro quo</em>? Investigue Garzón, investigue&#8230;</p>
<p>&#160;</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[cu3w0rx : Bottle]]></title>
<link>http://appmecha.wordpress.com/2009/10/28/cu3w0rx-bottle/</link>
<pubDate>Wed, 28 Oct 2009 14:13:39 +0000</pubDate>
<dc:creator>delagoya</dc:creator>
<guid>http://appmecha.wordpress.com/2009/10/28/cu3w0rx-bottle/</guid>
<description><![CDATA[One of the great aspects of CloudCrowd is that the code base is so small and readable. A big part of]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>One of the great aspects of CloudCrowd is that the code base is so small and readable. A big part of that comes by virtue of using the <a href="http://www.sinatrarb.com">Sinatra Web application framework</a> for the master and slave daemon processes. Sinatra is much closer to the GAE webapp framework than CherryPy (by default), in that you define methods that correspond to the HTTP verbs (GET, PUT, POST, DELETE and HEAD).  Sinatra differs in that the method&#8217;s first argument is the route that the method services. The GAE webapp framework instead forces you to define a class that the defines the HTTP verbs, and later map those classes to some route. Let&#8217;s take a look at &#8220;Hello World!&#8221; to illustrate the difference. Here is the GAE webapp version</p>
<pre class="brush: python;">
from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app

class HelloWorld(webapp.RequestHandler):
	def get(self):
		self.response.out.write(&#34;Hello World!&#34;)

app = webapp.WSGIApplication([(&#34;/&#34;,HellowWorld)])

def main():
	run_wsgi_application(app)

if __name__ == &#34;main&#34;:
	main()
</pre>
<p>Now here is the version in Sinatra:</p>
<pre class="brush: ruby;">
require &#34;rubygems&#34; # RubyGems is optional, depending on your setup
require &#34;sinatra&#34;
get '/' do
  &#34;Hello World!&#34;
end
</pre>
<p>Much more readable and concise. Here is a version of HellWorld in CherryPy, using the default MethodDispatcher, for comparison:</p>
<pre class="brush: python;">
import cherrypy

class HelloWorld:
    exposed = True
    def GET(self):
        return &#34;Hello World!&#34;

app = HelloWorld()

d = cherrypy.dispatch.MethodDispatcher()
conf = {'/': {'request.dispatch': d}}
cherrypy.tree.mount(root, &#34;/&#34;, conf)
</pre>
<p>Better, but you are still separating the the mapping of the root URL &#8220;/&#8221; to the HelloWorld class outside of the class. I started digging around the interwebz for Python frameworks that would work closer to the lightweight Sinatra and found <a>Bottle</a>. Bottle is small, self-contained and uses python decorators to map a function to a route. Brilliant. Here is the example using Bottle:</p>
<pre class="brush: python;">
from bottle import route, run

@route(&#34;/&#34;) # assumes GET method
def hello():
	return &#34;Hello world!&#34;

run() # This starts the HTTP server
</pre>
<p>Now that&#8217;s what I&#8217;m talking about! Deploying a Bottle application to GAE is covered in their <a href="http://bottle.paws.de/page/docs#deployment">documentation</a>. We&#8217;ll be using Bottle for <strong>cu3w0rx</strong> to create the master and slave daemons in later posts.</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Designing cu3w0rx]]></title>
<link>http://appmecha.wordpress.com/2009/10/27/cu3w0rx-design/</link>
<pubDate>Tue, 27 Oct 2009 03:30:18 +0000</pubDate>
<dc:creator>delagoya</dc:creator>
<guid>http://appmecha.wordpress.com/2009/10/27/cu3w0rx-design/</guid>
<description><![CDATA[cu3w0rx. Lovely name, eh? Moving on &#8230; In this series we will be looking to implement a simple ]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p><code>cu3w0rx</code>. Lovely name, eh? Moving on &#8230;</p>
<p>In this series we will be looking to implement a simple Map-Reduce framework that closely models the design and implementation of the <a href="http://github.com/documentcloud/cloud-crowd">CloudCrowd</a>, which is written in Ruby. CloudCrowd  has some nice design choices. Specifically its small size (~1,800 LOC), use of JSON for message transport, and emphasis on HTTP as the protocol is quite nice. It is also pretty to look at, and the interface is entirely AJAX driven, so relies on the same service calls as the rest of the suite.  I think it is worth our while to set the stage for the project. Here are a list of things we will be taking directly from CloudCrowd:</p>
<ol>
<li>The App Engine application will serve as the central master resource.</li>
<li>It will serve as the master work queue. All jobs will be submitted to it for processing.</li>
<li>All communication will be via JSON messages. As in CC, the web site will make use of the JSON returned from AJAX requests to the resource handlers.</li>
<li>There will be a clear specification for the top-level properties of a Job message, but handlers will be responsible for vetting the provided options to handle the request.</li>
<li>Operations on inputs are assumed to happen on local disk. E.g. jobs will be staged onto the worker nodes&#8217; scratch space.</li>
<li>Jobs will have the option of a callback URL on success.</li>
<li>For simplicity&#8217;s sake, authentication to the master, and between master and slaves, will be the same basic HTTP authentication credentials.</li>
<li>A worker node will accept work item requests based on the machine&#8217;s load.</li>
</ol>
<p>There will be several points that will stray from CloudCrowds implementation as well:</p>
<ol>
<li>Nodes will publish their capabilities to the master. It will not be assumed that all nodes have all the same capabilities. In this respect <code>cu3w0rx</code> will more resemble the <a href="http://github.com/ezmobius/nanite">nanite project</a> (Ruby + ERLang).</li>
<li>Worker nodes will not share the same code base as the master. The major reason for this is that worker nodes will not run on GAE, hence it makes no sense to hamstring them with the restrains that GAE imposes on python.</li>
<li>Workers will maintain their own state in a local database. This will server to keep track of capabilities, number of jobs processed, monitoring statistics, and results from previous jobs.</li>
<li>Map and reduce are implemented as two separate jobs, as far as the worker nodes are concerned.</li>
<li>Since this is a demonstration project, we will not implement a scheme to save result files to non-volitile storage. Instead we will provide a way to give authenticated access to result files from worker nodes. Result files from Reduce phases will live only at the final destination host (e.g. the hosts that have checked back into the master as having succeeded a particular job.</li>
<li>The queue is not necessarily FIFO. I am actually not sure if this is also true about CloudCrowd, but its worth mentioning here.</li>
</ol>
<p>I would also like to implement a way to provision and configure cloud VMs using the excellent <a href="http://libcloud.org/">libcloud</a> library, but I think that is outside the scope of a demonstration project. If you see anything missing (or think some stuff can be left out) leave a comment!</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Europa ziet Clouds teveel als donderwolk]]></title>
<link>http://hanseilers.wordpress.com/2009/10/22/europa-ziet-clouds-teveel-als-donderwolk/</link>
<pubDate>Thu, 22 Oct 2009 18:39:00 +0000</pubDate>
<dc:creator>hanseilers</dc:creator>
<guid>http://hanseilers.wordpress.com/2009/10/22/europa-ziet-clouds-teveel-als-donderwolk/</guid>
<description><![CDATA[Cloud computing is over enkele jaren alomtegenwoordig en even vanzelfsprekend als stroom. Dan zullen]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><table border="0" cellspacing="0" cellpadding="0" width="445">
<tbody>
<tr>
<td class="lead-tekst-zwart" style="font-size:11px;color:#000000;line-height:16px;font-weight:bold;padding:6px 0 20px;" align="left" valign="top">Cloud computing is over enkele jaren alomtegenwoordig en even vanzelfsprekend als stroom. Dan zullen we met bevreemding terugkijken op onze interne serverruimtes, gehuurde rackspace, maar vooral op de vrees die op dit moment, vooral in Europa, nog heerst voor Cloud computing. Wat houdt Europa tegen?</td>
</tr>
</tbody>
</table>
<table border="0" cellspacing="0" cellpadding="0" width="445">
<tbody>
<tr>
<td class="tekst-zwart" style="font-size:11px;color:#000000;line-height:16px;padding-right:10px;">
<div class="article">
<p><strong>Cloud Computing?</strong></p>
<p>Cloud computing is computerkracht waarbij capaciteit dynamisch schaalbaar beschikbaar en gevirtualiseerd is. Het wordt als een dienst aangeboden en gebruikers hebben geen kennis over of controle op de fysieke omgeving waarop de ‘cloud’ draait.</p>
<p>Zonder dat de meesten van ons het weten, maken we reeds allemaal op een of andere manier gebruik van Cloud computing. Diensten als Gmail en Hotmail zijn bijvoorbeeld gebaseerd op Cloud computing.</p>
<p>Er bestaan verschillende soorten Cloud computing. Er zijn varianten waarbij een compleet besturingssysteem wordt aangeboden waarbij de gebruiker alle rechten binnen dat systeem heeft. Dit biedt de meeste flexibiliteit, maar is ook een meer complexe oplossing. <a style="color:#cc0000;text-decoration:underline;" href="http://aws.amazon.com/ec2/" target="_blank">Amazon EC2</a> is hier een voorbeeld van. EC2 biedt Linux en Windows servers die per uur worden afgerekend. De gebruiker kan hier elke willekeurige applicatie op draaien, dus niet alleen webapplicaties. Inderdaad, er zijn nog applicaties die niet via een browser benaderbaar zijn &#8230;</p>
<p>Microsoft biedt met <a style="color:#cc0000;text-decoration:underline;" href="http://www.microsoft.com/azure/" target="_blank">Azure</a> een oplossing waarbij geen besturingssysteem wordt geboden, maar een applicatieruimte; een scala aan diensten en twee databaseoplossingen. Daarnaast zijn er configuratieopties die iets meer controle geven. Google biedt met <a style="color:#cc0000;text-decoration:underline;" href="http://code.google.com/appengine/" target="_blank">Google App Engine (GAE)</a> een oplossing waarbij er puur een applicatieruimte en een database geboden wordt. Azure en GAE schalen allebei automatisch op bij meer gebruik. Ook zijn ze gericht op webapplicaties en niet op desktopapplicaties.</p>
<p>Cloud Computing is een breed begrip waar ook de volgende termen onder vallen:</p>
<ul>
<li>Sofware as a Service (Saas),</li>
<li>Storage as a Service,</li>
<li>Security as a Service,</li>
<li>Content as a Service,</li>
<li>Integration as a Service en</li>
<li>Platform as a Service (Paas).</li>
</ul>
<p>Op basis van deze definitie, zijn Google Apps (niet hetzelfde als Google App Engine), Zoho etc. ook Cloud computing oplossingen.</p>
<p><strong>Besparen met clouds</strong></p>
<p>Cloud computing is per definitie een gecentraliseerd model. Deze centralisatie brengt met zich mee dat het eenvoudiger is de CO2 uitstoot te verminderen dan wanneer we allemaal onze eigen serverruimte zouden behouden. Aangezien IT op dit moment verantwoordelijk is voor 2% van de globale CO2 uitstoot en dit aandeel in de toekomst alleen maar groter zal worden, is hier veel winst te behalen.</p>
<p>Cloud computing kan ook op andere manieren zorgen voor besparing. Doordat de capaciteit van een cloud gedeeld wordt onder vele afnemers, is er uiteindelijk minder energie nodig om dezelfde diensten te leveren. Hardware standaardisatie, betere recycling van hardware en efficiëntere koeling zijn meer voordelen op een globale schaal.</p>
<p>Daarnaast biedt het afnemers van Cloud computing het voordeel van schaalbaarheid. In een scenario waarbij er sprake is van seizoenale pieken is er traditioneel een serveromgeving nodig die dubbel is uitgevoerd en die een verwachte piek ruim voldoende kan opvangen. De rest van het jaar staat de hardware nutteloos te draaien terwijl het wordt afgeschreven.  Cloud computing maakt dit scenario een stuk goedkoper. Doordat de pieken opgevangen kunnen worden door virtueel bij te schalen, is de investering in hardware niet nodig.</p>
<p>Tevens is de beheersinspanning bij het gebruik van Cloud computing lager. Puur het feit dat er geen fysieke hardware is waar aandacht aan besteed moet worden, levert al winst op. Door de flexibiliteit van gevirtualiseerde omgevingen die in mum van tijd &#8216;bijgeplaatst&#8217; kunnen worden, zijn de beheerskosten van Cloud computing lager. Ja, er is natuurlijk een leercurve, maar die hadden we ook bij traditionele oplossingen. Lagere beheerskosten, maar ook lagere start up-kosten leveren organisaties financieel voordeel op. Kosten van airconditioning, beveiliging, brandblusinstallaties en elektriciteit zijn bij Cloud computing niet aan de orde. Er wordt alleen betaald voor het gebruik van de &#8216;resources&#8217;.</p>
<p>De huidige economische situatie maakt dat organisaties zitten te springen om dergelijke kostenbesparende oplossingen. De VS hebben deze klok al duidelijk horen luiden.</p>
<p><strong>VS omarmen clouds, waar blijft Europa?</strong></p>
<p>Het is interessant om te zien dat de regering in de VS Cloud computing zo stimuleert. <a style="color:#cc0000;text-decoration:underline;" href="https://www.apps.gov/cloud/advantage/main/start_page.do" target="_blank">Zie hier hoe de regering van de VS omgaat</a> met clouds. Cloud computing wordt door de VS actief gepromoot &#8211; op een bijna Postbus-51-achtige manier. Geweldig om te zien dat ze de noodzaak inzien van Cloud computing en op die manier werken aan betere efficiency, kostenbesparing en het milieu. Waarom loopt Europa hier dan nog met een boog omheen, terwijl de voordelen voor het oprapen liggen?</p>
<p>?Er kleven een aantal inherente risico&#8217;s aan Cloud computing. Privacy is daarvan de belangrijkste. Organisaties zijn gewend om het bewaken van hun data door hun eigen systeembeheerders op hun eigen servers, in hun eigen kantoren uit te laten voeren. De stap naar &#8216;de cloud&#8217; is dan moeilijk te nemen. De verschillende aanbieders van clouds gaan anders om met privacy, maar uiteindelijk komt het neer op degene die de applicaties maakt. Door slim gebruik te maken van encryptie van data, een goede wachtwoord &#8216;policy&#8217; en controle van deze &#8216;policies&#8217;, worden de risico&#8217;s beperkt.</p>
<p>Daarnaast is de locatie van de datacenters waar de clouds staan voor sommige organisaties, vanwege wettelijke beperkingen, belangrijk. De overheid moet er bijvoorbeeld voor zorg dragen dat haar data binnen de Europese Economische Ruimte (EER) wordt opgeslagen. Voor zover bekend voldoen alleen EC2 en S3 van Amazon hieraan. Voor beide oplossingen staan sowieso datacenters in Ierland en wordt directe uitwisseling van data tussen EU datacenters en die in de VS niet toegelaten.</p>
<p>Onduidelijk is hoever de <a style="color:#cc0000;text-decoration:underline;" href="http://en.wikipedia.org/wiki/USA_PATRIOT_Act" target="_blank">Patriot Act</a> reikt. Zouden de VS bij data in datacenters van Microsoft, Google, Amazon mogen komen die niet op VS grondgebied staan?</p>
<p>??Beveiliging is ook een hekel punt bij Cloud computing. Niet altijd terecht. Laten we het vergelijken. Zie <a style="color:#cc0000;text-decoration:underline;" href="http://s3.amazonaws.com/aws_blog/AWS_Security_Whitepaper_2008_09.pdf">hier bijvoorbeeld de beveiligingsnormen</a> van Amazon EC2. Waarschijnlijk is EC2 veiliger dan de servers in uw eigen serverruimte op de gang en mogelijk ook veiliger dan de servers die bij uw hostingleverancier in het &#8216;rack&#8217; hangen.</p>
<p>Tenslotte kan bandbreedte in sommige Europese landen de beperkende factor voor Cloud computing zijn. In gebieden waar bandbreedte beperkt is, zal Cloud computing minder mogelijkheden bieden. In Nederland hebben we voldoende bandbreedte, een stijgende lijn in de snelheid en een dalende trend in de kosten – goed voor clouds.</p>
<p><strong>Balans opmaken</strong></p>
<p>Het is tijd voor ons om de balans op te maken en de voors en tegens goed tegen elkaar af te wegen. Dan zal al snel blijken dat de voordelen de overhand hebben. Buiten alle eerder genoemde voordelen op het gebied van financiën, milieu en efficiency, biedt Cloud computing namelijk ook nog eens enorm veel potentie voor de toekomst. Iets waar je nauwelijks om heen kunt, gezien de ontwikkelingen die gaande zijn in de markt.</p>
<p>?Denk aan Cloud gaming &#8211; waar de eindgebruiker niet elk jaar een nieuwe game console hoeft want de game wordt &#8216;gerenderd&#8217; door een cloud omgeving. Er is geen nieuwe videokaart meer nodig, want de game wordt &#8216;gestreamd&#8217; naar TV.</p>
<p>Net als het elektriciteitsnet het in korte tijd heeft overgenomen van particuliere / kleinschalige elektriciteitsproductie zal Cloud computing een vergelijkbaar effect hebben op private hosting, interne serverparken en gehuurde rackspace. Serverruimte zal dus als elektriciteit worden.</p>
<p>Al met al kan worden geconcludeerd dat Cloud Computing de kosten vermindert, de complexiteit flink reduceert, het milieu minder belast en grote potentie biedt voor de ICT van de toekomst. Reden genoeg om, net als in de VS, Cloud Computing stevig te omarmen in Europa en dus ook in Nederland. De grootste uitdaging zit hem erin de vooroordelen die rond Cloud Computing bestaan, plaats te laten maken voor de talrijke voordelen die het ons kan bieden.</p>
<p>En ja, er zijn groot uitgemeten problemen die zich voordoen bij diensten in de cloud, denk maar aan de <a style="color:#cc0000;text-decoration:underline;" href="http://news.google.com/news/search?aq=f&#38;um=1&#38;cf=all&#38;ned=us&#38;hl=en&#38;q=Sidekick" target="_blank">Sidekick problemen</a> &#8211; veroorzaakt door onvoorstelbaar slecht beheer. Ja het zal nog wel een keer voorkomen dat er fouten gemaakt worden met deze technologie</p>
<p>Maar van de eerste browser zei men ook dat het traag en grijs was met teveel blauwe links, dus dat internet zou wel niks worden <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
</div>
</td>
</tr>
</tbody>
</table>
<p>&#160;</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Book Review : Using Google App Engine]]></title>
<link>http://jimlawless.wordpress.com/2009/10/09/book-review-using-google-app-engine/</link>
<pubDate>Sat, 10 Oct 2009 01:37:47 +0000</pubDate>
<dc:creator>Jim Lawless</dc:creator>
<guid>http://jimlawless.wordpress.com/2009/10/09/book-review-using-google-app-engine/</guid>
<description><![CDATA[Book title: Using Google App Engine Edition: First Edition ( May 2009 ) Author: Charles Severance Pu]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p><img src="http://www.mailsend-online.com/wp/google_app.jpg" /> </p>
<p><strong>Book title:</strong> Using Google App Engine<br />
<strong>Edition:</strong> First Edition ( May 2009 )<br />
<strong>Author:</strong> Charles Severance<br />
<strong>Publisher:</strong> O&#8217;Reilly &#124; Google Press<br />
<strong>Cover Price:</strong> $29.99 ( U.S. )</p>
<p>I&#8217;ve been interested to try out some of the free <em>Cloud Computing</em> offerings that are rising into vogue.  The one that looked to have the lowest barrier-to-entry, was the Google App Engine (GAE).</p>
<p>I downloaded the local GAE development environment ( the Python flavor, not the Java edition ) and walked through the series of examples in Google&#8217;s tutorial.  Through the tutorial, I received a little exposure to the Datastore service and the Django-compatible templating mechanism.  It was a nice enough introduction, but I wanted to know more.</p>
<p>I searched for some GAE books and found some good reviews of this text. I ordered a copy.</p>
<p><strong>What I Skimmed</strong></p>
<p>The book is  a nice enough introduction to web programming in general.  It contains chapters covering the mechanics of web transactions, the history of HTML and CSS, and a 30-page introduction to programming in Python ( 2.5 ).</p>
<p>I skimmed through these chapters as I suspect a fair number of web developers would do.  I did briefly go through the Python tutorial and found it to be concise and informative.  Actually, it begins as an introduction to general programming using Python.</p>
<p>A guess-the-number game is provided which serves as a reference model for some of the concepts.  If they haven&#8217;t already, they should snip this section out as a PDF and give it away.</p>
<p>The tutorial manages to introduce control-flow, strings, functions, lists, dictionaries and objects in a short span of pages.</p>
<p>I completely skipped the chapters that describe how to install the GAE development environment on various platforms.  The author covers installation on Windows XP, Windows Vista, Mac OS, and Linux. No specific Linux distribution is cited.  The installation instructions are probably similar for most distributions.</p>
<p><strong>The Good Stuff</strong></p>
<p>The book does a good job in leveraging the Django-compatible templating mechanism.  I had seen some of these templates before, but was not overly impressed with the mechanism until I saw them use a convention that I wasn&#8217;t used to.</p>
<p>In normal templating systems that I&#8217;m used to, it&#8217;s common to leverage an <em>include</em> directive to pull in common snippets of HTML and/or other template code for common headers, footers, and such.  The convention that the author used for the Django templates was different.</p>
<p>In the template scheme he used, a baseline template is defined with a &#8220;body&#8221; section.  All other templates refer to this baseline template and override the content of the body section; they contain only the changes to that section.</p>
<p>In a way, this is kind of like an object-oriented document system that observes the <em>inheritance</em> property of OOP.  If one wants to make look-and-feel changes, they would likely only have to change the baseline template.</p>
<p>Later examples illustrate how to override multiple blocks of text in the baseline template.</p>
<p>The author takes the reader through some pretty fair examples.  He builds a web equivalent to the guess-the-number game to show the reader how a desktop console application and a web application differ in code and execution.  He does a good job introducing the reader to CGI programming.</p>
<p>He then builds a real-time chat application leveraging JQuery for a smooth AJAX interface to the web app.  He proceeds to build a functioning, multi-user web chat system.</p>
<p>We are introduced to the Datastore, the memory cache (memcached) interface, and the logging mechanism.</p>
<p>I enjoyed seeing some of the administrative console features.  One can view the logs and can also invoke Python code interactively, which I find to be quite liberating.  It&#8217;s nice to have a REPL ( read-evaluate-print-loop ) that will let you interact with the same back-end objects that your web code is using.</p>
<p>Please note that I have yet to actually try out any of this code.  I assume that it works properly.  I also assume that any errors in the code are corrected in an <em>errata</em> section somewhere on the web.</p>
<p><strong>What I Didn&#8217;t Care For</strong></p>
<p>The author spent some time building a session mechanism based on the <em>memcached</em> interface.  This mechanism did not seem to be backed up by persistent writes to the Datastore as memcached is a volatile cache.  The author admitted that the cache could end up removing the cached session info.</p>
<p>It&#8217;s my understanding that GAE provides a <em>users</em> class that provides a login mechanism and ( I would hope ) a persistent session object.  I don&#8217;t know much about this, but it shows up in the Google <em>helloworld.py</em> application on the Google tutorial.  It would have been nice to see how this works in the printed text.</p>
<p>The author mentions the HTTP form-file upload, but never mentions how the GAE framework can be made to process file uploads.  It&#8217;s not really essential to the book, but I&#8217;m kind of curious as to why it was referenced in the first place, unless he wanted to describe the mechanics used to publish one&#8217;s Python code and supporting files to the GAE cloud.</p>
<p><strong>Closing Thoughts</strong></p>
<p>Overall, I would recommend ( and have recommended ) the book to friends.  It&#8217;s a nice intro that has some diverse foundational information that would seem to make the book accessible to quite a broad audience.</p>
<p><a href="http://del.icio.us/post?url=http://jimlawless.wordpress.com/2009/10/09/book-review-using-google-app-engine/&#38;title=Book+Review+:+Using+Google+App+Engine" target="_blank"><img title="del_icio_us" src="http://www.mailsend-online.com/wp/del_icio_us.png" alt="del_icio_us" /></a> <a href="http://del.icio.us/post?url=http://jimlawless.wordpress.com/2009/10/09/book-review-using-google-app-engine/&#38;title=Book+Review+:+Using+Google+App+Engine" target="_blank">Save to del.icio.us</a><br /><a href="http://digg.com/submit?phase=2&#38;url=http://jimlawless.wordpress.com/2009/10/09/book-review-using-google-app-engine/&#38;title=Book+Review+:+Using+Google+App+Engine" target="_blank"><img title="digg" src="http://www.mailsend-online.com/wp/digg.png" alt="digg" /></a> <a href="http://digg.com/submit?phase=2&#38;url=http://jimlawless.wordpress.com/2009/10/09/book-review-using-google-app-engine/&#38;title=Book+Review+:+Using+Google+App+Engine" target="_blank">Digg it</a><br /><a href="http://reddit.com/submit?url=http://jimlawless.wordpress.com/2009/10/09/book-review-using-google-app-engine/&#38;title=Book+Review+:+Using+Google+App+Engine" target="_blank"><img title="reddit" src="http://www.mailsend-online.com/wp/reddit.png" alt="reddit" /></a> <a href="http://reddit.com/submit?url=http://jimlawless.wordpress.com/2009/10/09/book-review-using-google-app-engine/&#38;title=Book+Review+:+Using+Google+App+Engine" target="_blank">Save to Reddit</a><br /><a href="http://www.facebook.com/share.php?u=http://jimlawless.wordpress.com/2009/10/09/book-review-using-google-app-engine/" target="_blank"><img title="facebook" src="http://www.mailsend-online.com/wp/facebook.png" alt="facebook" /></a> <a href="http://www.facebook.com/share.php?u=http://jimlawless.wordpress.com/2009/10/09/book-review-using-google-app-engine/" target="_blank">Share on Facebook</a><br /><a href="http://twitter.com/home?status=Check+out+http://jimlawless.wordpress.com/2009/10/09/book-review-using-google-app-engine/"><img title="twitter" src="http://www.mailsend-online.com/wp/twitter.gif" alt="twitter" /></a> <a href="http://twitter.com/home?status=Check+out+http://jimlawless.wordpress.com/2009/10/09/book-review-using-google-app-engine/" target="_blank">Share on Twitter</a><br /><a href="http://www.addthis.com/bookmark.php?pub=dvd&#38;url=http://jimlawless.wordpress.com/2009/10/09/book-review-using-google-app-engine/;title=Book+Review+:+Using+Google+App+Engine" target="_blank"><img title="aolfav" src="http://www.mailsend-online.com/wp/aolfav.gif" alt="aolfav" /></a> <a href="http://www.addthis.com/bookmark.php?pub=dvd&#38;url=http://jimlawless.wordpress.com/2009/10/09/book-review-using-google-app-engine/;title=Book+Review+:+Using+Google+App+Engine" target="_blank">More bookmarks</a>
<p><img src="http://www.mailsend-online.com/cgi-bin/wphit.pl" /><br />
<em>Unless otherwise noted, all code and text entries are Copyright © 2009 by James K. Lawless</em></p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[groovytweets update 10]]></title>
<link>http://hansamann.wordpress.com/2009/10/08/groovytweets-update-10/</link>
<pubDate>Fri, 09 Oct 2009 06:09:35 +0000</pubDate>
<dc:creator>hansamann</dc:creator>
<guid>http://hansamann.wordpress.com/2009/10/08/groovytweets-update-10/</guid>
<description><![CDATA[It&#8217;s more than 2 months ago since I blogged about the groovytweets status, but there have been]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>It&#8217;s more than 2 months ago since I blogged about the <a href="http://groovytweets.org">groovytweets</a> status, but there have been numerous minor updates and improvements. The friends list (the Twitter users we collect tweets from) has been expanded to ~422 followers (and <a href="http://www.groovytweets.org/public/friends">likely more</a> when you read this), the regular expressions used to decide if a tweet is &#8216;groovy&#8217; has been adapted to the changing groovy universe (like gparallelizer renamed to gpars or following vmware news now), and so it goes on.</p>
<p>But the real meat is a bit behind the scenes. The features you&#8217;re likely to see quite early are language detection (filtering by language) and a new <a href="http://www.groovytweets.org/public/links">link ranking</a>. I still have to improve the quality of language detection as tweets often use English terms even if the tweet itself would be written in a different language. Larger texts submitted to the Google Translation API of course yield better results; tweets just having 140 characters makes this a bit harder.</p>
<p>The<a href="http://www.groovytweets.org/public/links"> groovy link ranking feature</a> can already be seen live in an early version. I am now collecting the links and tracking their usage in tweets the same as retweets for tweet. The nice thing is that I am tracking the final URL, so if someone used bit.ly to create a short version of a URL I am actually following the redirects to find the final destination. Next, I am prepared to limit the links shown in the UI to the last weeks (2 currently) and in addition the relevancy of the links degrades over time. This means a link from today having 5 mentions in the groovy community will eventually be higher ranked than a link from yesterday having 6 mentions, simply becuase time is an important factor for relevancy.</p>
<div id="attachment_96" class="wp-caption alignleft" style="width: 310px"><a href="http://www.groovytweets.org/public/links"><img class="size-medium wp-image-96" title="Appengine Link Data View" src="http://hansamann.wordpress.com/files/2009/10/screen-shot-2009-10-08-at-11-07-46-pm.png?w=300" alt="Links" width="300" height="260" /></a><p class="wp-caption-text">Links</p></div>
<p>The real real change for groovytweets is yet to come though. As you might have heard, the new <a href="http://news.cnet.com/8301-13577_3-10356837-36.html">Twitter Retweet API </a>is on it&#8217;s way. It has been changed multiple times now, based on a lot of user input flowing to Twitter and hopefully even mine. It will fundamentally change how Twitter aggregators/relevancy tools can count retweets. For now a Retweet was a community-agreed syntax, like RT @originaluser text. In groovytweets code I was analyzing each incoming Tweet to decide if it fits in one of the many retweet syntaxes and tried to find the original tweet, then tried to look that tweet up and increase the relevancy.</p>
<p>Well, now Twitter is making the Retweet an official concept of Twitter. They even give you a new API method to look up the total retweets of a tweet, which sounds great. The downside is that each Twitter account may currently use 150 API calls per hour. If I wanted to update 50 tweets displayed on the groovytweets homepage every minute, this means 50 Tweets * 60 Calls per hour = 3000 calls per hour. Well, I got 150. An that is not including the minutely check on new tweets coming from groovytweets friends. So: we&#8217;re in trouble here. One solution would be to get whitelisted for more API calls, but there is a better one (or two).</p>
<p>The one solution I still got some hope for is that Twitter will simply include a retweet count with each Tweet. The problem here, I guess, is that I am interested in the retweets within a specific community only. And providing the count only for *my* friends instead of a global retweet count (which is way less relavant some might argue) might potentially be a pretty resource intensive task for them.</p>
<p>The next and more likely solution involves using the Twitter Streaming API. The good thing about the API is that it will show retweets. Although the API just changed again, making the Retweet now the top element instead of the Tweet (and including a retweet_details element), it is then very easy to detect a Retweet. The bad news: Groovytweets is hosted on Google Appengine, and Appengine kills each request after about 30 seconds. So I invested some time finding a cheap vServer on which I open a permanent streaming connection to Twitter. I will then call an API over on groovytweets to feed the retweet information into the app. This splits the system into two parts, which I wanted to avoid, but it looks like the best solution.</p>
<p>Follow me <a href="http://twitter.com/hansamann">@hansamann</a> to get the news as it happens.</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Heroku versus GAE &amp; GAE/J]]></title>
<link>http://rrees.wordpress.com/2009/10/08/heroku-versus-gae-gaej/</link>
<pubDate>Thu, 08 Oct 2009 10:10:47 +0000</pubDate>
<dc:creator>rrees</dc:creator>
<guid>http://rrees.wordpress.com/2009/10/08/heroku-versus-gae-gaej/</guid>
<description><![CDATA[At the Geek Night last night there was a lot of questions about how Heroku compared with Google App ]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>At the <a title="LGN: Heroku" href="http://londongeeknights.wetpaint.com/page/Heroku">Geek Night last night</a> there was a lot of questions about how Heroku compared with Google App Engine (and I guess implicit in that how it compares to <a title="JRuby GAE Gem on Google Code" href="http://code.google.com/p/appengine-jruby/">GAE/J with the JRuby gem</a>). Since it came up several times I thought it would be interesting to capture some of the answers.</p>
<p>Firstly there are the similarities, both deal with the application as the base unit of cloud scaling. Heroku offers several services that are similar to GAE, e.g. mailing, scheduled and background jobs. Some aspects like Memcache are in beta with Heroku but fundamentally both services seem to concur.</p>
<p>They are both free to start developing and then the pricing for the system varies a bit between the two, GAE might be cheaper but also has a more complex set of variables that go into the pricing, Heroku prices on: data size, web processes required and then options, so it&#8217;s easier to project your costs.</p>
<p>Differences then: well a big one is that Heroku uses a standard SQL database and also has excellent import/export facilities. GAE uses Google BigTable which is great for scaling and availability but data export and interactions are very limited. Heroku has an amazing deployment mechanism that involves simply pushing to a remote branch. GAE is slightly more involved but it is still relatively easy compared with deploying your own applications.</p>
<p>GAE provides access to a variety of Google services that are handy such as Google Account integration and image manipulation. GAE also has XMPP integration which is pretty unique if you have the requirement. However these do tie you to the platform and if you wanted to migrate you&#8217;d have to avoid using the Google webapp framework and the API. If flexibility is an issue you are probably going to prefer Heroku&#8217;s use of standard Ruby libraries and frameworks.</p>
<p>Heroku has few restrictions on what can and can&#8217;t be done in a web process, you also have quite powerful access to the user space your application runs in. GAE and particularly GAE/J has a lot of restrictions which can be quite painful particularly as there can be a discrepency between development and deployment environments.</p>
<p>However running a JVM in the cloud provides a lot of flexibility in terms of languages that can be used and deployed. Heroku is focussing on Ruby for now.</p>
<p>From my point of view, choose Heroku if you need: uncomplicated Rails/Rack application deployment, a conventional datastore that you want to have good access to, a simple pricing model. Choose GAE if you want to have out of the box access to Google&#8217;s services and a complete scaling solution.</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[GAE Testbed Documentation Released]]></title>
<link>http://jgeewax.wordpress.com/2009/10/06/gae-testbed-documentation-released/</link>
<pubDate>Tue, 06 Oct 2009 03:38:58 +0000</pubDate>
<dc:creator>JJG</dc:creator>
<guid>http://jgeewax.wordpress.com/2009/10/06/gae-testbed-documentation-released/</guid>
<description><![CDATA[I&#8217;d been looking to get familiar with Sphinx for a while, and couldn&#8217;t ever seem to find]]></description>
<content:encoded><![CDATA[I&#8217;d been looking to get familiar with Sphinx for a while, and couldn&#8217;t ever seem to find]]></content:encoded>
</item>
<item>
<title><![CDATA[Hacking the Google App engine with python]]></title>
<link>http://happyt.wordpress.com/2009/09/25/hacking-the-google-app-engine-with-python/</link>
<pubDate>Fri, 25 Sep 2009 08:41:00 +0000</pubDate>
<dc:creator>ianm</dc:creator>
<guid>http://happyt.wordpress.com/2009/09/25/hacking-the-google-app-engine-with-python/</guid>
<description><![CDATA[Our company had a hack day last week and I thought that I’d have a look at the Google App engine. I ]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>Our company had a hack day last week and I thought that I’d have a look at the Google App engine. I was getting used to the management reply of “do you have a budget code?” when asking for a server in the racks, so I thought that I’d experiment with some data in the cloud. I had taken in the story about the Guardian knocking up a quick python web app using Django to notate the MP’s expenses information. I heard tell it took a week so I thought I might get something simple done in a day.<br />
<!--more--><br />
What I hadn’t realised is that <a href="http://simonwillison.net/">Simon Willison</a>, who wrote the Guardian app, had been a major contributor to the Django framework and so knew it backwards. Sigh. I did have a look at the framework but in the midst of various problems with wifi, there was just too much for the first half day. In the end I just cut some simple python code together to see what response times were like and to get a flavour of the database side in the Google App engine. It was a good experience and convinced me to give it another go after learning more about Django. I’ve put some notes here about what I needed for development and a few demo screens about the app that I created.</p>
<p>I needed python on the laptop, so I went for the latest version, v3. That was my first mistake. Google doesn’t work too well with this version; it has some idiosyncracies that require 2.6. I had to uninstall the new version and set up the older version. I would advise over riding the default directories, as some parts of the operation (patchng for django?) seem to falter over spaces in directory names. In the end I installed to the C:/python26 directory and all seemed to work. I then installed the app-engine-patch that is needed to run Django on the Google App engine. I used version 1.1. It was interesting to start looking at Django, but I found that I needed serious learning time. In the end I decided just to set up some simple REST service to input some records and return some XML.</p>
<p>Once python is on your development machine, you need to add the Google app engine tools. These give a simple gui to allow you to control the loading and running of several services, each with their own socket. Write the app using any favourite editor (htmlkit is a simple, free one that I can recommend &#8211; although I&#8217;m normally on eclipse), then compile and run with this gui. It will run the app on a local server, which is booted automatically. Browse to the server with eg http://localhost:8080 and the app will be run. A few seconds delay the first time, as it is being compiled. You choose the port number when loading the app, so you can have several apps running at one time. Pause them, continue etc.<br />
<a href="http://happyt.wordpress.com/files/2009/09/gae-python.png"><img src="http://happyt.wordpress.com/files/2009/09/gae-python.png" alt="gae-python" title="gae-python" width="480" height="269" class="alignleft size-full wp-image-567" /></a></p>
<p>What happens in the app and what sub pages exist, are defined in the application. It effectively links a routine to a page url. When you’ve tested your application locally, just click the Deploy button and it will be sent up to Google’s cloud and it will then be available across the net. It really is simple.</p>
<p>Two main files are required, app.yaml and main.py</p>
<p>An example of app.yaml is,</p>
<p><code>application: data-form<br />
version: 1<br />
runtime: python<br />
api_version: 1<br />
handlers:<br />
- url: .*<br />
  script: main.py<br />
</code></p>
<p>This names the application as data-form and defines the action for all the pages in the application as main.py. There are only a limited number of application names allowed per developer (10, I think).</p>
<p>Main.py is where the logic is stored and has the definitions of the processing, the classes and the urls.</p>
<p>First we have the normal includes for the libraries,</p>
<p><code>import cgi<br />
from google.appengine.api import users<br />
from google.appengine.ext import webapp<br />
from google.appengine.ext.webapp.util import run_wsgi_app<br />
from google.appengine.ext import db<br />
</code><br />
The class definition for the objects in the database, in this case a football fixture,</p>
<p><code>class Fixture(db.Model):<br />
  user = db.UserProperty()<br />
  league = db.StringProperty()<br />
  status = db.StringProperty()<br />
  home = db.StringProperty()<br />
  hscore = db.StringProperty()<br />
  ascore = db.StringProperty()<br />
  away = db.StringProperty()<br />
  date = db.DateTimeProperty(auto_now_add=True)<br />
</code></p>
<p>The following class creates the display page. It reads from the fixtures database, using the gql querylanguage. Then it writes out the fixtures, followed by a form to input a new fixture. </p>
<p><code><br />
class MainPage(webapp.RequestHandler):<br />
  def get(self):<br />
    self.response.out.write('')<br />
    fixtures = db.GqlQuery("SELECT * FROM Fixture ORDER BY home ASC LIMIT 10")<br />
#<br />
    for fixture in fixtures:<br />
      if fixture.status:<br />
        self.response.out.write('<b>%s ' % fixture.league )<br />
        self.response.out.write('%s ' % fixture.home )<br />
        self.response.out.write('%s-' % fixture.hscore )<br />
        self.response.out.write('%s ' % fixture.ascore )<br />
        self.response.out.write('%s ' % fixture.away )<br />
        self.response.out.write('</b><br />' )<br />
      else:<br />
        self.response.out.write('<b>%s v </b><br />' % fixture.home)<br />
#<br />
# Write the submission form and the footer of the page<br />
    self.response.out.write("""<br />
            &#60;div&#62;<br />
		 Fixture<br />
		 Started<br />
		 Finished<br />
		&#60;br /&#62;<br />
		 Prem<br />
		 Championship<br />
		 Second<br />
		&#60;br /&#62;<br />
		Home<br />
		Away<br />
		&#60;br /&#62;<br />
	    &#60;/div&#62;<br />
            &#60;div&#62;&#60;/div&#62;<br />
      """)<br />
</code></p>
<p>Which gives a screen like this, </p>
<p><a href="http://happyt.wordpress.com/files/2009/09/gae-python-list1.png"><img src="http://happyt.wordpress.com/files/2009/09/gae-python-list1.png?w=300" alt="gae-python-list" title="gae-python-list" width="417" height="278" class="aligncenter size-medium wp-image-559" /></a></p>
<p>The following class is used to add the fixture from the form data.</p>
<p><code>class AddFixture(webapp.RequestHandler):<br />
  def post(self):<br />
    fixture = Fixture()<br />
#<br />
    if users.get_current_user():<br />
      fixture.author = users.get_current_user()<br />
#<br />
    fixture.league = self.request.get('league')<br />
    fixture.status = self.request.get('status')<br />
    fixture.home = self.request.get('home')<br />
    fixture.hscore = self.request.get('hscore')<br />
    fixture.ascore = self.request.get('ascore')<br />
    fixture.away = self.request.get('away')<br />
#<br />
    fixture.put()<br />
    self.redirect('/')<br />
</code></p>
<p>This class will simply list the matches,</p>
<p><code>class ListFixtures(webapp.RequestHandler):<br />
  def get(self):<br />
    self.response.out.write('List fixtures')<br />
#<br />
    fixtures = db.GqlQuery("SELECT * FROM Fixture ORDER BY home ASC LIMIT 10")<br />
#<br />
    for fixture in fixtures:<br />
      if fixture.status:<br />
        self.response.out.write('<b>%s ' % fixture.home )<br />
        self.response.out.write('%s-' % fixture.hscore )<br />
        self.response.out.write('%s ' % fixture.ascore )<br />
        self.response.out.write('%s ' % fixture.away )<br />
        self.response.out.write('</b><br />' )<br />
      else:<br />
        self.response.out.write('<b>%s v </b><br />' % fixture.home)<br />
#<br />
    self.response.out.write("""<br />
      """)<br />
</code></p>
<p>This class lists the fixtures as XML.</p>
<p><code>class ListFixturesXML(webapp.RequestHandler):<br />
  def get(self):<br />
    self.response.out.write('')<br />
#<br />
    fixtures = db.GqlQuery("SELECT * FROM Fixture ORDER BY league, home ASC LIMIT 10")<br />
#<br />
    for fixture in fixtures:<br />
      self.response.out.write('%s' % fixture.league )<br />
      self.response.out.write('')<br />
      self.response.out.write('%s' % fixture.home )<br />
      self.response.out.write('%s' % fixture.hscore )<br />
      self.response.out.write('%s' % fixture.ascore )<br />
      self.response.out.write('%s' % fixture.away )<br />
      self.response.out.write('')<br />
</code></p>
<p>Finally a section that defines which page urls are associated with which procedure. If the address localhost:8080/xml is used, the ListFixturesXML routine will be called.</p>
<p><code>application = webapp.WSGIApplication(<br />
                                     [('/', MainPage),<br />
                                      ('/sign', AddFixture),<br />
                                      ('/xml', ListFixturesXML),<br />
			  ('/list', ListFixtures)],<br />
                                     debug=True)<br />
def main():<br />
  run_wsgi_app(application)<br />
if __name__ == "__main__":<br />
  main()<br />
</code></p>
<p>All relatively painless, once you get the overall idea of the layout. It becomes more complex as the operations require more processing,  further classes and interaction, which is where having a framework like Django will bring benefits. I shall take the time to look more into Django, as the value of running this type of service on the cloud are that it is largely free for moderate usage and free of the overheads of setting up any hardware and web server software. Javascript could have been used in the same way; I just wanted to have a look at python, as I may need it in other systems.</p>
</div>]]></content:encoded>
</item>

</channel>
</rss>
