开发者

String error in my python api wrapper class

开发者 https://www.devze.com 2023-01-22 21:00 出处:网络
I\'m writing an API wrapper to a couple of different web services. I have a method that has an article url, and I want to extract text from it using alchemyapi.

I'm writing an API wrapper to a couple of different web services.

I have a method that has an article url, and I want to extract text from it using alchemyapi.

def extractText(self):
    #All Extract Text Methods ---------------------------------------------------------//
    #Extract page text from a web URL (ignoring navigation links, ads, etc.).
    if self.alchemyapi == True:
        self.full_text = self.alchemyObj.URLGetText(self.article_link)

which goes to the following code in the python wrapper

def URLGetText(self, url, t开发者_开发百科extParams=None):
    self.CheckURL(url)
    if textParams == None:
      textParams = AlchemyAPI_TextParams()
    textParams.setUrl(url)
    return self.GetRequest("URLGetText", "url", textParams)

def GetRequest(self, apiCall, apiPrefix, paramObject):
    endpoint = 'http://' + self._hostPrefix + '.alchemyapi.com/calls/' + apiPrefix + '/' + apiCall
    endpoint += '?apikey=' + self._apiKey + paramObject.getParameterString()
    handle = urllib.urlopen(endpoint)
    result = handle.read()
    handle.close()
    xpathQuery = '/results/status'
    nodes = etree.fromstring(result).xpath(xpathQuery)
    if nodes[0].text != "OK":
      raise 'Error making API call.'
    return result

However I get this error ---

  Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "text_proc.py", line 97, in __init__
    self.alchemyObj.loadAPIKey("api_key.txt");    
  File "text_proc.py", line 115, in extractText
    if self.alchemyapi == True:
  File "/Users/Diesel/Desktop/AlchemyAPI.py", line 502, in URLGetText
    return self.GetRequest("URLGetText", "url", textParams)
  File "/Users/Diesel/Desktop/AlchemyAPI.py", line 618, in GetRequest
    raise 'Error making API call.'

I know I'm somehow passing the url string to the api wrapper in a faulty format, but I can't figure out how to fix it.


The information provided is not actually very helpful to diagnose or solve the problem. Have you considered taking a look at the response from the server? You might inspect a complete traffic log using Fiddler.

Additionally, the SDK provided by Alchemy doesn't seem to be of - cough, cough - the greatest quality. Since it really consists only of around 600 lines of source code, I'd consider writing a shorter, more robust / pythonic / whatever SDK.

I might also add that right now, even the on-site demo at the Alchemy web site is failing, so maybe your problem is related to that. I really suggest taking a look at the traffic.


You should raise Exception or a subclass thereof, instead of a string.


You're getting the error because your function GetRequest() raising a string as an exception:

if nodes[0].text != "OK":
  raise 'Error making API call.'

If that's not what you want, you have two options:

  1. You can have the function return the string or None, or
  2. You can pass the error message to a real subclass of Exception (as suggested by knutin)

In either case, if you are assigning that return value to a variable, you can handle it accordingly. Here is an example:

Option 1 Let's assume you decide to have GetRequest() return None:

def URLGetText(self, url, textParams=None):
    self.CheckURL(url)
    if textParams == None:
        textParams = AlchemyAPI_TextParams()
    textParams.setUrl(url)

    # Capture the value of GetRequest() before returning it
    retval = self.GetRequest("URLGetText", "url", textParams)
    if retval is None:
        print 'Error making API call.' # print the error but still return 

    return retval 

def GetRequest(self, apiCall, apiPrefix, paramObject):
    # ...
    if nodes[0].text != "OK":
      return None
    return result

This option is a little ambiguous. How do you know that it was really an error, or the return value truly was None?

Option 2 This is probably the better way to do it:

First create an subclass of Exception:

class GetRequestError(Exception):
    """Error returned from GetRequest()"""
    pass

Then raise it in GetRequest()`:

def URLGetText(self, url, textParams=None):
    self.CheckURL(url)
    if textParams == None:
      textParams = AlchemyAPI_TextParams()
    textParams.setUrl(url)

    # Attempt to get a legit return value & handle errors
    try:
        retval = self.GetRequest(apiCall, apiPrefix, paramObject)
    except GetRequestError as err:
        print err # prints 'Error making API call.'
        # handle the error here
        retval = None

    return retval

def GetRequest(self, apiCall, apiPrefix, paramObject):
    # ...
    if nodes[0].text != "OK":
      raise GetRequestError('Error making API call.')
    return result

This way you're raising a legitimate error when GetRequest() doesn't return the desired result, and then you can handle the error using a try..except block and optionally print the error, stop the program there, or keep going (which is what I think you want to do based on your question).


This is Shaun from AlchemyAPI. We just posted a new version of the python SDK that raises exceptions properly. You can get it here http://www.alchemyapi.com/tools/.

If you have any other feedback about the SDK, please message me. Thanks for using our NLP service.

0

精彩评论

暂无评论...
验证码 换一张
取 消