Entries Tagged 'pyphanfare' ↓
April 27th, 2008 — development, pyphanfare, python
Wikipedia defines Duck Typing as:
In computer programming, duck typing is a style of dynamic typing in which an object’s current set of methods and properties determines the valid semantics, rather than its inheritance from a particular class. The name of the concept refers to the duck test, attributed to James Whitcomb Riley, which may be phrased as follows:
“If it walks like a duck and quacks like a duck, I would call it a duck.”
Coming from a strong background in C#, it took awhile for this feature of Python to seem useful. I was use to creating interfaces and creating a proper inheritance chain implementing these interfaces and/or defining abstract base classes, all to have a good set of mock objects to use in unit tests.
I really love the ability to quickly whip out a duck typed class in Python to make simple mock objects so that I am testing my code in a unit test and not boundary objects (e.g. urllib). I don’t need to test whether my request is properly handled by the server at the urllib endpoint and that the response is properly read and processed. I need to instead make sure that my request conforms to a published specification and that the expected result/response from the server is processed properly. This also allows my tests to run offline.
Here is an example of some mock objects that I use in pyphanfare:
# pyphanfare/tests/mocks.py
from pyphanfare.tests.testdata import data
class URLopener:
def open(self, url):
params = url.split('?')[1].split('&')
for param in params:
tokens = param.split('=')
if tokens[0].strip() == 'method':
return URLhandle(tokens[1].strip())
def addheader(self, *args):
self.headers = args
class URLhandle:
def __init__(self, method):
self.method = method
def read(self):
return data[self.method]
pyphanfare.tests.testdata is just a Python module that contains test data in the form of a dictionary object indexed by method name that I am calling on the API having a value of XML that is expected in the response.
April 27th, 2008 — development, pyphanfare, python
Phanfare has decided to implement authenticated requests in a way that feels a bit clunky in design and a bit tricky to figure out how to get working as it isn’t well documented.
On the initial Authenticate request call, they send back a cookie string in XML that you are supposed to use in sending an HTTP Header, Cookie, with each subsequent request.
Cookie: phanfare2=COOKIE_STRING; domain=.phanfare.com
Being a Python library, pyphanfare uses urllib’s URLopener utility class for the HTTP calls. In order to send a cookie with a URLopener originated request you’ll want to do the following:
cookie_str = 'phanfare2=COOKIE_STRING; domain=.phanfare.com'
opener = URLopener()
opener.addheader('Cookie', cookie_str)
xml_str = opener.open(URL).read()
April 23rd, 2008 — development, pyphanfare, python
This past weekend I found myself getting a bit frustrated in working on pyphanfare in that as I was referencing the documentation for the the API, I clicked on a link at the bottom of the page that said “API” and got a different document describing a slightly different API with a completely different authentication scheme.
Phanfare API 1.0
Phanfare API 2.0
Comparing the two API documents, I could not distinguish whether or not they were in fact two distinct different API versions, or if one was obsolete and if so, which one. After posting some messages on the forums and sending a few emails, I got a response informing me that there are two distinct different API versions.
Also the text on the 1.0 API was updated to make it clearer — great response time to updating the documentation:
When Phanfare released it’s overhaul, Phanfare 2.0, it also was accompanied with a different API. The accounts that have been upgraded need to use the new API, the sites that haven’t been updated must use the old API. That being said, the API for 1.0 will be shutdown in June 2008, so I assume that 1.0 accounts will be upgraded then as well.
So, it looks like I need to take a step back on pyphanfare and reexamine my approach. I will ditch the effort to support the 1.0 API and focus on getting the 2.0 version out and usable.