DomainTools/python_api

403 NotAuthorizedException in code when Account Information endpoint disabled

wesinator opened this issue · 2 comments

I'm getting an unexpected 403 NotAuthorizedException on .whois() running in Python 3.
Installed with pip3 install --user domaintools_api

macOS and Ubuntu

from domaintools import API
import dtconfig

api = API(dtconfig.user, dtconfig.apiKey)
print(api.username, api.key)

#whois = api.whois('google.com')
#print(whois)

parsed_whois = api.parsed_whois("google.com")
print(parsed_whois)

output:

NotAuthorizedException                    Traceback (most recent call last)
<ipython-input-33-2391f6a41ef5> in <module>
      9 #print(whois)
     10 
---> 11 parsed_whois = api.parsed_whois("google.com")
     12 print(parsed_whois)

/usr/local/lib/python3.7/site-packages/domaintools/api.py in parsed_whois(self, query, **kwargs)
    125     def parsed_whois(self, query, **kwargs):
    126         """Pass in a domain name"""
--> 127         return self._results('parsed-whois', '/v1/{0}/whois/parsed'.format(query), cls=ParsedWhois, **kwargs)
    128 
    129     def registrant_monitor(self, query, exclude=[], days_back=0, limit=None, **kwargs):

/usr/local/lib/python3.7/site-packages/domaintools/api.py in _results(self, product, path, cls, **kwargs)
     57         """Returns _results for the specified API path with the specified **kwargs parameters"""
     58         if product != 'account-information' and self.rate_limit and not self.limits_set and not self.limits:
---> 59             self._rate_limit()
     60 
     61         uri = '/'.join(('{0}://api.domaintools.com'.format('https' if self.https else 'http'), path.lstrip('/')))

/usr/local/lib/python3.7/site-packages/domaintools/api.py in _rate_limit(self)
     51         """Pulls in and enforces the latest rate limits for the specified user"""
     52         self.limits_set = True
---> 53         for product in self.account_information():
     54             self.limits[product['id']] = {'interval': timedelta(seconds=60 / float(product['per_minute_limit']))}
     55 

/usr/local/lib/python3.7/site-packages/domaintools/base_results.py in __iter__(self)
    167 
    168     def __iter__(self):
--> 169         return self._items().__iter__()
    170 
    171     def has_key(self, key):

/usr/local/lib/python3.7/site-packages/domaintools/base_results.py in _items(self)
    150                 return self.items()
    151 
--> 152             response = self.response()
    153             for step in self.items_path:
    154                 response = response[step]

/usr/local/lib/python3.7/site-packages/domaintools/base_results.py in response(self)
    131     def response(self):
    132         if self._response is None:
--> 133             response = self.data()
    134             for step in self.response_path:
    135                 response = response[step]

/usr/local/lib/python3.7/site-packages/domaintools/base_results.py in data(self)
     82         if self._data is None:
     83             results = self._get_results()
---> 84             raise_after = self.setStatus(results.status_code, results)
     85             if self.kwargs.get('format', 'json') == 'json':
     86                 self._data = results.json()

/usr/local/lib/python3.7/site-packages/domaintools/base_results.py in setStatus(self, code, response)
    117             raise BadRequestException(code, reason)
    118         elif code == 403:
--> 119             raise NotAuthorizedException(code, reason)
    120         elif code == 404:
    121             raise NotFoundException(code, reason)

NotAuthorizedException: {'error': {'code': 403, 'message': 'Your API user account is not authorized to access this product.'}, 'resources': {'support': 'http://www.domaintools.com/support/'}}

dtconfig.py contains the following:

user = 'user'
apiKey = '[UUID lowercase]'
host = 'https://api.domaintools.com'

The same dtconfig user and key work correctly with manual api calls in the following code snippet:

uriFirst = '/v1/' + domain + '/whois'
            signature = signer.sign(timestamp, uriFirst)
            uriSecond = '?api_username=' + user + '&signature=' + signature + '&timestamp=' + timestamp
            fullUrl = host + uriFirst + uriSecond
            #print(fullUrl)
            try:
                retrieve = requests.get(fullUrl).json()

Am I missing something ?

domaintools whois google.com works using the same credentials in ~/.dtapi

Talking to member services, apparently this is caused if "the Account Information endpoint was temporarily disabled"

Still strange it was working outside of the api object