Package: webservices.naudit
NOTICE: This is a fork fromhttps://github.com/aldryncore/webserviceswhich is archived. This fork is only intended to keep runninghttps://github.com/Naudit/django-simple-ssoas far as we can.
Feel free to generate MR (We probably accept most of them) but issues will not be fixed unless they are trivial.Build and consume web services (aka APIs) in Python.FeaturesProviders that work with Django, Flask and TwistedEverything is signed (using itsdangerous)Synchronous consumer (framework independant)Asynchronous consumer (powered by Twisted)InstallationDjango (provider/consumer)pip install webservices[django]Flask (provider/consumer)pip install webservices[flask]Twisted (provider/consumer)pip install webservices[twisted]Synchronous consumer onlypip install webservices[consumer]QuickstartWe’ll write an API that greets you with your name (or ‘hello world’ if not name
is provided).ProviderDjangoWe assume you have a settingAPI_KEYSwhich is a dictionary of public keys
mapping to private keys.myapi/urls.py:from django.conf.urls import url, patterns
from webservices.sync import provider_for_django
from myapi.views import HelloProvider

urlpatterns = patterns('',
    url(r'hello/$', provider_for_django(HelloProvider())),
)Yourmyapi/views.py:from django.conf import settings
from webservices.models import Provider

class HelloProvider(Provider):
    def get_private_key(self, public_key):
        return settings.API_KEYS.get(public_key)

    def provide(self, data):
        name = data.get('name', 'world')
        return {'greeting': u'hello %s' % name}Flaskapp.py:from flask import Flask
from webservices.sync import provider_for_flask
from webservices.models import Provider

app = Flask(__name__)

API_KEYS = {
    'publickey': 'privatekey', # your keys here
}

class HelloProvider(Provider):
    def get_private_key(self, public_key):
        return API_KEYS.get(public_key)

    def provide(self, data):
        name = data.get('name', 'world')
        return {'greeting': u'hello %s' % name}

provider_for_flask(app, '/hello/', HelloProvider())Twistedapp.py:from twisted.internet import reactor
from twisted.web.server import Site
from webservices.async import provider_for_twisted
from webservices.models import Provider

API_KEYS = {
    'publickey': 'privatekey', # your keys here
}

class HelloProvider(Provider):
    def get_private_key(self, public_key):
        return API_KEYS.get(public_key)

    def provide(self, data):
        name = data.get('name', 'world')
        return {'greeting': u'hello %s' % name}

resource = provider_for_twisted(HelloProvider())

site = Site(resource)
reactor.listenTCP(80, site)
reactor.run()Noticed how the provider is basically the same for all three (other thanget_private_key)? Neat, right?Handling errorsTo log errors (for example using raven) you can implement thereport_exceptionmethod onProviderclasses.
This method is called whenever theprovidemethod throws an exception. It takes no arguments.ConsumerSynchronousTo consume that code (assuming it’s hosted on ‘https://api.example.org’):from webservices.sync import SyncConsumer

consumer = SyncConsumer('https://api.example.org', 'mypublickey', 'myprivatekey')
result = consumer.consume('/hello/', {'name': 'webservices')
print result # prints 'hello webservices'AsynchronousSame as above, but async:from webservices.async import TwistedConsumer
from twisted.internet import reactor

def callback(result):
    print result # prints 'hello webserivces'
    reactor.stop()

consumer = TwistedConsumer('https://api.example.org', 'mypublickey', 'myprivatekey')
deferred = consumer.consume('/hello/', {'name': 'webservices')
deferred.addCallback(callback)

reactor.run()Data Source NameYou can create consumers from Data Source Names (eg'http://public_key:private_key@api.example.org') using thefrom_dsnclassmethod on consumers.Example:consumer = SyncConsumer.from_dsn(’https://public_key:private_key@api.example.org’)LicenseThis code is licensed under the 3-clause BSD license, see LICENSE.txt.