tags:

views:

93

answers:

2

Hi

I learning Python (coming from a dotnet background) and developing an app which interacts with a webservice.

The web service is flat, in that it has numerous calls some of which are related to sessions e.g. logging on etc, whereas other calls are related to retrieving/setting business data.

To accompany the webservice, there are a couple of python classes which wrap all the calls. I am looking to develop a client on top of that class but give the client more OO structure.

The design of my own app was to have a Session-type class which would be responsible for logging on/maintaining the connection etc , but itself would be injected into a Business-type class which is responsible for making all the business calls.

So the stack is something like

WebService          (Soap)   
 WebServiceWrapper  (Python)
  Session           (Python)
   Business         (Python)

Here's a sample of my code (I've renamed some methods to try and make stuff more explicit)

from webServiceWrapper import webServiceAPI

class Session():
    def __init__(self, user, password):
        self._api = webServiceAPI()
        self.login = self._api.login(user, password) 

    def webServiceCalls(self):
        return self._api()

class Business():
    def __init__(self, service):
        self._service=service

    def getBusinessData(self):
        return self._service.get_business_data()

and my unit test

class exchange(unittest.TestCase):
    def setUp(self):
        self.service = Session("username","password")
        self._business = Business(self.service.webServiceCalls())

    def testBusinessReturnsData(self):
        self.assertFalse(self._business.getBusinessData()==None)

The unit test fails fails on

return self._api() 

saying that the underlying class is not callable

TypeError: 'webServiceAPI' is not callable

My first q is, is that the python way? Is the OO thinking which underpins app development with static languages good for dynamic as well? (That's probably quite a big q!)

My second q is that, if this kind of architecture is ok, what am I doing wrong (I guess in terms of passing references to objects in this way)?

Many thx

S

+1  A: 

I don't see anything that is wrong or un-Pythonic here. Pythonistas often point out the differences to static languages like Java or C#, but many real-world application mostly use a simple static class design in Python, too.

I guess that webServiceAPI is not a class, thus it can't be called.

If you are using Python 2.x, always inherit from the object type, otherwise you'll get a “classic class” (a relict from ancient times that is kept for background compatibility).

Philipp
@Philipp ... many thx for these comments. I think I'm reasonably secure in the static class design area! However, determining where this kind of design choice (and the various design patterns which accompany it) should be superceded using dynamic and/or functional techniques is where I'm very wobbly!
Simon Woods
I have only seen a tiny fraction of your class design and can't judge from that whether the design is too static or not. I think you should keep in mind that static designs are not wrong by itself, only in some cases less than optimal.The only advice I can give ATM is not to use getters and setters: all member variables are public in Python, so Java-style encapsulation doesn't work and is superfluous.
Philipp
Thx again Philipp
Simon Woods
+3  A: 

If WebserviceAPI is an object just remove the parentheses like that:

return self._api 

You already created an instance of the object in the constructor.

Maybe add the definition of WebserviceAPI to the question, I can only guess at the moment.

Fabian
@Fabian. That was it. Thx very much.
Simon Woods
One additional thing, I don't know what WebserviceAPI does, but it does not sound like you need an instance of it for every session (that is what you're doing now).
Fabian
Well, the WebServiceAPI.Logon returns a token, which I do need to use in all subsequent calls to the webservice. Also the WebServiceAPI wraps the (what I am calling) business calls of the soap webservice. So, ISTM, that either I need to re-instantiate the WebServiceAPI in My Business class (passing around the token I got when I logged on) or else I pass a reference to the previously instantiated WebServiceAPI. I'd opted to pass around the instance. Dunno if that is correct or not. Pls feel free to offer a better design.
Simon Woods