Package: simpleapi
Version:0.0.9Author:Florian Schlachter (http://www.fs-tools.de)license:MIT-license / see LICENSE file for morewebsite:http://simpleapi.florian-schlachter.demailinglist:subscribe:simpleapi@librelist.comAn almost complete documentation is still work in progress and will be published athttp://simpleapi.florian-schlachter.desoon.Aboutsimpleapi is aneasy to use, consistent, transparent and portableway of
providing an API. It supportsseveral transport formats(e. g. json, jsonp,
xml, yaml) and providesserver(standalone and also django, Flask, Google AppEngine and any WSGI-compatible implementation like gunicorn) andclient libraries(PHP, Python) to interact seamlessly. You can also use nearly everyAjax framework(e. g. jQuery, ExtJS, etc.) to access the API.server support fordjango,FlaskandGoogle AppEngineclient support forpython,phpandjavascriptdynamic key authentication / ip restrictiontype-conversion / constraintsobject serialization of django model instances, django queryset instances,
mongoengine documents, mongoengine queryset instancesinheritance / multiple versions of one APIseveral encoding/decoding formats (json, jsonp, xml, yaml, etc.)several result formats (ie. for ExtJS forms, etc.)features: caching, throttlingdebugging and profiling capabilitiesexamplesInstallationpip install --upgrade simpleapiFrom GitHubgit clone git://github.com/flosch/simpleapi.gitDependenciesserver: django >= 1.1.1, Flask >= 0.1 or Google AppEnginePython 2.5 or greatersimplejson (if you’re using Python <= 2.5)python-dateutilpyyaml (optional, for YAML-support)sphinx (optional, for the docs)(see requirements.txt as well)ExamplesSMS-SystemServer (handler.py):from simpleapi import Namespace, serialize
from models import SMS, APIUser

class SMSAPI(Namespace):
    __authentication__ = lambda namespace, access_key: \
        APIUser.objects.filter(access_key=access_key).count() > 0

    def send(self, to, msg, from='testsender'):
        sms = SMS.objects.create(
            to=to
            msg=msg,
            from=from
        )
        return {
            'sent': sms.send(),
            'obj': serialize(sms, excludes=[re.compile('^date'),])
        }
    send.published = True
    send.constraints = {'to': re.compile(r'^\+\d{2,}\ \d{3,}\ \d{5,}')}

    def status(self, id):
        return SMS.objects.get(id=id)
    status.published = True
    status.constraints = {'id': int}

    def last(self, numbers=5):
        return SMS.objects.all()[:numbers]
    last.published = True
    last.constraints = {'numbers': int}Standalone-Server(app.py):from simpleapi import Route
from handlers import SMSAPI

route = Route(SMSAPI, framework='standalone', path=r'^/api/')
route.serve() # serves on port 5050 by defaultGunicorn (WSGI-compatible implementation) (app.py):from simpleapi import Route
from handlers import SMSAPI

route = Route(SMSAPI, framework='wsgi', path=r'^/api/')

# start Gunicorn (with 5 workers):
# gunicorn -w 5 app:routeDjango-Server(urls.py):from handlers import SMSAPI
urlpatterns = patterns('',
    (r'^api/$', Route(SMSAPI))
)Flask-Server(app.py):from flask import Flask
from simpleapi import Route
from handlers import SMSAPI

app = Flask(__name__)
app.route('/api/')(Route(SMSAPI, framework='flask'))

if __name__ == '__main__':
    app.run()Google AppEngine(main.py):from google.appengine.ext import webapp
from google.appengine.ext.webapp import util

from simpleapi import Route
from handlers import SMSAPI

def main():
    application = webapp.WSGIApplication(
        [('/api/', Route(SMSAPI, framework='appengine'))]
    )
    util.run_wsgi_app(application)

if __name__ == '__main__':
    main()Client (python/remote):from simpleapi import Client

client = Client(ns='http://remote.tld:8888/api/', access_key='mysecret',
                transport_type='xml')

sms = client.sms(to='555123', msg='Hey yo! This is simpleapi calling.')
print "Sent successful?", sms['sent']

sms = client.sms(to='555123', msg='2nd test with own sender',
                 sender='simpleapi')
print "Sent successful?", sms['sent']
print "Which sender?", sms['obj']['sender']Client (python/local):from simpleapi import DummyClient, Route
from handlers import SMSAPI

client = DummyClient(Route(SMSAPI, framework='dummy'),
                     access_key='mysecret')

sms = client.sms(to='555123', msg='Hey yo! This is simpleapi calling.')
print "Sent successful?", sms['sent']

sms = client.sms(to='555123', msg='2nd test with own sender',
                 sender='simpleapi')
print "Sent successful?", sms['sent']
print "Which sender?", sms['obj']['sender']Client (PHP):require_once("class.client.php");

$client = new Client($ns="http://localhost:8888/api/",
                     $access_key='mysecret');
print("Sent? ".$client->sms(array(
    'to' => '555123',
    'msg' => 'Hey yo! This is the PHP client sending you a SMS.'
))->{'sent'});Client (jQuery):jQuery.get(
    "/api/",
    {_call: 'send', to: '555123', 'msg': 'Hey ya!'},
    function (return) {
        if (return.result.sent)
            alert('Sent successfully!');
        else
            alert('Sending failed!');
    }
)CalculatorServer (handler.py):from simpleapi import Namespace

class CalculatorAPI(Namespace):
    __ip_restriction__ = ['127.0.0.*',]
    __authentication__ = "lets_calc"

    def power(self, a, b):
        return a ** b
    power.published = True
    power.constraints = lambda namespace, key, value: float(value)

    def sum(self, **kwargs)
        return sum(kwargs.values())
    sum.published = True
    sum.constraints = lambda namespace, key, value: float(value)Standalone-Server(app.py):from simpleapi import Route
from handlers import CalculatorAPI

route = Route(CalculatorAPI, framework='standalone', path=r'^/api/')
route.serve() # serves on port 5050 by defaultGunicorn (WSGI-compatible implementation) (app.py):from simpleapi import Route
from handlers import CalculatorAPI

route = Route(CalculatorAPI, framework='wsgi', path=r'^/api/')

# start Gunicorn (with 5 workers):
# gunicorn -w 5 app:routeDjango-Server(urls.py):from handlers import CalculatorAPI
urlpatterns = patterns('',
    (r'^api/$', Route(CalculatorAPI))
)Flask-Server(app.py):from flask import Flask
from simpleapi import Route
from handlers import CalculatorAPI

app = Flask(__name__)
app.route('/api/')(Route(CalculatorAPI, framework='flask'))

if __name__ == '__main__':
    app.run()Google AppEngine(main.py):from google.appengine.ext import webapp
from google.appengine.ext.webapp import util

from simpleapi import Route
from handlers import CalculatorAPI

def main():
    application = webapp.WSGIApplication(
        [('/api/', Route(CalculatorAPI, framework='appengine'))]
    )
    util.run_wsgi_app(application)

if __name__ == '__main__':
    main()Client (python/remote):from simpleapi import Client

client = Client(ns='http://remote.tld:8888/api/', access_key='lets_calc')

print "5 ** 8 =", client.power(a=5, b=8)
print "1+2+3+4+5+6+7 =", client.sum(a=1, b=2, c=3, d=4, e=5, f=6, g=7)Client (python/local):from simpleapi import DummyClient, Route
from handlers import CalculatorAPI

client = DummyClient(Route(CalculatorAPI, framework='dummy'),
                     access_key='lets_calc')

print "5 ** 8 =", client.power(a=5, b=8)
print "1+2+3+4+5+6+7 =", client.sum(a=1, b=2, c=3, d=4, e=5, f=6, g=7)Client (PHP):require_once("class.client.php");

$client = new Client($ns="http://localhost:8888/api/",
                     $access_key='lets_calc');
print("5 ** 8 = ".$client->power(array('a'=>5, 'b'=>8)));Client (jQuery):jQuery.get(
    "/api/",
    {_call: 'power', a: 5, b: 8, _access_key: "lets_calc"},
    function (return) {
        alert('5 ** 8 = ' + return.result)
    }
)