SleepyMongoose meets the Python after dark

 

For a while now I have been looking for a reasonable

REST-based NoSQL Database I can use from the Google App Engine just to avoid
having to pay Google for their database fees.

Earlier today… I was able to make the SleepyMongoose
snuggle-up with the Python for some after-hours fun in the dark.

SleepyMongoose

You can read-up about SleepyMongoose here.

It’s a REST-based interface for MongoDB that runs as a lightweight Python HTTP
Server – I will eventually get around to making this SleepyMongoose wake-up by
shoving some Stackless Python into it just for fun and because Stackless always
makes Python work better.

So what does the SleepyMongoose need once I get around to
using it from the Google App Engine ?

SleepyMongoose needs a slick Python wrapper so I don’t gotta
deal with all that REST stuff which after-all the REST interface is only needed
because Google doesn’t seem to care much about bandwidth consumption for
anything other than their own database and it just makes sense to make Google
give me a FREE No-Cost MongoDb Proxy which is what this is all leading to
anyway.

SleepyMongoose meets the Python

 So, since I am a pretty good Python coder I chose to whip-up

a Magic little object that allows me to get away from REST and right into
Python objects.

I implemented the SleepyMongoose API as documented in their Wiki.

Keep in mind the code presented here requires the Vyper
Logix Library as found here (shameless
plug, of course
).

Here’s a sample of what the usage looks like:

from vyperlogix import
mongodb

 

if (__name__ == ‘__main__’):

    import os,sys

   

    sm = mongodb.SleepyMongoose(‘127.0.0.1:27080’).db(‘gps_1M’).collection(‘num_connections’)

    results = sm.connect()

    print ‘sm.connect() #1
–> ‘
,results

 

    results = sm.server(‘mongodb://127.0.0.1:65535’).connect()

    print ‘sm.connect() #2
–> ‘
,results

 

    results = sm.server(‘mongodb://127.0.0.1:65535’).name(‘backup’).connect()

    print ‘sm.connect() #3
–> ‘
,results

 

    results = sm.docs({“x”:2}).insert()

    print ‘sm.insert() #1
–> ‘
,results

 

    results = sm.find({“x”:2})

    print ‘sm.find() #1 –>
,results

 

    results = sm.criteria({“x”:2}).remove()

    print ‘sm.remove() #1
–> ‘
,results

 

    results = sm.docs().insert({“x”:3})

    print ‘sm.insert() #1
–> ‘
,results

 

    results = sm.find({“x”:3})

    print ‘sm.find() #2 –>
,results

 

    results = sm.remove({“x”:3})

    print ‘sm.remove() #2
–> ‘
,results

 

    results = sm.docs([{“x”:2},{“x”:3}]).insert()

    print ‘sm.insert() #3
–> ‘
,results

 

    results = sm.criteria({“x”:2}).remove()

    print ‘sm.remove() #3
–> ‘
,results

 

    results = sm.criteria([{“x”:3}]).remove()

    print ‘sm.remove() #4
–> ‘
,results

 

    results = sm.insert([{“x”:2},{“x”:3}])

    print ‘sm.insert() #4
–> ‘
,results

 

    results = sm.remove({“x”:2})

    print ‘sm.remove() #5
–> ‘
,results

 

    results = sm.remove([{“x”:3}])

    print ‘sm.remove() #6
–> ‘
,results

    pass

Here’s the rest of the code:  (Simple and to the point, no nonsense code,
in a few hours…)

__copyright__ = “””\

(c). Copyright 2008-2011,
Vyper Logix Corp., All Rights Reserved.

 

Published under Creative
Commons License

(http://creativecommons.org/licenses/by-nc/3.0/)

restricted to
non-commercial educational use only.,

 

http://www.VyperLogix.com
for details

 

THE AUTHOR VYPER LOGIX
CORP DISCLAIMS ALL WARRANTIES WITH REGARD TO

THIS SOFTWARE, INCLUDING
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND

FITNESS, IN NO EVENT SHALL
THE AUTHOR BE LIABLE FOR ANY SPECIAL,

INDIRECT OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING

FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT,

NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION

WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE !

 

USE AT YOUR OWN RISK.

“””

import logging

 

import urllib2

 

import simplejson

 

from vyperlogix import
misc

from vyperlogix.misc import _utils

from vyperlogix.classes import MagicObject

 

arg0 = lambda args:args[0] if (misc.isIterable(args)) and (len(args) > 0) and (misc.isString(args[0])) else None

list0 = lambda args:args[0] if (misc.isIterable(args)) and (len(args) > 0) and ( (misc.isList(args[0])) or (misc.isDict(args[0])) ) else []

int0 = lambda args:args[0] if (misc.isIterable(args)) and (len(args) > 0) and (misc.isInteger(args[0])) else None

bool0 = lambda args:args[0] if (misc.isIterable(args)) and (len(args) > 0) and (misc.isBooleanString(args[0])) else None

 

__only__ = lambda value,target:value if (str(value).lower().capitalize() == str(target).lower().capitalize()) else None

 

class SleepyMongoose(MagicObject.MagicObject2):

    def __init__(self,sleepy_mongoose):

        ”’

        See
also: https://github.com/kchodorow/sleepy.mongoose/wiki/

        ”’

        toks = sleepy_mongoose.split(‘:’)

        try:

            self.__sleepy_mongoose__ =
sleepy_mongoose if (misc.isString(toks[0]) and misc.isInteger(int(toks[-1]))) else None

        except:

            self.__sleepy_mongoose__ =
None

        self.__database__ = None

        self.__collection__ = None

        self.__server__ = None

        self.__server_name__ = None

        self.__last_exception__ =
None

        self.__n__ = None

        self.__docs__ = None

        self.__criteria__ = None

        self.__newobj__ = None

        self.__fields__ = None

        self.__sort__ = None

        self.__skip__ = None

        self.__limit__ = None

        self.__explain__ = None

        self.__batch_size__ = None

        self.__id__ = None

       

    def __http_get__(self,url):

        data = None

        try:

            response = urllib2.urlopen(url)

            json = response.read()

            data = simplejson.loads(json)

        except Exception, ex:

            self.__last_exception__ =
_utils.formattedException(details=ex)

            data = None

        return data

 

    def __http_post__(self,url,parms=()):

        from vyperlogix.url._urllib2 import
http_post

        data = None

        try:

            json = http_post(url,parms)

            data = simplejson.loads(json)

        except Exception, ex:

            self.__last_exception__ =
_utils.formattedException(details=ex)

            data = None

        return data

 

    def __handle_exceptions__(self):

        if (not self.__sleepy_mongoose__):

            logging.error(‘ERROR: Cannot understand “SleepyMongoose(%s)”‘
% (self.__sleepy_mongoose__))

        elif (not self.__database__):

            logging.error(‘ERROR: Cannot understand “db(%s)”‘ % (self.__database__))

        elif (not self.__collection__):

            logging.error(‘ERROR: Cannot understand “collection(%s)”‘
% (self.__collection__))

   

    def __getattr__(self,name):

        self.__n__ = name

        return super(SleepyMongoose, self).__getattr__(name)

 

    def __call__(self,*args,**kwargs):

        if (self.__n__ == ‘db’):

            self.__database__ = arg0(args)

            self.__reset_magic__()

        elif (self.__n__ == ‘collection’):

            self.__collection__ =
arg0(args)

            self.__reset_magic__()

        elif (self.__n__ == ‘server’):

            self.__server__ = arg0(args)

            self.__reset_magic__()

        elif (self.__n__ == ‘name’):

            self.__server_name__ =
arg0(args)

            self.__reset_magic__()

        elif (self.__n__ == ‘docs’):

            self.__docs__ = list0(args)

            self.__reset_magic__()

        elif (self.__n__ == ‘criteria’):

            self.__criteria__ = list0(args)

            self.__reset_magic__()

        elif (self.__n__ == ‘fields’):

            self.__fields__ = list0(args)

            self.__reset_magic__()

        elif (self.__n__ == ‘sort’):

            self.__sort__ = list0(args)

            self.__reset_magic__()

        elif (self.__n__ == ‘skip’):

            self.__skip__ = int0(args)

            self.__reset_magic__()

        elif (self.__n__ == ‘limit’):

            self.__limit__ = int0(args)

            self.__reset_magic__()

        elif (self.__n__ == ‘batch_size’):

            self.__batch_size__ =
int0(args)

            self.__reset_magic__()

        elif (self.__id__ == ‘id’):

            self.__id__ = int0(args)

            self.__reset_magic__()

        elif (self.__n__ == ‘explain’):

            self.__explain__ =
__only__(bool0(args),‘True’)

            self.__reset_magic__()

        elif (self.__n__ == ‘newobj’):

            self.__newobj__ = list0(args)

            self.__reset_magic__()

        elif (self.__n__ == ‘find’):

            if (self.__sleepy_mongoose__)
and (self.__database__) and (self.__collection__):

                p = []

                if (self.__criteria__):

                    p.append(tuple([“criteria”,simplejson.dumps(self.__criteria__)]))

                    self.__criteria__ = None

                if (self.__fields__):

                    p.append(tuple([“fields”,simplejson.dumps(self.__fields__)]))

                    self.__fields__ = None

                if (self.__sort__):

                    p.append(tuple([“sort”,simplejson.dumps(self.__sort__)]))

                    self.__sort__ = None

                if (self.__skip__):

                    p.append(tuple([“skip”,‘%d’%(self.__skip__)]))

                    self.__skip__ = None

                if (self.__limit__):

                    p.append(tuple([“limit”,‘%d’%(self.__limit__)]))

                    self.__limit__ = None

                if (self.__explain__):

                    p.append(tuple([“explain”,‘%s’%(self.__explain__)]))

                    self.__explain__ = None

                if (self.__batch_size__):

                    p.append(tuple([“batch_size”,‘%d’%(self.__batch_size__)]))

                    self.__batch_size__ = None

                if (self.__server_name__):

                    p.append(tuple([“name”,self.__server_name__]))

                url = http://%s/%s/%s/_%s’
% (self.__sleepy_mongoose__,self.__database__,self.__collection__,self.__n__)

                return self.__http_post__(url,tuple(p))

            else:

                self.__handle_exceptions__()

            self.__reset_magic__()

        elif (self.__n__ == ‘insert’):

            if (self.__sleepy_mongoose__)
and (self.__database__) and (self.__collection__):

                p = []

                if (self.__docs__):

                    p.append(tuple([“docs”,simplejson.dumps(self.__docs__)]))

                    self.__docs__ = None

                else:

                    p.append(tuple([“docs”,simplejson.dumps(list0(args))]))

                    self.__docs__ = None

                if (self.__server_name__):

                    p.append(tuple([“name”,self.__server_name__]))

                url = http://%s/%s/%s/_%s’
% (self.__sleepy_mongoose__,self.__database__,self.__collection__,self.__n__)

                return self.__http_post__(url,tuple(p))

            else:

                self.__handle_exceptions__()

            self.__reset_magic__()

        elif (self.__n__ == ‘update’):

            if (self.__sleepy_mongoose__)
and (self.__database__) and (self.__collection__):

                p = []

                if (self.__criteria__):

                    p.append(tuple([“criteria”,simplejson.dumps(self.__criteria__)]))

                    self.__criteria__ = None

                if (self.__newobj__):

                    p.append(tuple([“newobj”,simplejson.dumps(self.__newobj__)]))

                    self.__newobj__ = None

                if (self.__server_name__):

                    p.append(tuple([“name”,self.__server_name__]))

                url = http://%s/%s/%s/_%s’
% (self.__sleepy_mongoose__,self.__database__,self.__collection__,self.__n__)

                return self.__http_post__(url,tuple(p))

            else:

                self.__handle_exceptions__()

            self.__reset_magic__()

        elif (self.__n__ == ‘more’):

            if (self.__sleepy_mongoose__)
and (self.__database__) and (self.__collection__):

                p = []

                if (self.__id__):

                    p.append(tuple([“id”,‘%d’%(self.__id__)]))

                    self.__id__ = None

                if (self.__batch_size__):

                    p.append(tuple([“batch_size”,‘%d’%(self.__batch_size__)]))

                    self.__batch_size__ = None

                if (self.__server_name__):

                    p.append(tuple([“name”,self.__server_name__]))

                q = ‘?’+‘&’.join([‘=’.join(list(t)) for t in p]) if (len(p) > 0) else

                url = http://%s/%s/%s/_%s%s’
% (self.__sleepy_mongoose__,self.__database__,self.__collection__,self.__n__,q)

                return self.__http_get__(url)

            else:

                self.__handle_exceptions__()

            self.__reset_magic__()

        elif (self.__n__ == ‘cmd’):

            if (self.__sleepy_mongoose__)
and (self.__database__):

                p = []

                _c_ = list0(args)

                if (_c_):

                    p.append(tuple([“cmd”,simplejson.dumps(_c_)]))

                url = http://%s/%s/_%s’ % (self.__sleepy_mongoose__,self.__database__,self.__n__)

                return self.__http_post__(url,tuple(p))

            else:

                self.__handle_exceptions__()

            self.__reset_magic__()

        elif (self.__n__ == ‘remove’):

            if (self.__sleepy_mongoose__)
and (self.__database__) and (self.__collection__):

                p = []

                if (self.__criteria____):

                    p.append(tuple([“criteria”,simplejson.dumps(self.__criteria____)]))

                    self.__criteria____ = None

                else:

                    p.append(tuple([“criteria”,simplejson.dumps(list0(args))]))

                    self.__criteria____ = None

                if (self.__server_name__):

                    p.append(tuple([“name”,self.__server_name__]))

                url = http://%s/%s/%s/_%s’
% (self.__sleepy_mongoose__,self.__database__,self.__collection__,self.__n__)

                return self.__http_post__(url,tuple(p))

            else:

                self.__handle_exceptions__()

            self.__reset_magic__()

        elif (self.__n__ == ‘connect’):

            _token = self.__n__

            if (self.__sleepy_mongoose__):

                p = []

                if (self.__server__):

                    p.append(tuple([“server”,self.__server__]))

                if (self.__server_name__):

                    p.append(tuple([“name”,self.__server_name__]))

                url = http://%s/_%s’ % (self.__sleepy_mongoose__,_token)

                return self.__http_post__(url,tuple(p))

            else:

                self.__handle_exceptions__()

            self.__reset_magic__()

        else:

            logging.debug(‘DEBUG: Cannot understand “%s(%s,%s)”‘ % (self.n,args,kwargs))

        return self

 

 

Advertisements
%d bloggers like this: