From 4c1c96ab3aee3bb231d8cf56f07de71d476d1531 Mon Sep 17 00:00:00 2001 From: whoisxmlapi Date: Mon, 30 Oct 2023 12:48:28 +0200 Subject: [PATCH] Update Website Categorization API version --- README.rst | 10 +- src/websitecategorization/client.py | 10 +- src/websitecategorization/models/response.py | 48 ++++--- src/websitecategorization/version.py | 2 +- tests/model_test.py | 125 ++++--------------- 5 files changed, 61 insertions(+), 134 deletions(-) diff --git a/README.rst b/README.rst index f23e020..528ad07 100644 --- a/README.rst +++ b/README.rst @@ -30,7 +30,7 @@ Installation Examples ======== -Full API documentation available `here `_ +Full API documentation available `here `_ Create a new client ------------------- @@ -51,10 +51,7 @@ Make basic requests print("Responded? " + "Yes" if response.website_responded else "No") if response.website_responded: for cat in response.categories: - if cat.tier1: - print("Tier1 cat: " + str(cat.tier1.name)) - if cat.tier2: - print("Tier2 cat: " + str(cat.tier2.name)) + print("Cat: " + str(cat.name)) Advanced usage ------------------- @@ -66,6 +63,5 @@ Extra request parameters # Specifying minimal level of confidence response = client.data('whoisxmlapi.com', 0.75) - # Getting raw API response in XML and CSV + # Getting raw API response in XML xml = client.raw_data('whoisxmlapi.com', output_format=Client.XML_FORMAT) - csv = client.raw_data('whoisxmlapi.com', output_format=Client.CSV_FORMAT) diff --git a/src/websitecategorization/client.py b/src/websitecategorization/client.py index 3a85382..335d3c7 100644 --- a/src/websitecategorization/client.py +++ b/src/websitecategorization/client.py @@ -8,7 +8,7 @@ class Client: - __default_url = "https://website-categorization.whoisxmlapi.com/api/v2" + __default_url = "https://website-categorization.whoisxmlapi.com/api/v3" _api_requester: ApiRequester or None _api_key: str @@ -22,7 +22,6 @@ class Client: JSON_FORMAT = 'json' XML_FORMAT = 'xml' - CSV_FORMAT = 'csv' __DATETIME_OR_NONE_MSG = 'Value should be None or an instance of ' \ 'datetime.date' @@ -116,8 +115,7 @@ def raw_data(self, domain: str, min_confidence: float or None = None, :param domain: Domain name, string :param min_confidence: Minimal confidence value. The higher this value the fewer false-positive results will be returned, float - :param output_format: Use Client.JSON_FORMAT, Client.XML_FORMAT, - Client.CSV_FORMAT constants + :param output_format: Use Client.JSON_FORMAT, Client.XML_FORMAT constants :return: str :raises ConnectionError: :raises WebsiteCategorizationApiError: Base class for all errors below @@ -163,12 +161,12 @@ def _validate_domain_name(value) -> str: @staticmethod def _validate_output_format(value: str): if value.lower() in {Client.JSON_FORMAT, - Client.XML_FORMAT, Client.CSV_FORMAT}: + Client.XML_FORMAT}: return value.lower() raise ParameterError( f"Response format must be {Client.JSON_FORMAT} " - f"or {Client.XML_FORMAT} or {Client.CSV_FORMAT}") + f"or {Client.XML_FORMAT}") @staticmethod def _validate_confidence(value: float): diff --git a/src/websitecategorization/models/response.py b/src/websitecategorization/models/response.py index b3c8f14..1815a97 100644 --- a/src/websitecategorization/models/response.py +++ b/src/websitecategorization/models/response.py @@ -44,60 +44,72 @@ def _bool_value(values: dict, key: str) -> bool: return False -class Tier(BaseModel): +class Category(BaseModel): confidence: float - id: str + id: int name: str def __init__(self, values): super().__init__() self.confidence = 0.0 self.name = "" - self.id = "" + self.id = 0 if values is not None: self.confidence = _float_value(values, 'confidence') - self.id = _string_value(values, 'id') + self.id = _int_value(values, 'id') self.name = _string_value(values, 'name') -class Category(BaseModel): - tier1: Tier or None - tier2: Tier or None +class AS(BaseModel): + asn: int + domain: str + name: str + route: str + type: str def __init__(self, values): super().__init__() - - self.tier1 = None - self.tier2 = None + self.asn = 0 + self.domain = "" + self.name = "" + self.route = "" + self.type = "" if values is not None: - if 'tier1' in values and values['tier1']: - self.tier1 = Tier(values['tier1']) - if 'tier2' in values and values['tier2']: - self.tier2 = Tier(values['tier2']) + self.asn = _int_value(values, 'asn') + self.domain = _string_value(values, 'domain') + self.name = _string_value(values, 'name') + self.route = _string_value(values, 'route') + self.type = _string_value(values, 'type') class Response(BaseModel): + as_field: AS or None domain_name: str - website_responded: bool if sys.version_info < (3, 9): categories: typing.List[Category] else: categories: [Category] + created_date: str or None + website_responded: bool def __init__(self, values): super().__init__() + self.as_field = None self.domain_name = "" - self.website_responded = False self.categories = [] + self.created_date = None + self.website_responded = False if values is not None: + if 'as' in values and values['as']: + self.as_field = AS(values['as']) self.domain_name = _string_value(values, 'domainName') + self.categories = _list_of_objects(values, 'categories', 'Category') + self.created_date = _string_value(values, 'createdDate') self.website_responded = _bool_value(values, 'websiteResponded') - self.categories = _list_of_objects( - values, 'categories', 'Category') class ErrorMessage(BaseModel): diff --git a/src/websitecategorization/version.py b/src/websitecategorization/version.py index 17eaa83..aa16731 100644 --- a/src/websitecategorization/version.py +++ b/src/websitecategorization/version.py @@ -1,2 +1,2 @@ -VERSION = '1.0.0' +VERSION = '1.1.0' LIBRARY_NAME = 'website-categorization-python' diff --git a/tests/model_test.py b/tests/model_test.py index b538194..6831325 100644 --- a/tests/model_test.py +++ b/tests/model_test.py @@ -4,82 +4,23 @@ _json_response_ok = '''{ - "categories": [ - { - "tier1": { - "confidence": 0.9499015947838411, - "id":"IAB-596", - "name":"Technology & Computing" - }, - "tier2": { - "confidence":0.8420597541031617, - "id":"IAB-618", - "name":"Information and Network Security" - } - }, - { - "tier1": { - "confidence":0.9499015947838411, - "id":"IAB-596", - "name":"Technology & Computing" - }, - "tier2": { - "confidence":0.6916495127489835, - "id":"IAB-623", - "name":"Email" - } - }, - { - "tier1": { - "confidence":0.9499015947838411, - "id":"IAB-52", - "name":"Business and Finance" - }, - "tier2": { - "confidence":0.6916495127489835, - "id":"IAB-99", - "name":"Information Services Industry" - } - }, - { - "tier1": { - "confidence":0.9499015947838411, - "id":"IAB-52", - "name":"Business and Finance" - }, - "tier2": { - "confidence":0.6916495127489835, - "id":"IAB-115", - "name":"Technology Industry" - } - }, - { - "tier1": { - "confidence":0.9499015947838411, - "id":"IAB-52", - "name":"Business and Finance" - }, - "tier2": { - "confidence":0.6916495127489835, - "id":"IAB-116", - "name":"Telecommunications Industry" - } - }, - { - "tier1": { - "confidence":0.9499015947838411, - "id":"IAB-596", - "name":"Technology & Computing" - }, - "tier2": { - "confidence":0.6087944770670476, - "id":"IAB-619", - "name":"Internet" - } - } - ], - "domainName": "whoisxmlapi.com", - "websiteResponded": true + "as": { + "asn": 13335, + "domain": "https://www.cloudflare.com", + "name": "CLOUDFLARENET", + "route": "172.67.64.0/20", + "type": "Content" + }, + "domainName": "whoisxmlapi.com", + "categories": [ + { + "confidence": 0.85, + "id": 5, + "name": "Computer and Internet Info" + } + ], + "createdDate": "2009-03-19T21:47:17+00:00", + "websiteResponded": true }''' _json_response_error = '''{ @@ -98,34 +39,14 @@ def test_response_parsing(self): parsed.website_responded, response['websiteResponded']) self.assertIsInstance(parsed.categories, list) self.assertEqual( - parsed.categories[0].tier1.id, - response['categories'][0]['tier1']['id']) + parsed.categories[0].id, + response['categories'][0]['id']) self.assertEqual( - parsed.categories[0].tier1.name, - response['categories'][0]['tier1']['name']) + parsed.categories[0].name, + response['categories'][0]['name']) self.assertEqual( - parsed.categories[0].tier1.confidence, - response['categories'][0]['tier1']['confidence']) - - self.assertEqual( - parsed.categories[0].tier2.id, - response['categories'][0]['tier2']['id']) - self.assertEqual( - parsed.categories[0].tier2.name, - response['categories'][0]['tier2']['name']) - self.assertEqual( - parsed.categories[0].tier2.confidence, - response['categories'][0]['tier2']['confidence']) - - self.assertEqual( - parsed.categories[1].tier1.id, - response['categories'][1]['tier1']['id']) - self.assertEqual( - parsed.categories[1].tier1.name, - response['categories'][1]['tier1']['name']) - self.assertEqual( - parsed.categories[1].tier1.confidence, - response['categories'][1]['tier1']['confidence']) + parsed.categories[0].confidence, + response['categories'][0]['confidence']) def test_error_parsing(self): error = loads(_json_response_error)