From 085eed9d0317efc243774593d161a23987c9e96e Mon Sep 17 00:00:00 2001 From: resteve Date: Mon, 28 Nov 2011 15:07:22 +0100 Subject: [PATCH 01/15] Merge pull request #2 from iiijjjii/master From 5fec28f863d522fca5e37084df21bc7729aabcb3 Mon Sep 17 00:00:00 2001 From: resteve Date: Mon, 28 Nov 2011 15:14:07 +0100 Subject: [PATCH 02/15] Implement Product Configurable API. * Needs custom magento_webservices module (available in Github) * https://github.com/zikzakmedia/magento_webservices --- magento/__init__.py | 4 ++-- magento/catalog.py | 43 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 2 deletions(-) diff --git a/magento/__init__.py b/magento/__init__.py index da147ad..741cec4 100644 --- a/magento/__init__.py +++ b/magento/__init__.py @@ -14,7 +14,7 @@ 'Country', 'Region', 'Category', 'CategoryAttribute', 'Product', 'ProductAttribute', 'ProductAttributeSet', 'ProductTypes', 'ProductImages', - 'ProductTierPrice', 'ProductLinks', 'Inventory', + 'ProductTierPrice', 'ProductLinks', 'ProductConfigurable', 'Inventory', 'Order', 'Shipment', 'Invoice', ] @@ -24,5 +24,5 @@ from catalog import Category, CategoryAttribute from catalog import Product, ProductAttribute, ProductAttributeSet from catalog import ProductTypes, ProductImages, ProductTierPrice -from catalog import ProductLinks, Inventory +from catalog import ProductLinks, ProductConfigurable, Inventory from sales import Order, Shipment, Invoice diff --git a/magento/catalog.py b/magento/catalog.py index ff8749a..1ccb819 100644 --- a/magento/catalog.py +++ b/magento/catalog.py @@ -635,6 +635,49 @@ def attributes(self, link_type): """ return self.call('catalog_product_link.attributes', [link_type]) +class ProductConfigurable(API): + """ + Product Configurable API for magento + """ + __slots__ = ( ) + + def info(self, product): + """ + Configurable product Info + + :param product: ID or SKU of product + :return: List + """ + return self.call('ol_catalog_product_link.list', [product]) + + def getSuperAttributes(self, product): + """ + Configurable Attributes product + + :param product: ID or SKU of product + :return: List + """ + return self.call('ol_catalog_product_link.listSuperAttributes', [product]) + + def update(self, product, linked_products, attributes): + """ + Configurable Update product + + :param product: ID or SKU of product + :param linked_products: List ID or SKU of linked product to link + :param attributes: dicc + :return: True/False + """ + return bool(self.call('ol_catalog_product_link.assign', [product, linked_products, attributes])) + + def remove(self, product, linked_products): + """ + Remove a product link configurable + + :param product: ID or SKU of product + :param linked_products: List ID or SKU of linked product to unlink + """ + return bool(self.call('ol_catalog_product_link.remove', [product, linked_products])) class Inventory(API): """ From 0d09c31f47621776d25811821fd89fd18bdfddaa Mon Sep 17 00:00:00 2001 From: resteve Date: Mon, 28 Nov 2011 16:17:31 +0100 Subject: [PATCH 03/15] Updated README --- README | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 README diff --git a/README b/README new file mode 100644 index 0000000..18cdb3c --- /dev/null +++ b/README @@ -0,0 +1,38 @@ +Magento Python +************** + +Python library to connect Magento Webservices + +Check documentation source code + +Examples: + +from magento import * + +url = 'http://domain.com/' +apiuser = 'user' +apipass = 'password' + +"""Product""" +with Product(url, apiuser, apipass) as product_api: + ofilter = {'created_at':{'from':'2011-09-15 00:00:00'}} + products = product_api.list(ofilter) + +with ProductTypes(url, apiuser, apipass) as product_type_api: + product_type = product_type_api.list() + +with Product(url, apiuser, apipass) as product_api: + sku = 'prod1' + product = product_api.info(sku) + +"""Websites""" +with API(url, apiuser, apipass) as magento_api: + websites = magento_api.call('ol_websites.list', []) + store_group = magento_api.call('ol_groups.list', []) + store_views = magento_api.call('ol_storeviews.list', []) + +"""Order""" +with Order(url, apiuser, apipass) as order_api: + order_increment_id = '100000001 ' + status = 'canceled' + order_api.addcomment(order_increment_id, status) From 4ec3173f7d28cd787fb040da4b14960675706078 Mon Sep 17 00:00:00 2001 From: resteve Date: Wed, 7 Dec 2011 15:35:32 +0100 Subject: [PATCH 04/15] Updated Catalog Product Attribute Info API * Note: Needs updated Magento Webservices Module * https://github.com/zikzakmedia/magento_webservices --- magento/catalog.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/magento/catalog.py b/magento/catalog.py index 1ccb819..ca8a8ef 100644 --- a/magento/catalog.py +++ b/magento/catalog.py @@ -363,6 +363,15 @@ def list(self, attribute_set_id): """ return self.call('catalog_product_attribute.list', [attribute_set_id]) + def info(self, attribute): + """ + Retrieve product attribute info + + :param attribute: ID or Code of the attribute + :return: `list` of `dict` + """ + return self.call('ol_catalog_product_attribute.info', [attribute]) + def options(self, attribute, store_view=None): """ Retrieve product attribute options From 47eb33ef80fede097e9dbd45978481abb3e82414 Mon Sep 17 00:00:00 2001 From: resteve Date: Wed, 7 Dec 2011 20:04:58 +0100 Subject: [PATCH 05/15] Implement ProductConfigurable:setSuperAttributeValues API --- magento/catalog.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/magento/catalog.py b/magento/catalog.py index ca8a8ef..8c905ff 100644 --- a/magento/catalog.py +++ b/magento/catalog.py @@ -668,6 +668,16 @@ def getSuperAttributes(self, product): """ return self.call('ol_catalog_product_link.listSuperAttributes', [product]) + def setSuperAttributeValues(self, product, attribute): + """ + Configurable Attributes product + + :param product: ID or SKU of product + :param attribute: ID attribute + :return: List + """ + return self.call('ol_catalog_product_link.setSuperAttributeValues', [product, attribute]) + def update(self, product, linked_products, attributes): """ Configurable Update product From 1f53b7b8e5e8760a25da5a521bcdcee1b0dae115 Mon Sep 17 00:00:00 2001 From: www-xilus-es Date: Mon, 31 Dec 2012 11:42:10 +0100 Subject: [PATCH 06/15] Implement create attributes options API * useful to create manufacturers for example --- magento/catalog.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/magento/catalog.py b/magento/catalog.py index 8c905ff..5ce7334 100644 --- a/magento/catalog.py +++ b/magento/catalog.py @@ -382,6 +382,17 @@ def options(self, attribute, store_view=None): return self.call('catalog_product_attribute.options', [attribute, store_view]) + def createOption(self, attribute, data): + """ + Create new options to attribute + + :param attribute: ID or Code of the attribute. + :param data: Dictionary of Data. + :return: True if created. + """ + return bool(self.call('product_attribute.addOption', + [attribute, data])) + class ProductAttributeSet(API): """ Product Attribute Set API From 8654bf5f88b7b47d84c8797736d2da9d3d2c1576 Mon Sep 17 00:00:00 2001 From: Sharoon Thomas Date: Thu, 25 Apr 2013 12:34:45 +0530 Subject: [PATCH 07/15] Pepify the code --- magento/__init__.py | 20 ++++++++-------- magento/catalog.py | 54 +++++++++++++++++++++++++------------------- magento/customer.py | 4 ++-- magento/directory.py | 2 +- magento/sales.py | 34 ++++++++++++++-------------- magento/utils.py | 1 + 6 files changed, 62 insertions(+), 53 deletions(-) diff --git a/magento/__init__.py b/magento/__init__.py index 741cec4..57e1d6e 100644 --- a/magento/__init__.py +++ b/magento/__init__.py @@ -14,15 +14,15 @@ 'Country', 'Region', 'Category', 'CategoryAttribute', 'Product', 'ProductAttribute', 'ProductAttributeSet', 'ProductTypes', 'ProductImages', - 'ProductTierPrice', 'ProductLinks', 'ProductConfigurable', 'Inventory', - 'Order', 'Shipment', 'Invoice', + 'ProductTierPrice', 'ProductLinks', 'ProductConfigurable', + 'Inventory', 'Order', 'Shipment', 'Invoice', ] -from api import API -from customer import Customer, CustomerGroup, CustomerAddress -from directory import Country, Region -from catalog import Category, CategoryAttribute -from catalog import Product, ProductAttribute, ProductAttributeSet -from catalog import ProductTypes, ProductImages, ProductTierPrice -from catalog import ProductLinks, ProductConfigurable, Inventory -from sales import Order, Shipment, Invoice +from .api import API +from .customer import Customer, CustomerGroup, CustomerAddress +from .directory import Country, Region +from .catalog import Category, CategoryAttribute +from .catalog import Product, ProductAttribute, ProductAttributeSet +from .catalog import ProductTypes, ProductImages, ProductTierPrice +from .catalog import ProductLinks, ProductConfigurable, Inventory +from .sales import Order, Shipment, Invoice diff --git a/magento/catalog.py b/magento/catalog.py index 5ce7334..30b1ec4 100644 --- a/magento/catalog.py +++ b/magento/catalog.py @@ -19,7 +19,7 @@ class Category(API): """ Product Category API """ - __slots__ = ( ) + __slots__ = () def currentStore(self, store_view=None): """ @@ -189,7 +189,7 @@ class CategoryAttribute(API): Product Category Attribute API to connect to magento Allows to get attributes and options for category. """ - __slots__ = ( ) + __slots__ = () def currentStore(self, store_view=None): """ @@ -225,7 +225,7 @@ class Product(API): """ Product API for magento """ - __slots__ = ( ) + __slots__ = () def currentStore(self, store_view=None): """ @@ -277,7 +277,7 @@ def create(self, product_type, attribute_set_id, sku, data): :return: INT id of product created """ return int(self.call( - 'catalog_product.create', + 'catalog_product.create', [product_type, attribute_set_id, sku, data] ) ) @@ -310,7 +310,7 @@ def setSpecialPrice(self, product, special_price=None, :return: Boolean """ return bool(self.call( - 'catalog_product.setSpecialPrice', + 'catalog_product.setSpecialPrice', [product, special_price, from_date, to_date, store_view] ) ) @@ -342,7 +342,7 @@ class ProductAttribute(API): """ Product Attribute API """ - __slots__ = ( ) + __slots__ = () def currentStore(self, store_view=None): """ @@ -390,14 +390,16 @@ def createOption(self, attribute, data): :param data: Dictionary of Data. :return: True if created. """ + print "Test Create Option" return bool(self.call('product_attribute.addOption', [attribute, data])) + class ProductAttributeSet(API): """ Product Attribute Set API """ - __slots__ = ( ) + __slots__ = () def list(self): """ @@ -405,14 +407,14 @@ def list(self): :return: `list` of `dict` """ - return self.call('catalog_product_attribute_set.list', [ ]) + return self.call('catalog_product_attribute_set.list', []) class ProductTypes(API): """ Product Types API """ - __slots__ = ( ) + __slots__ = () def list(self): """ @@ -420,14 +422,14 @@ def list(self): :return: `list` of `dict` """ - return self.call('catalog_product_type.list', [ ]) + return self.call('catalog_product_type.list', []) class ProductImages(API): """ Product Images API """ - __slots__ = ( ) + __slots__ = () def currentStore(self, store_view=None): """ @@ -436,7 +438,7 @@ def currentStore(self, store_view=None): :param store_view: Store view ID or Code :return: int """ - args = [ ] + args = [] if store_view: args = [store_view] return int(self.call('catalog_product_attribute_media.currentStore', @@ -482,7 +484,7 @@ def create(self, product, image, image_name, image_mime=None, :param product: ID or SKU of product :param image: The binary data of image - :param image_name: The name to give the image file. + :param image_name: The name to give the image file. Eg 'my_image_thumb.jpg' :param image_mime: The mime type of the image. :param store_view: Store view ID or Code @@ -534,7 +536,7 @@ class ProductTierPrice(API): """ Product Tier Price API """ - __slots__ = ( ) + __slots__ = () def info(self, product): """ @@ -576,7 +578,7 @@ class ProductLinks(API): """ Product links API (related, cross sells, up sells, grouped) """ - __slots__ = ( ) + __slots__ = () def list(self, link_type, product): """ @@ -638,7 +640,7 @@ def types(self): :return: `list` of types """ - return self.call('catalog_product_link.types', [ ]) + return self.call('catalog_product_link.types', []) def attributes(self, link_type): """ @@ -655,11 +657,12 @@ def attributes(self, link_type): """ return self.call('catalog_product_link.attributes', [link_type]) + class ProductConfigurable(API): """ Product Configurable API for magento """ - __slots__ = ( ) + __slots__ = () def info(self, product): """ @@ -677,7 +680,8 @@ def getSuperAttributes(self, product): :param product: ID or SKU of product :return: List """ - return self.call('ol_catalog_product_link.listSuperAttributes', [product]) + return self.call('ol_catalog_product_link.listSuperAttributes', + [product]) def setSuperAttributeValues(self, product, attribute): """ @@ -687,7 +691,8 @@ def setSuperAttributeValues(self, product, attribute): :param attribute: ID attribute :return: List """ - return self.call('ol_catalog_product_link.setSuperAttributeValues', [product, attribute]) + return self.call('ol_catalog_product_link.setSuperAttributeValues', + [product, attribute]) def update(self, product, linked_products, attributes): """ @@ -698,7 +703,8 @@ def update(self, product, linked_products, attributes): :param attributes: dicc :return: True/False """ - return bool(self.call('ol_catalog_product_link.assign', [product, linked_products, attributes])) + return bool(self.call('ol_catalog_product_link.assign', + [product, linked_products, attributes])) def remove(self, product, linked_products): """ @@ -707,13 +713,15 @@ def remove(self, product, linked_products): :param product: ID or SKU of product :param linked_products: List ID or SKU of linked product to unlink """ - return bool(self.call('ol_catalog_product_link.remove', [product, linked_products])) + return bool(self.call('ol_catalog_product_link.remove', + [product, linked_products])) + class Inventory(API): """ Allows to update stock attributes (status, quantity) """ - __slots__ = ( ) + __slots__ = () def list(self, products): """ @@ -736,7 +744,7 @@ def update(self, product, data): """ return bool( self.call( - 'cataloginventory_stock_item.update', + 'cataloginventory_stock_item.update', [product, data] ) ) diff --git a/magento/customer.py b/magento/customer.py index a7cd68a..b6eff8b 100644 --- a/magento/customer.py +++ b/magento/customer.py @@ -23,7 +23,7 @@ class Customer(API): with CustomerAPI(url, username, password) as customer_api: return customer_api.list() """ - __slots__ = ( ) + __slots__ = () def list(self, filters=None): """ @@ -83,7 +83,7 @@ class CustomerGroup(API): """ Customer Group API to connect to magento """ - __slots__ = ( ) + __slots__ = () def list(self): """ diff --git a/magento/directory.py b/magento/directory.py index 4213ca3..53328f4 100644 --- a/magento/directory.py +++ b/magento/directory.py @@ -15,7 +15,7 @@ class Country(API): """ Country API to connect to magento """ - __slots__ = ( ) + __slots__ = () def list(self): """ diff --git a/magento/sales.py b/magento/sales.py index f06bff1..5ecfd04 100644 --- a/magento/sales.py +++ b/magento/sales.py @@ -2,7 +2,7 @@ ''' magento.sales - Allows to export/import sales orders from/into Magento, + Allows to export/import sales orders from/into Magento, to create invoices, shipments, credit memos :copyright: (c) 2010 by Sharoon Thomas. @@ -16,7 +16,7 @@ class Order(API): """ Allows to import/export orders. """ - __slots__ = ( ) + __slots__ = () def list(self, filters=None): """ @@ -52,7 +52,7 @@ def addcomment(self, order_increment_id, TODO: Identify possible values for status """ if comment is None: - comment = u"" + comment = "" return bool(self.call( 'sales_order.addComment', [order_increment_id, status, comment, notify] @@ -91,7 +91,7 @@ class Shipment(API): """ Allows create/export order shipments. """ - __slots__ = ( ) + __slots__ = () def list(self, filters=None): """ @@ -116,7 +116,7 @@ def info(self, shipment_increment_id): """ return self.call('sales_order_shipment.info', [shipment_increment_id]) - def create(self, order_increment_id, + def create(self, order_increment_id, items_qty, comment=None, email=True, include_comment=False): """ Create new shipment for order @@ -133,7 +133,7 @@ def create(self, order_increment_id, :type include_comment: bool """ if comment is None: - comment = u'' + comment = '' return self.call( 'sales_order_shipment.create', [ order_increment_id, items_qty, comment, email, include_comment @@ -149,7 +149,7 @@ def addcomment(self, shipment_increment_id, """ return bool( self.call( - 'sales_order_shipment.addComment', + 'sales_order_shipment.addComment', [shipment_increment_id, comment, email, include_in_email] ) ) @@ -211,7 +211,7 @@ class Invoice(API): """ Allows create/export order invoices """ - __slots__ = ( ) + __slots__ = () def list(self, filters=None): """ @@ -238,7 +238,7 @@ def info(self, invoice_increment_id): 'sales_order_invoice.info', [invoice_increment_id] ) - def create(self, order_increment_id, items_qty, + def create(self, order_increment_id, items_qty, comment=None, email=True, include_comment=False): """ Create new invoice for order @@ -257,7 +257,7 @@ def create(self, order_increment_id, items_qty, :rtype: str """ return self.call( - 'sales_order_invoice.create', + 'sales_order_invoice.create', [order_increment_id, items_qty, comment, email, include_comment] ) @@ -269,7 +269,7 @@ def addcomment(self, invoice_increment_id, :param invoice_increment_id: Invoice ID """ if comment is None: - comment = u"" + comment = "" return bool( self.call( 'sales_order_invoice.addComment', @@ -284,20 +284,20 @@ def capture(self, invoice_increment_id): """ Capture Invoice - :attention: You should check the invoice to see if can be - captured before attempting to capture an invoice, otherwise + :attention: You should check the invoice to see if can be + captured before attempting to capture an invoice, otherwise the API call with generate an error. - Invoices have states as defined in the model + Invoices have states as defined in the model Mage_Sales_Model_Order_Invoice: STATE_OPEN = 1 STATE_PAID = 2 STATE_CANCELED = 3 - Also note there is a method call in the model that checks this - for you canCapture(), and it also verifies that the payment is - able to be captured, so the invoice state might not be the only + Also note there is a method call in the model that checks this + for you canCapture(), and it also verifies that the payment is + able to be captured, so the invoice state might not be the only condition that’s required to allow it to be captured. :param invoice_increment_id: Invoice ID diff --git a/magento/utils.py b/magento/utils.py index 423174e..1f78807 100644 --- a/magento/utils.py +++ b/magento/utils.py @@ -9,6 +9,7 @@ :license: AGPLv3, see LICENSE for more details ''' + def expand_url(url, protocol): """ Expands the given URL to a full URL by adding From 00c09cd3b513ff6fcd209ca2c2de5f9d574f595b Mon Sep 17 00:00:00 2001 From: resteve Date: Mon, 7 Jan 2013 12:28:37 +0100 Subject: [PATCH 08/15] Product Attribute. Remove Option --- magento/catalog.py | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/magento/catalog.py b/magento/catalog.py index 30b1ec4..5399105 100644 --- a/magento/catalog.py +++ b/magento/catalog.py @@ -384,16 +384,27 @@ def options(self, attribute, store_view=None): def createOption(self, attribute, data): """ - Create new options to attribute + Create new options to attribute (Magento > 1.7.0) :param attribute: ID or Code of the attribute. :param data: Dictionary of Data. + {'label':[{'store_id':[0,1], 'value':'Value'},], 'order':1, 'is_default':1} :return: True if created. """ - print "Test Create Option" return bool(self.call('product_attribute.addOption', [attribute, data])) + def removeOption(self, attribute, option): + """ + Remove option to attribute (Magento > 1.7.0) + + :param attribute: ID or Code of the attribute. + :param option: Option ID. + :return: True if the option is removed. + """ + return bool(self.call('product_attribute.removeOption', + [attribute, option])) + class ProductAttributeSet(API): """ From 47fdd343ec42454f5fe9dbe5ef054e66f6ce669f Mon Sep 17 00:00:00 2001 From: Matt Chisholm Date: Wed, 3 Apr 2013 17:46:02 +0200 Subject: [PATCH 09/15] change API path, this works on Magento 1.7 --- magento/catalog.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/magento/catalog.py b/magento/catalog.py index 5399105..510eb5c 100644 --- a/magento/catalog.py +++ b/magento/catalog.py @@ -370,7 +370,7 @@ def info(self, attribute): :param attribute: ID or Code of the attribute :return: `list` of `dict` """ - return self.call('ol_catalog_product_attribute.info', [attribute]) + return self.call('catalog_product_attribute.info', [attribute]) def options(self, attribute, store_view=None): """ From 89d80e3b1e51719f444f5420946b8769f76721a2 Mon Sep 17 00:00:00 2001 From: Matt Chisholm Date: Thu, 4 Apr 2013 13:00:42 +0200 Subject: [PATCH 10/15] add note about custom plugin required for ProductConfigurable --- magento/catalog.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/magento/catalog.py b/magento/catalog.py index 510eb5c..f1956cb 100644 --- a/magento/catalog.py +++ b/magento/catalog.py @@ -671,7 +671,10 @@ def attributes(self, link_type): class ProductConfigurable(API): """ - Product Configurable API for magento + Product Configurable API for magento. + + These API endpoints only work if you have zikzakmedia's + magento_webservices Magento plugin installed. """ __slots__ = () From 3cbe126fea30c30574a3321ba4101f5dcf93f6e1 Mon Sep 17 00:00:00 2001 From: Ali Date: Fri, 8 Feb 2013 15:44:42 -0800 Subject: [PATCH 11/15] fixed multicall --- magento/api.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/magento/api.py b/magento/api.py index 196731b..3d247fb 100644 --- a/magento/api.py +++ b/magento/api.py @@ -163,11 +163,11 @@ def call(self, resource_path, arguments): return self.client.service.call( self.session, resource_path, arguments) - def multiCall(self, calls, options): + def multiCall(self, calls): """ Proxy for multicalls """ if self.protocol == 'xmlrpc': - return self.client.multiCall(self.session, calls, options) + return self.client.multiCall(self.session, calls) else: - return self.client.service.multiCall(self.session, calls, options) + return self.client.service.multiCall(self.session, calls) From 728784c9971f114ba261805e3371ecd8acfbefac Mon Sep 17 00:00:00 2001 From: Matt Chisholm Date: Thu, 4 Apr 2013 18:15:02 +0200 Subject: [PATCH 12/15] Rename createOption to addOption * `createOption` is called `addOption` in Magento * deprecate `createOption` --- magento/catalog.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/magento/catalog.py b/magento/catalog.py index f1956cb..b915026 100644 --- a/magento/catalog.py +++ b/magento/catalog.py @@ -10,6 +10,7 @@ ''' import base64 +import warnings from mimetypes import guess_type from magento.api import API @@ -382,7 +383,7 @@ def options(self, attribute, store_view=None): return self.call('catalog_product_attribute.options', [attribute, store_view]) - def createOption(self, attribute, data): + def addOption(self, attribute, data): """ Create new options to attribute (Magento > 1.7.0) @@ -394,6 +395,12 @@ def createOption(self, attribute, data): return bool(self.call('product_attribute.addOption', [attribute, data])) + def createOption(self, *a, **kw): + warnings.warn( + "ProductAttribute: createOption is deprecated, use addOption instead." + ) + return self.addOption(*a, **kw) + def removeOption(self, attribute, option): """ Remove option to attribute (Magento > 1.7.0) From 49e52f2edd8fbb8a30f92534b44581d137e9bf79 Mon Sep 17 00:00:00 2001 From: Matt Chisholm Date: Thu, 4 Apr 2013 18:22:38 +0200 Subject: [PATCH 13/15] Implement ProductAttribute API * add methods for `create` and `update` * add methods for attributeAdd and attributeRemove --- magento/catalog.py | 56 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/magento/catalog.py b/magento/catalog.py index b915026..31754e3 100644 --- a/magento/catalog.py +++ b/magento/catalog.py @@ -412,6 +412,27 @@ def removeOption(self, attribute, option): return bool(self.call('product_attribute.removeOption', [attribute, option])) + def create(self, data): + """ + Create attribute entity. + + :param data: Dictionary of entity data to create attribute with. + + :return: Integer ID of attribute created + """ + return self.call('catalog_product_attribute.create', [data]) + + def update(self, attribute, data): + """ + Update attribute entity data. + + :param attribute: ID or Code of the attribute. + :param data: Dictionary of entity data to update on attribute. + + :return: Boolean + """ + return self.call('catalog_product_attribute.update', [attribute, data]) + class ProductAttributeSet(API): """ @@ -427,6 +448,41 @@ def list(self): """ return self.call('catalog_product_attribute_set.list', []) + def create(self, attribute_set_name, skeleton_set_id): + """ + Create a new attribute set based on a "skeleton" attribute set. + If unsure, use the "Default" attribute set as a skeleton. + + :param attribute_set_name: name of the new attribute set + :param skeleton_set_id: id of the skeleton attribute set to base this set on. + + :return: Integer ID of new attribute set + """ + return self.call('catalog_product_attribute_set.create', [attribute_set_name, skeleton_set_id]) + + def attributeAdd(self, attribute_id, attribute_set_id): + """ + Add an existing attribute to an attribute set. + + :param attribute_id: ID of the attribute to add + :param attribute_set_id: ID of the attribute set to add to + + :return: Boolean + """ + return self.call('catalog_product_attribute_set.attributeAdd', [attribute_id, attribute_set_id]) + + def attributeRemove(self, attribute_id, attribute_set_id): + """ + Remove an existing attribute to an attribute set. + + :param attribute_id: ID of the attribute to remove + :param attribute_set_id: ID of the attribute set to remove from + + :return: Boolean + """ + return self.call('catalog_product_attribute_set.attributeRemove', [attribute_id, attribute_set_id]) + + class ProductTypes(API): """ From cbdc743588f816d20a9f3221b9e0d9d54fc35e4f Mon Sep 17 00:00:00 2001 From: Matt Chisholm Date: Sun, 14 Apr 2013 18:47:53 +0200 Subject: [PATCH 14/15] Make ProductImage.create signature match Magento Previously this was a layering violation. There's no reason for `create` to change the argument signature of just this method, base64 encode the image, and detect its mime-type, especially if `update` does not do any of that . The calling code should be responsible for encoding and mime-type detecting in both cases, and both methods should match the Magento API. --- magento/catalog.py | 22 +++++----------------- 1 file changed, 5 insertions(+), 17 deletions(-) diff --git a/magento/catalog.py b/magento/catalog.py index 31754e3..793b7dc 100644 --- a/magento/catalog.py +++ b/magento/catalog.py @@ -9,9 +9,7 @@ :license: AGPLv3, see LICENSE for more details ''' -import base64 import warnings -from mimetypes import guess_type from magento.api import API @@ -551,28 +549,18 @@ def types(self, attribute_set_id): return self.call('catalog_product_attribute_media.types', [attribute_set_id]) - def create(self, product, image, image_name, image_mime=None, - store_view=None): + def create(self, product, data, store_view=None): """ Upload a new product image. :param product: ID or SKU of product - :param image: The binary data of image - :param image_name: The name to give the image file. - Eg 'my_image_thumb.jpg' - :param image_mime: The mime type of the image. + :param data: `dict` of image data (label, position, exclude, types) + Example: { 'label': 'description of photo', + 'position': '1', 'exclude': '0', + 'types': ['image', 'small_image', 'thumbnail']} :param store_view: Store view ID or Code :return: string - image file name """ - if image_mime is None: - image_mime = guess_type(image_name) - data = { - 'file': { - 'content': base64.b64encode(image), - 'name': image_name, - 'mime': image_mime, - } - } return self.call('catalog_product_attribute_media.create', [product, data, store_view]) From a7e0f8fc97225548577dbfd7032bce796cdf25af Mon Sep 17 00:00:00 2001 From: Sharoon Thomas Date: Thu, 25 Apr 2013 12:58:12 +0530 Subject: [PATCH 15/15] Cleanup the README file * Convert to ReST syntax * Update the code examples * Add LICENSE --- README | 38 -------------------------------------- README.rst | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 38 deletions(-) delete mode 100644 README create mode 100644 README.rst diff --git a/README b/README deleted file mode 100644 index 18cdb3c..0000000 --- a/README +++ /dev/null @@ -1,38 +0,0 @@ -Magento Python -************** - -Python library to connect Magento Webservices - -Check documentation source code - -Examples: - -from magento import * - -url = 'http://domain.com/' -apiuser = 'user' -apipass = 'password' - -"""Product""" -with Product(url, apiuser, apipass) as product_api: - ofilter = {'created_at':{'from':'2011-09-15 00:00:00'}} - products = product_api.list(ofilter) - -with ProductTypes(url, apiuser, apipass) as product_type_api: - product_type = product_type_api.list() - -with Product(url, apiuser, apipass) as product_api: - sku = 'prod1' - product = product_api.info(sku) - -"""Websites""" -with API(url, apiuser, apipass) as magento_api: - websites = magento_api.call('ol_websites.list', []) - store_group = magento_api.call('ol_groups.list', []) - store_views = magento_api.call('ol_storeviews.list', []) - -"""Order""" -with Order(url, apiuser, apipass) as order_api: - order_increment_id = '100000001 ' - status = 'canceled' - order_api.addcomment(order_increment_id, status) diff --git a/README.rst b/README.rst new file mode 100644 index 0000000..484eb84 --- /dev/null +++ b/README.rst @@ -0,0 +1,48 @@ +Magento Python API +================== + +Python library to connect to Magento Webservices. + +Check documentation source code + +Usage +----- + +.. code-block:: python + + import magento + + url = 'http://domain.com/' + apiuser = 'user' + apipass = 'password' + + with magento.Product(url, apiuser, apipass) as product_api: + order_filter = {'created_at':{'from':'2011-09-15 00:00:00'}} + products = product_api.list(order_filter) + + with magento.ProductTypes(url, apiuser, apipass) as product_type_api: + product_type = product_type_api.list() + + with magento.Product(url, apiuser, apipass) as product_api: + sku = 'prod1' + product = product_api.info(sku) + + with magento.API(url, apiuser, apipass) as magento_api: + # Calling custom APIs if you have extension modules on your + # magento installation + websites = magento_api.call('ol_websites.list', []) + store_group = magento_api.call('ol_groups.list', []) + store_views = magento_api.call('ol_storeviews.list', []) + + with magento.Order(url, apiuser, apipass) as order_api: + order_increment_id = '100000001 ' + status = 'canceled' + order_api.addcomment(order_increment_id, status) + + +License +------- + +GNU Affero General Public License version 3 + +See LICENSE for more details