diff --git a/.gitignore b/.gitignore index ae11db0..2d22aea 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,4 @@ *.swp *.egg-info dist -build \ No newline at end of file +build diff --git a/README.md b/README.md index 9e81756..59c424d 100644 --- a/README.md +++ b/README.md @@ -2,17 +2,22 @@ semantics3 is a python client for accessing the Semantics3 Products API, which provides structured information, including pricing histories, for a large number of products. See https://www.semantics3.com for more information. -Quickstart guide: https://www.semantics3.com/quickstart API documentation can be found at https://www.semantics3.com/docs/ ## Installation -semantics3 can be installed through pypi: +semantics3 can be installed through pip: ```bash pip install semantics3 ``` -To install the latest source from the repository +To install the egg directly from github + +```bash +pip install -e git+ssh://git@github.com/Semantics3/semantics3-python.git#egg=semantics3 +``` + +To install the latest source: ```bash git clone https://github.com/Semantics3/semantics3-python.git @@ -27,7 +32,7 @@ python setup.py install In order to use the client, you must have both an API key and an API secret. To obtain your key and secret, you need to first create an account at https://www.semantics3.com/ -You can access your API access credentials from the user dashboard at https://www.semantics3.com/dashboard/applications +You can access your API access credentials from the user dashboard at https://dashboard.semantics3.com. ### Setup Work @@ -37,141 +42,234 @@ Let's lay the groundwork. from semantics3 import Products # Set up a client to talk to the Semantics3 API using your Semantics3 API Credentials -products = Products( - api_key = "SEM3xxxxxxxxxxxxxxxxxxxxxx", - api_secret = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +sem3 = Products( + api_key=os.environ['SEMANTICS3_API_KEY'], + api_secret=os.environ['SEMANTICS3_API_SECRET'] ) ``` -### First Query aka 'Hello World': +### First Request aka 'Hello World': + +Let's run our first request! We are going to run a simple search for the word "iPhone" as follows: -Let's make our first query! For this query, we are going to search for all Toshiba products that fall under the category of "Computers and Accessories", whose cat_id is 4992. ```python -# Build the query -products.products_field( "cat_id", 4992 ) -products.products_field( "brand", "Toshiba" ) +# Build the request +sem3.products_field("search", "iphone") -# Make the query -results = products.get_products(); +# Run the request +results = sem3.get_products() #or -results = products.get() +results = sem3.get() -# View the results of the query +# View the results of the request print results ``` -## Examples +## Sample Requests -The following examples show you how to interface with some of the core functionality of the Semantics3 Products API. For more detailed examples check out the Quickstart guide: https://www.semantics3.com/quickstart +The following examples show you how to interface with some of the core functionality of the Semantics3 Products API. -### Explore the Category Tree +### Pagination -In this example we are going to be accessing the categories endpoint. We are going to be specifically exploiring the "Computers and Accessories" category, which has a cat_id of 4992. For more details regarding our category tree and associated cat_ids check out our API docs at https://www.semantics3.com/docs +The example in our "Hello World" script returns the first 10 results. In this example, we'll scroll to subsequent pages, beyond our initial request: ```python -# Build the query -products.categories_field( "cat_id", 4992 ); +# Build the request +sem3.products_field("search", "iphone") -# Execute the query -results = products.get_categories(); +# Run the request +results = sem3.get_products() -# View the results of the query -print results +# Specify a cache size +sem3.cache(5) + +# Iterate through the results +page_no = 0 +for i in sem3.iter(): + page_no += 1 + print "We are at page = %s" % page_no + print "The results for this page are:" + print i + sleep(1) #respect rate limit ``` -### Nested Search Query +### Request Timeout -You can intuitively construct all your complex queries but just repeatedly using the products_field() or add() methods. -Here is how we translate the following JSON query: +The RealTime API has a hard server-side timeout of **60s** (up to **120s** for some customers) by default after which the client request will be aborted. You can +override this behaviour by setting a client-side timeout value as shown below: + +```python +import os +from requests.exceptions import ReadTimeout, ConnectTimeout +from semantics3 import Products + +sem3 = Products( + api_key=os.environ['SEMANTICS3_API_KEY'], + api_secret=os.environ['SEMANTICS3_API_SECRET'], + timeout=5 +) + +try: + sem3.run_query('realtime/skus', 'GET', { 'url': 'https://www.walmart.com/ip/325408104' }) +except (ReadTimeout, ConnectTimeout): + print('request timed out in 5s') -```javascript -{ - "cat_id" : 4992, - "brand" : "Toshiba", - "weight" : { "gte":1000000, "lt":1500000 }, - "sitedetails" : { - "name" : "newegg.com", - "latestoffers" : { - "currency": "USD", - "price" : { "gte" : 100 } - } - } -} ``` -This query returns all Toshiba products within a certain weight range narrowed down to just those that retailed recently on newegg.com for >= USD 100. + +### UPC Query + +Running a UPC/EAN/GTIN query is as simple as running a search query: ```python -# Build the query -products = Products( api_key, api_secret ) -products.products_field( "cat_id", 4992 ) -products.products_field( "brand", "Toshiba" ) -products.products_field( "weight", "gte", 1000000 ) -products.products_field( "weight", "lt", 1500000 ) -products.products_field( "sitedetails", "name", "newegg.com" ) -products.products_field( "sitedetails", "latestoffers", "currency", "USD" ) -products.products_field( "sitedetails", "latestoffers", "price", "gte", 100 ) -# Let's make a modification - say we no longer want the weight attribute -products.remove( "products", "weight" ); - -# Make the query -results = products.get_products(); +# Build the request +sem3.products_field("upc", "883974958450") +sem3.products_field("fields", ["name","gtins"]) + +# Run the request +results = sem3.get_products() + +# View the results of the request +print results +``` + +### URL Query + +Get the picture? You can run URL queries as follows: + +```python +sem3.products_field("url", "http://www.walmart.com/ip/15833173") +results = sem3.get_products() print results ``` -### Pagination +### Price Filter -The Semantics3 API allows for pagination, so you can request for, say, 5 results, -and then continue to obtain the next 5 from where you stopped previously. For the -python semantics3 module, we have implemented this using iterators. -All you have to do is specify a cache size, and use it the same way you would -any iterator: +Filter by price using the "lt" (less than) tag: ```python -# Specify a cache size -products.cache(5) +sem3.products_field("search", "iphone") +sem3.products_field("price", "lt", 300) +results = sem3.get_products() +print results +``` -# Iterate through the results -for i in products.iter(): - print i +### Category ID Query + +To lookup details about a cat_id, run your request against the categories resource: + +```python +# Build the request +sem3.categories_field("cat_id", 4992) + +# Run the request +results = sem3.get_categories() + +# View the results of the request +print results ``` -Our library will automatically request for results 5 products at a time. +## Webhooks +You can use webhooks to get near-real-time price updates from Semantics3. + +### Creating a webhook + +You can register a webhook with Semantics3 by sending a POST request to `"webhooks"` endpoint. +To verify that your URL is active, a GET request will be sent to your server with a `verification_code` parameter. Your server should respond with `verification_code` in the response body to complete the verification process. + +```python +params = { + webhook_uri : "http://mydomain.com/webhooks-callback-url" +} + +webhook = sem3.run_query("webhooks", "POST", params) +print webhook["id"] +print webhook["webhook_uri"] +``` -### Explore Price Histories -For this example, we are going to look at a particular product that is sold by select merchants and has a price of >= USD 30 and seen after a specific date (specified as a UNIX timestamp). +To fetch existing webhooks +```python +webhooks = sem3.run_query("webhooks", "GET") +print webhooks +``` +To remove a webhook ```python -# Build the query -products.offers_field( "sem3_id", "4znupRCkN6w2Q4Ke4s6sUC"); -products.offers_field( "seller", ["LFleurs","Frys","Walmart"] ); -products.offers_field( "currency", "USD"); -products.offers_field( "price", "gte", 30); -products.offers_field( "lastrecorded_at", "gte", 1348654600); +webhook_id = '7JcGN81u' +endpoint = "webhooks/%s" % webhook_id + +response = sem3.run_query( endpoint, "DELETE") +print response +``` +### Registering events +Once you register a webhook, you can start adding events to it. Semantics3 server will send you notifications when these events occur. +To register events for a specific webhook send a POST request to the `"webhooks/{webhook_id}/events"` endpoint +```python +params = { + "type": "price.change", + "product": { + "sem3_id": "1QZC8wchX62eCYS2CACmka" + }, + "constraints": { + "gte": 10, + "lte": 100 + } +} -# Make the query -results = products.get_offers() +webhook_id = '7JcGN81u' +endpoint = "webhooks/%s/events" % webhook_id -# View the results of the query -print results +eventObject = sem3.run_query(endpoint, "POST", params) +print eventObject["id"] +print eventObject["type"] +print eventObject["product"] ``` +To fetch all registered events for a give webhook +```python +webhook_id = '7JcGN81u' +endpoint = "webhooks/%s/events" % webhook_id +events = sem3.run_query(endpoint, "GET") +print events +``` +### Webhook Notifications +Once you have created a webhook and registered events on it, notifications will be sent to your registered webhook URI via a POST request when the corresponding events occur. Make sure that your server can accept POST requests. Here is how a sample notification object looks like +```javascript +{ + "type": "price.change", + "event_id": "XyZgOZ5q", + "notification_id": "X4jsdDsW", + "changes": [{ + "site": "abc.com", + "url": "http://www.abc.com/def", + "previous_price": 45.50, + "current_price": 41.00 + }, { + "site": "walmart.com", + "url": "http://www.walmart.com/ip/20671263", + "previous_price": 34.00, + "current_price": 42.00 + }] +} +``` ## Contributing Use GitHub's standard fork/commit/pull-request cycle. If you have any questions, email . -## Author +## Authors + +* Shawn Tan -* Shawn Tan +* Abishek Bhat ## Copyright -Copyright (c) 2013 Semantics3 Inc. +Copyright (c) 2015 Semantics3 Inc. ## License diff --git a/README.rst b/README.rst index e69de29..f4293d5 100644 --- a/README.rst +++ b/README.rst @@ -0,0 +1,233 @@ +semantics3 +========== + +semantics3 is a python client for accessing the Semantics3 Products API, +which provides structured information, including pricing histories, for +a large number of products. See https://www.semantics3.com for more +information. + +Quickstart guide: https://www.semantics3.com/quickstart API +documentation can be found at https://www.semantics3.com/docs/ + +Installation +------------ + +semantics3 can be installed through pypi: + +.. code:: bash + + pip install semantics3 + +To install the latest source from the repository + +.. code:: bash + + git clone https://github.com/Semantics3/semantics3-python.git + cd semantics3-python + python setup.py install + +Requirements +------------ + +- requests-oauthlib + +Getting Started +--------------- + +In order to use the client, you must have both an API key and an API +secret. To obtain your key and secret, you need to first create an +account at https://www.semantics3.com/ You can access your API access +credentials from the user dashboard at https://dashboard.semantics3.com. + +Setup Work +~~~~~~~~~~ + +Let's lay the groundwork. + +.. code:: python + + from semantics3 import Products + + # Set up a client to talk to the Semantics3 API using your Semantics3 API Credentials + products = Products( + api_key = "SEM3xxxxxxxxxxxxxxxxxxxxxx", + api_secret = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + ) + +First Query aka 'Hello World': +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Let's make our first query! For this query, we are going to search for +all Toshiba products that fall under the category of "Computers and +Accessories", whose cat\_id is 4992. + +.. code:: python + + # Build the query + products.products_field( "cat_id", 4992 ) + products.products_field( "brand", "Toshiba" ) + + # Make the query + results = products.get_products(); + #or + results = products.get() + + # View the results of the query + print results + +Examples +-------- + +The following examples show you how to interface with some of the core +functionality of the Semantics3 Products API. For more detailed examples +check out the Quickstart guide: https://www.semantics3.com/quickstart + +Explore the Category Tree +~~~~~~~~~~~~~~~~~~~~~~~~~ + +In this example we are going to be accessing the categories endpoint. We +are going to be specifically exploiring the "Computers and Accessories" +category, which has a cat\_id of 4992. For more details regarding our +category tree and associated cat\_ids check out our API docs at +https://www.semantics3.com/docs + +.. code:: python + + # Build the query + products.categories_field( "cat_id", 4992 ); + + # Execute the query + results = products.get_categories(); + + # View the results of the query + print results + +Nested Search Query +~~~~~~~~~~~~~~~~~~~ + +You can intuitively construct all your complex queries but just +repeatedly using the products\_field() or add() methods. Here is how we +translate the following JSON query: + +.. code:: javascript + + { + "cat_id" : 4992, + "brand" : "Toshiba", + "weight" : { "gte":1000000, "lt":1500000 }, + "sitedetails" : { + "name" : "newegg.com", + "latestoffers" : { + "currency": "USD", + "price" : { "gte" : 100 } + } + } + } + +This query returns all Toshiba products within a certain weight range +narrowed down to just those that retailed recently on newegg.com for >= +USD 100. + +.. code:: python + + # Build the query + products = Products( api_key, api_secret ) + products.products_field( "cat_id", 4992 ) + products.products_field( "brand", "Toshiba" ) + products.products_field( "weight", "gte", 1000000 ) + products.products_field( "weight", "lt", 1500000 ) + products.products_field( "sitedetails", "name", "newegg.com" ) + products.products_field( "sitedetails", "latestoffers", "currency", "USD" ) + products.products_field( "sitedetails", "latestoffers", "price", "gte", 100 ) + # Let's make a modification - say we no longer want the weight attribute + products.remove( "products", "weight" ); + + # Make the query + results = products.get_products(); + print results + +Pagination +~~~~~~~~~~ + +The Semantics3 API allows for pagination, so you can request for, say, 5 +results, and then continue to obtain the next 5 from where you stopped +previously. For the python semantics3 module, we have implemented this +using iterators. All you have to do is specify a cache size, and use it +the same way you would any iterator: + +.. code:: python + + # Specify a cache size + products.cache(5) + + # Iterate through the results + for i in products.iter(): + print i + +Our library will automatically request for results 5 products at a time. + +Explore Price Histories +~~~~~~~~~~~~~~~~~~~~~~~ + +For this example, we are going to look at a particular product that is +sold by select merchants and has a price of >= USD 30 and seen after a +specific date (specified as a UNIX timestamp). + +.. code:: python + + # Build the query + products.offers_field( "sem3_id", "4znupRCkN6w2Q4Ke4s6sUC"); + products.offers_field( "seller", ["LFleurs","Frys","Walmart"] ); + products.offers_field( "currency", "USD"); + products.offers_field( "price", "gte", 30); + products.offers_field( "lastrecorded_at", "gte", 1348654600); + + + + # Make the query + results = products.get_offers() + + # View the results of the query + print results + +Contributing +------------ + +Use GitHub's standard fork/commit/pull-request cycle. If you have any +questions, email support@semantics3.com. + +Author +------ + +- Shawn Tan shawn@semantics3.com + +Copyright +--------- + +Copyright (c) 2013 Semantics3 Inc. + +License +------- + +:: + + The "MIT" License + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + diff --git a/semantics3/categories.py b/semantics3/categories.py index 7036647..4835bce 100644 --- a/semantics3/categories.py +++ b/semantics3/categories.py @@ -4,8 +4,8 @@ from semantics3 import Semantics3Request class Categories(Semantics3Request): - def __init__(self, api_key, api_secret): - Semantics3Request.__init__(self, api_key, api_secret, 'categories') + def __init__(self, api_key, api_secret, api_base='https://api.semantics3.com/v1/'): + Semantics3Request.__init__(self, api_key, api_secret, 'categories', api_base) def get_categories(self): return self.get() diff --git a/semantics3/offers.py b/semantics3/offers.py index 2538c02..250c872 100644 --- a/semantics3/offers.py +++ b/semantics3/offers.py @@ -4,8 +4,8 @@ from semantics3 import Semantics3Request class Offers(Semantics3Request): - def __init__(self, api_key, api_secret): - Semantics3Request.__init__(self, api_key, api_secret, 'offers') + def __init__(self, api_key, api_secret, api_base='https://api.semantics3.com/v1/'): + Semantics3Request.__init__(self, api_key, api_secret, 'offers', api_base) def get_offers(self): return self.get() diff --git a/semantics3/products.py b/semantics3/products.py index aa4f3ff..a07d6b0 100644 --- a/semantics3/products.py +++ b/semantics3/products.py @@ -5,8 +5,8 @@ class Products(Semantics3Request): - def __init__(self, api_key, api_secret): - Semantics3Request.__init__(self, api_key, api_secret, 'products') + def __init__(self, api_key, api_secret, api_base='https://api.semantics3.com/v1/', timeout=120): + Semantics3Request.__init__(self, api_key, api_secret, 'products', api_base, timeout) def get_products(self): return self.get() diff --git a/semantics3/semantics3.py b/semantics3/semantics3.py index edc07c1..c6657e0 100644 --- a/semantics3/semantics3.py +++ b/semantics3/semantics3.py @@ -1,5 +1,6 @@ import json from requests_oauthlib import OAuth1Session +from url_normalize import url_normalize try: import urllib.parse as urllib @@ -12,13 +13,9 @@ from error import Semantics3Error -API_DOMAIN = 'api.semantics3.com' -API_BASE = 'https://' + API_DOMAIN + '/v1/' - - class Semantics3Request: - def __init__(self, api_key=None, api_secret=None, endpoint=None): + def __init__(self, api_key=None, api_secret=None, endpoint=None, api_base='https://api.semantics3.com/v1/', timeout=120): if api_key is None: raise Semantics3Error( 'API Credentials Missing', @@ -38,11 +35,27 @@ def __init__(self, api_key=None, api_secret=None, endpoint=None): self.data_query = {} self.query_result = None self.cache_size = 10 - - def fetch(self, endpoint, params): - api_endpoint = API_BASE + endpoint + '?' +\ - urllib.urlencode({'q': params}) - content = self.oauth.get(api_endpoint,headers={'User-Agent':'Semantics3 Python Lib/0.2'}) + self.api_base = api_base + self.timeout = timeout + + def fetch(self, method, endpoint, params): + api_endpoint = url_normalize(self.api_base + endpoint) + if method.lower() in ['get', 'delete']: + content = self.oauth.request( + method, + api_endpoint, + params = params, + headers={'User-Agent':'Semantics3 Python Lib/0.2'}, + timeout=self.timeout + ) + else: + content = self.oauth.request( + method, + api_endpoint, + data = json.dumps(params), + headers={'User-Agent':'Semantics3 Python Lib/0.2', 'Content-Type':'application/json'}, + timeout=self.timeout + ) return content def remove(self, endpoint, *fields): @@ -70,8 +83,7 @@ def add(self, endpoint, *fields): else: raise Semantics3Error( 'Invalid constraint', - 'Cannot add this constraint, \'' + parent + '\' is already\ - a value.' + 'Cannot add this constraint, \'' + parent + '\' is already a value.' ) if isinstance(parent, dict): @@ -79,8 +91,7 @@ def add(self, endpoint, *fields): else: raise Semantics3Error( 'Invalid constraint', - 'Cannot add this constraint, \'' + parent + '\' is already\ - a value.' + 'Cannot add this constraint, \'' + parent + '\' is already a value.' ) def field(self, *fields): @@ -103,28 +114,47 @@ def iter(self): if(offset < total_count): self.run_query() - def query(self, endpoint, **kwargs): - content = self.fetch(endpoint, json.dumps(kwargs)).content.decode('utf-8') - return json.loads(content) + def query(self, method, endpoint, kwargs): + if method.lower() == "get": + params = { 'q' : json.dumps(kwargs) } + else: + params = kwargs + response = self.fetch(method, endpoint, params) + try: + response_json = response.json() + except: + raise Exception("Malformed JSON") + + if response.status_code < 400: + return response.json() + else: + if response.json().get('code') != 'OK': + response_body = response.json() + raise Semantics3Error(response_body.get('code'), + response_body.get('message')) - def run_query(self, endpoint=None): + def run_query(self, endpoint=None, method='GET', params=None): endpoint = endpoint or self.endpoint - if not endpoint in self.data_query: - raise Semantics3Error("No query built", "You need to first create\ - a query using the add() method.") - query = self.data_query[endpoint] - self.query_result = self.query( - endpoint, - **query - ) - - if self.query_result['code'] != 'OK': - raise Semantics3Error(self.query_result['code'], - self.query_result['message']) + if method.lower() == "get": + try: + query = self.data_query[endpoint] + except KeyError: + query = params or {} + self.query_result = self.query( + method, + endpoint, + query + ) + else: + self.query_result = self.query( + method, + endpoint, + params + ) + return self.query_result def get(self, endpoint=None): - self.run_query(endpoint) - return self.query_result + return self.run_query(endpoint) def clear_query(self): self.data_query = {} diff --git a/setup.py b/setup.py index 5d01468..da0f211 100644 --- a/setup.py +++ b/setup.py @@ -6,23 +6,30 @@ from distutils.core import setup install_requires = [ - 'requests-oauthlib >= 0.4.0' + 'requests-oauthlib >= 0.4.0', + 'url-normalize' ] - - def read(fname): - return open(os.path.join(os.path.dirname(__file__), fname)).read() + try: + import pypandoc + description = pypandoc.convert(fname, 'rst') + except (IOError, ImportError): + description = '' + print(description) + with open('README.rst','w') as f: f.write(description) + return description + setup( name="semantics3", - version="0.2", - author="Shawn Tan", - author_email="shawn@semantics3.com", + version="0.3.9", + author="Shawn Tan, Abishek Bhat", + author_email="abishek@semantics3.com", description=("Semantics3 Products API"), license="MIT", keywords="api ecommerce products", url="https://github.com/Semantics3/semantics3-python", packages=['semantics3'], - long_description=read('README.rst'), + long_description=read('README.md'), install_requires=install_requires, classifiers=[ "Topic :: Utilities", diff --git a/tests/test_product.py b/tests/test_product.py new file mode 100644 index 0000000..d09f478 --- /dev/null +++ b/tests/test_product.py @@ -0,0 +1,65 @@ +from semantics3 import Products +import unittest +from os import environ + +sem3 = Products( + api_key = environ["SEM3_API_KEY"], + api_secret = environ["SEM3_API_SECRET"] + ) + + +class TestProductAPI(unittest.TestCase): + + """Docstring for TestProductAPI. """ + def test_get_products(self): + """@todo: Docstring for test_get_products. + :returns: @todo + + """ + sem3.products_field("search", "iphone") + results = sem3.get_products() + self.assertEqual(results['code'], 'OK') + sem3.clear_query() + + def test_upc_query(self): + """@todo: Docstring for test_upc_query. + :returns: @todo + + """ + pass + sem3.products_field("upc", "883974958450") + sem3.products_field("field", ["name","gtins"]) + results = sem3.get_products() + self.assertEqual(results['code'], 'OK') + sem3.clear_query() + + def test_url_query(self): + """@todo: Docstring for test_url_query. + :returns: @todo + + """ + sem3.products_field("url", "http://www.walmart.com/ip/15833173") + results = sem3.get_products() + self.assertEqual(results['code'], 'OK') + sem3.clear_query() + + def test_price_query(self): + """@todo: Docstring for test_price_query. + :returns: @todo + + """ + sem3.products_field("search", "iphone") + sem3.products_field("price", "lt", 300) + results = sem3.get_products() + self.assertEqual(results['code'], 'OK') + sem3.clear_query() + + def test_catid_query(self): + """@todo: Docstring for test_catid_query. + :returns: @todo + + """ + sem3.categories_field("cat_id", 4992) + results = sem3.get_categories() + self.assertEqual(results['code'], 'OK') + sem3.clear_query() diff --git a/tests/test_webhooks.py b/tests/test_webhooks.py new file mode 100644 index 0000000..b50b123 --- /dev/null +++ b/tests/test_webhooks.py @@ -0,0 +1,69 @@ +from semantics3 import Semantics3Request +import unittest +from os import environ + +sem3 = Semantics3Request( + api_key = environ["SEM3_API_KEY"], + api_secret = environ["SEM3_API_SECRET"] + ) + + +class TestWebhoOKsAPI(unittest.TestCase): + + """Docstring for TestWebhoOKs. """ + + def test_webhook_registration(self): + """@todo: Docstring for test_webhook_registration. + + :returns: @todo + """ + result = sem3.run_query('webhooks', "POST", {"webhook_uri" : "https://semantics3-basic-webhook-receiver-11ozacc07xtw.runkit.sh/"}) + self.assertIn('created', result["results"]) + + def test_get_webhooks(self): + """@todo: Docstring for test_get_webhooks. + :returns: @todo + + """ + webhooks = sem3.run_query('webhooks', "GET") + self.assertEqual(webhooks['code'], 'OK') + + def test_register_event(self): + """@todo: Docstring for function. + + :returns: @todo + + """ + webhooks = sem3.run_query('webhooks', "GET") + if len(webhooks['results']): + webhook_id = webhooks['data'][0]['id'] + params = { + "type": "price.change", + "product": { + "sem3_id": "1QZC8wchX62eCYS2CACmka" + }, + "constraints" : { + "gte" : 10, + "lte" : 100 + } + } + response = sem3.run_query('webhooks/%s/events' % webhook_id, "POST", params) + self.assertEqual(response['code'], 'OK') + del params['constraints'] + response1 = sem3.run_query('webhooks/%s/events' % webhook_id, "POST", params) + self.assertEqual(response1['code'], 'OK') + else: + self.assertEqual(webhooks['code'], 'OK') + + def test_delete_webhook(self): + """@todo: Docstring for test_delete_webhook. + :returns: @todo + + """ + webhooks = sem3.run_query('webhooks', "GET") + if len(webhooks['results']): + webhook_id = webhooks['results'][0]['id'] + response = sem3.run_query('webhooks/%s' % webhook_id, "DELETE") + self.assertEqual(response['code'], 'OK') + else: + self.assertEqual(webhooks['code'], 'OK')