Login

django soaplib test client

Author:
erny
Posted:
March 30, 2009
Language:
Python
Version:
1.0
Score:
0 (after 0 ratings)

This code monkey patches soaplib client to allow the usage of django test client for local web service testing (without a running server). It adds basic authentication.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
import base64
import httplib
from soaplib import client
from django.test.client import Client as DjangoTestClient


def Client(url, impl, username=None, password=None):
    """ soaplib test client

        url:        protocol://[username:password@]host[:port]/path
        impl:       soaplib web service description
        username:   for basic auth
        password:   for basic auth

        Usage example (with django soaplib webservice snippet)

        The service (app/view.py):
        from soaplib_handler import DjangoSoapApp, soapmethod, soap_types
        class HelloWorldService(DjangoSoapApp):
            __tns__ = 'http://my.namespace.org/soap/

            @soapmethod(soap_types.String, _returns soap_types.String)
            def hello(who):
                return 'Hello %s!'
        hello_world_service = HelloWorldService()        

        Your urls.py:
        urlpatterns = patterns(
            '',
            (r'^hello_world/', 'app.views.hello_world_service'),
            (r'^hello_world/service.wsdl', 'app.views.hello_world_service'),
        )

        Accessing the web service with patched soaplib client        
        >>> from django_soaplib_client import Client
        >>> cl = Client('http://localhost:8000/hello_service/', HelloWorldService())
        >>> cl.hello('buddy')
        Hello buddy!
        >>> cl = Client('http://localhost:8000/hello_service/', HelloWorldService(), 
        ...        'username', 'password') # with authentication
        >>>
    """
    if username:
        protocol, rest = url.split('://')
        url = '%s://%s:%s@%s' % (protocol, username, password or '', rest)
    return client.make_service_client(url, impl)


class FakeHTTPConnection(object):
    """ Replacement to root all requests to Django test client.
        host is something like: [username:password@]host[:port]
        soaplib client may not work with https.
    """

    username = ''
    password = ''

    def __init__(self, host):
        """ Initializer.

            host:port part is ignored
        """
        self._connection = DjangoTestClient()
        self._response = None
        if '@' in host:
            self.username, self.password = host.split('@')[0].split(':')

    def request(self, method, path, body=None, headers=None):
        """ Route request to Django test client.

            method:     GET, POST, etc.
            path:       path part of URL
            body:       text to send to the host
            headers:    headers dict: { header_name: (header, value), ...}
        """
        extra = {}
        if headers:
            for key, value in headers.items():
                key = 'HTTP_' + key.upper().replace('-', '_')
                extra[key] = value
        extra['REQUEST_METHOD'] = method
        if self.username:
            auth = '%s:%s' % (self.username, self.password)
            auth = 'Basic %s' % base64.encodestring(auth)
            auth = auth.strip()
            extra['HTTP_AUTHORIZATION'] = auth
        if body:
            resp = self._connection.post(path, body,
                content_type='dummy', **extra)
        else:
            resp = self._connection.get(path, **extra)
        self._response = resp

    def getresponse(self):
        """ Get reponse from Django. """
        return FakeHTTPResponse(self._response)

    def close(self):
        """ Close request and related response object. """
        if self._response:
            self._response.close()


class FakeHTTPResponse(object):
    """ Replacement to get response from Django test client. """

    def __init__(self, response):
        """ Initializer.

            response: Django HttpResponse object.
        """
        self._response = response
        self.status = response.status_code
        self.reason = httplib.responses[self.status]

    def read(self):
        """ Read response body (from Django test client). """
        return self._response.content

    def getheaders(self):
        """ Get response headers. """
        return self._response._headers.values()

class httplib_replacement:
    """ Replacement for monkey patching httplib.

        Web only need HTTPConnection.
    """
    HTTPConnection = FakeHTTPConnection


# monkey patch httlib in soaplib client with our fake class
client.httplib = httplib_replacement

More like this

  1. Template tag - list punctuation for a list of items by shapiromatron 3 months, 1 week ago
  2. JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 3 months, 2 weeks ago
  3. Serializer factory with Django Rest Framework by julio 10 months, 1 week ago
  4. Image compression before saving the new model / work with JPG, PNG by Schleidens 11 months ago
  5. Help text hyperlinks by sa2812 11 months, 3 weeks ago

Comments

Please login first before commenting.