I’ve run in to this situation a few times and end up having to query my gBrain for the answer. When using json as a transport from python to html/javascript, I frequently end up needing to move date and time data. However, the builtin json module is not happy when you ask it to serialize a date/time object.

>>> json.dumps(datetime.datetime.now())
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.6/json/__init__.py", line 230, in dumps
    return _default_encoder.encode(obj)
  File "/usr/lib/python2.6/json/encoder.py", line 367, in encode
    chunks = list(self.iterencode(o))
  File "/usr/lib/python2.6/json/encoder.py", line 317, in _iterencode
    for chunk in self._iterencode_default(o, markers):
  File "/usr/lib/python2.6/json/encoder.py", line 323, in _iterencode_default
    newobj = self.default(o)
  File "/usr/lib/python2.6/json/encoder.py", line 344, in default
    raise TypeError(repr(o) + " is not JSON serializable")
TypeError: datetime.datetime(2011, 12, 1, 0, 50, 53, 152215) is not JSON serializable

So this means we need to figure out a work around. The trick is to let the json module know what it should do with a date/time object while leaving the rest of it in place. So, no replacing the default handler.

What we need to do is subclass the JSONEncoder and override the default method

class JSONEncoder(json.JSONEncoder):
    def default(self, obj):
        if hasattr(obj, 'isoformat'): #handles both date and datetime objects
            return obj.isoformat()
        else:
            return json.JSONEncoder.default(self, obj)

Using the hasattr and looking for ‘isoformat’ method will allow this to handle both date objects and datetime objects. So all that is left to demonstrate is how to put it together with the json.dumps method.

>>> json.dumps(datetime.datetime.now(), cls=JSONEncoder)
'"2011-12-01T00:58:34.479929"'

Ok, so now you have this ISO formatted string containing date information, how do you get that converted to a javascript date object once it has been transmitted across the abyss and now resides in a javscript callback function?

var d = new Date("2011-12-01T00:58:34.479929");

Happy Data Slinging!

 

So, I’m hacking on a Python for Android project, which is built over top of the SL4A project. I’m currently using the remote method of development where you fire up an interpreter and share it in public mode. Then you import android.py and instantiate an instance of Android with IP and Port information of your public server. You can then hack in your favorite editor on a laptop instead of using a thumb-board or other. It looks like this:

import android  # The SL4A android.py module should be on your sys.path.

ip = '192.168.x.xxxx'
port = 35766
droid = android.Android((ip, port))

What happens is the __getattr__ method of the Android object uses magic to change droid.getenvironment() into an RPC call to the public server and then return the result back as a named tuple. Nice. Being the nosey bugger that I tend to be, I modified the code to add a debug param to the __init__ method, that when set, would print out what was being sent out over RPC and then the raw tuple results. A snippet of the modification goes like this:

  def __getattr__(self, name):
    def rpc_call(*args):
      if self._debug:
          print "droid.%s%s" % (name, str(args))
      res = self._rpc(name, *args)
      if self._debug:
          print "\t%s" % str(res)
      return res
    return rpc_call

You can easily see where I put my “if self._debug” logic in place. Now if I use my modified android.py I can turn on the debug flag and get some 411 on the magic that is going on. It ends up looking like this:

droid.eventWait(3000,)
	Result(id=28, result=None, error=None)
droid.eventWait(3000,)
	Result(id=29, result={u'data': u'@end', u'name': u'dmt:fromClient.speak', u'time': 1322542655069000L}, error=None)
droid.wakeLockRelease()
	Result(id=30, result=None, error=None)
 

While I was playing around with Python for Andoid, I was using the webViewShow method to load an interactive html page and set up message passing both from

html/js -> python

and from

python -> html/js

Part of this requires that I knock out and hack some html/js code. However, I am using the Remote method with a public server on my android device, since I am too lazy to set up eclipse and a full blown android dev env. The example code they show, uses an html file located on the sdcard of the device. Of course this brings its own problems, since now I have to mount, edit, unmount between each hack cycle. Ick. Well I could just tell it to load the html from an off device server, but being lazy ( I think I mentioned that already. ) I didn’t want to rsync back and forth to my remote server, set up directories, etc. Also, I didn’t want to set up a Django install just to serve a hacky html script.

So I think to myself, man there has to be some light-weight way to serve this up locally while I’m hacking. So I think, hey CherryPy, but then I remember Edna and it hits me, I can serve static pages out of a directory with just python. A little google-fu and this page appears, giving just the needed incantation.

 python -m SimpleHTTPServer 8080

Which happily serves everything out of the directories below it on the specified port (8080 in this case). I make a little adjustment in to my webViewShow and change it from file:/// to http://my-dev-ip:8080/thefile.html and all is good with the world. As I hack, changes to the html are pulled and served immediately.

Did I mention, Python Rocks!

 

App Engine is a pretty dramatic thought departure for lots of programmers who are used to writing an app that runs on a single server and access a single database.  Case in point, there has been a recurring topic of auto-increment fields on the  App Engine list — people trying to implement their own version of it since it is not a native datastore type.

Using an auto-increment field is not the way to go.  It is viable when you only have 1 database but the datastore for your app is going to/can be replicated out to other machines.  This would mean that their exists times, when datastore’ != datastore” — over time datastore’ would be sync’d with datastore” so that datastore’ == datastore”   — this would lead one to believe that there will be times when the idea of an auto-increment field will not be synchronizable or that the result of the synchronization would be less than satisfactory.  My belief that auto-increment fields are the wrong idea in this environment is strengthened by the fact that they are not offered as an intrinsic datatype.

The way to go, in my opinion, is to use UUIDs. (see links below)
  http://docs.python.org/lib/module-uuid.html
  http://www.faqs.org/rfcs/rfc4122.html

Other Thoughts on the topic:

  • data access is very expensive, using a UUID should be faster
  • UUID1 or UUID4 would be the types to consider
  • UUID1 is preferable as it would introduce some machine significance which should make the chances for a collision to be even more remote than for a UUID4 (random)
© 2012 In Re: Suffusion theme by Sayontan Sinha
Stop SOPA