Skip to content

Commit 1da77bf

Browse files
author
basti
committed
Support for operations CartCreate, CartAdd, CartModify, CartGet, CartClean added.
Be careful: something in CartModify does not quite work yet!
1 parent d8f07c7 commit 1da77bf

File tree

2,191 files changed

+119443
-17
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

2,191 files changed

+119443
-17
lines changed

amazonproduct/api.py

+265-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
from Crypto.Hash import SHA256 as sha256
1616

1717
import hmac
18-
import re
1918
import socket
2019
from time import strftime, gmtime, sleep
2120
import urllib2
@@ -416,6 +415,271 @@ def browse_node_lookup(self, browse_node_id, response_group=None, **params):
416415
# otherwise re-raise exception
417416
raise # pragma: no cover
418417

418+
def _convert_cart_items(self, items, key='ASIN'):
419+
"""
420+
Converts items into correct format for cart operations.
421+
"""
422+
result = {}
423+
# TODO ListItemId
424+
if type(items) == dict:
425+
for no, (item_id, quantity) in enumerate(items.items()):
426+
result['Item.%i.%s' % (no+1, key)] = item_id
427+
result['Item.%i.Quantity' % (no+1)] = quantity
428+
return result
429+
430+
def cart_create(self, items, **params):
431+
"""
432+
The ``CartCreate`` operation enables you to create a remote shopping
433+
cart. A shopping cart is the metaphor used by most e-commerce
434+
solutions. It is a temporary data storage structure that resides on
435+
Amazon servers. The structure contains the items a customer wants to
436+
buy. In Product Advertising API, the shopping cart is considered remote
437+
because it is hosted by Amazon servers. In this way, the cart is remote
438+
to the vendor's web site where the customer views and selects the items
439+
they want to purchase.
440+
441+
Once you add an item to a cart by specifying the item's ListItemId and
442+
ASIN, or OfferListing ID, the item is assigned a ``CartItemId`` and
443+
accessible only by that value. That is, in subsequent requests, an item
444+
in a cart cannot be accessed by its ``ListItemId`` and ``ASIN``, or
445+
``OfferListingId``. ``CartItemId`` is returned by ``CartCreate``,
446+
``CartGet``, and C``artAdd``.
447+
448+
Because the contents of a cart can change for different reasons, such
449+
as item availability, you should not keep a copy of a cart locally.
450+
Instead, use the other cart operations to modify the cart contents. For
451+
example, to retrieve contents of the cart, which are represented by
452+
CartItemIds, use ``CartGet``.
453+
454+
Available products are added as cart items. Unavailable items, for
455+
example, items out of stock, discontinued, or future releases, are
456+
added as SaveForLaterItems. No error is generated. The Amazon database
457+
changes regularly. You may find a product with an offer listing ID but
458+
by the time the item is added to the cart the product is no longer
459+
available. The checkout page in the Order Pipeline clearly lists items
460+
that are available and those that are SaveForLaterItems.
461+
462+
It is impossible to create an empty shopping cart. You have to add at
463+
least one item to a shopping cart using a single ``CartCreate``
464+
request. You can add specific quantities (up to 999) of each item.
465+
466+
``CartCreate`` can be used only once in the life cycle of a cart. To
467+
modify the contents of the cart, use one of the other cart operations.
468+
469+
Carts cannot be deleted. They expire automatically after being unused
470+
for 7 days. The lifespan of a cart restarts, however, every time a cart
471+
is modified. In this way, a cart can last for more than 7 days. If, for
472+
example, on day 6, the customer modifies a cart, the 7 day countdown
473+
starts over.
474+
"""
475+
try:
476+
params.update(self._convert_cart_items(items))
477+
return self.call(Operation='CartCreate', **params)
478+
except AWSError, e:
479+
480+
if e.code == 'AWS.MissingParameters':
481+
raise ValueError(e.msg)
482+
483+
if e.code == 'AWS.ParameterOutOfRange':
484+
raise ValueError(e.msg)
485+
486+
if e.code == 'AWS.ECommerceService.ItemNotEligibleForCart':
487+
raise InvalidCartItem(e.msg)
488+
489+
# otherwise re-raise exception
490+
raise # pragma: no cover
491+
492+
def cart_add(self, cart_id, hmac, items, **params):
493+
"""
494+
The ``CartAdd`` operation enables you to add items to an existing
495+
remote shopping cart. ``CartAdd`` can only be used to place a new item
496+
in a shopping cart. It cannot be used to increase the quantity of an
497+
item already in the cart. If you would like to increase the quantity of
498+
an item that is already in the cart, you must use the ``CartModify``
499+
operation.
500+
501+
You add an item to a cart by specifying the item's ``OfferListingId``,
502+
or ``ASIN`` and ``ListItemId``. Once in a cart, an item can only be
503+
identified by its ``CartItemId``. That is, an item in a cart cannot be
504+
accessed by its ASIN or OfferListingId. CartItemId is returned by
505+
``CartCreate``, ``CartGet``, and ``CartAdd``.
506+
507+
To add items to a cart, you must specify the cart using the ``CartId``
508+
and ``HMAC`` values, which are returned by the ``CartCreate``
509+
operation.
510+
511+
If the associated CartCreate request specified an AssociateTag, all
512+
``CartAdd`` requests must also include a value for Associate Tag
513+
otherwise the request will fail.
514+
515+
.. note:: Some manufacturers have a minimum advertised price (MAP) that
516+
can be displayed on Amazon's retail web site. In these cases, when
517+
performing a Cart operation, the MAP Is returned instead of the actual
518+
price. The only way to see the actual price is to add the item to a
519+
remote shopping cart and follow the PurchaseURL. The actual price will
520+
be the MAP or lower.
521+
"""
522+
try:
523+
params.update({
524+
'CartId' : cart_id,
525+
'HMAC' : hmac,
526+
})
527+
params.update(self._convert_cart_items(items))
528+
return self.call(Operation='CartAdd', **params)
529+
except AWSError, e:
530+
531+
if e.code == 'AWS.ECommerceService.InvalidCartId':
532+
raise InvalidCartId
533+
534+
if e.code == 'AWS.ECommerceService.CartInfoMismatch':
535+
raise CartInfoMismatch
536+
537+
if e.code == 'AWS.MissingParameters':
538+
raise ValueError(e.msg)
539+
540+
if e.code == 'AWS.ParameterOutOfRange':
541+
raise ValueError(e.msg)
542+
543+
if e.code == 'AWS.ECommerceService.ItemNotEligibleForCart':
544+
raise InvalidCartItem(e.msg)
545+
546+
if e.code == 'AWS.ECommerceService.ItemAlreadyInCart':
547+
if self.locale == 'jp': print e.msg
548+
item = self._reg('already-in-cart').search(e.msg).group('item')
549+
raise ItemAlreadyInCart(item)
550+
551+
# otherwise re-raise exception
552+
raise # pragma: no cover
553+
554+
def cart_modify(self, cart_id, hmac, items, **params):
555+
"""
556+
The ``CartModify`` operation enables you to change the quantity of
557+
items that are already in a remote shopping cart and move items from
558+
the active area of a cart to the SaveForLater area or the reverse.
559+
560+
To modify the number of items in a cart, you must specify the cart
561+
using the CartId and HMAC values that are returned in the CartCreate
562+
operation. A value similar to HMAC, URLEncodedHMAC, is also returned.
563+
This value is the URL encoded version of the HMAC. This encoding is
564+
necessary because some characters, such as + and /, cannot be included
565+
in a URL. Rather than encoding the HMAC yourself, use the
566+
URLEncodedHMAC value for the HMAC parameter.
567+
568+
You can use ``CartModify`` to modify the number of items in a remote
569+
shopping cart by setting the value of the Quantity parameter
570+
appropriately. You can eliminate an item from a cart by setting the
571+
value of the Quantity parameter to zero. Or, you can double the number
572+
of a particular item in the cart by doubling its Quantity . You cannot,
573+
however, use ``CartModify`` to add new items to a cart.
574+
575+
If the associated CartCreate request specified an AssociateTag, all
576+
``CartModify`` requests must also include a value for Associate Tag
577+
otherwise the request will fail.
578+
"""
579+
# TODO Action=SaveForLater
580+
try:
581+
params.update({
582+
'CartId' : cart_id,
583+
'HMAC' : hmac,
584+
})
585+
params.update(self._convert_cart_items(items, key='CartItemId'))
586+
return self.call(Operation='CartModify', **params)
587+
except AWSError, e:
588+
589+
if e.code == 'AWS.ECommerceService.CartInfoMismatch':
590+
raise CartInfoMismatch
591+
592+
if e.code == 'AWS.MissingParameters':
593+
raise ValueError(e.msg)
594+
595+
if e.code == 'AWS.ParameterOutOfRange':
596+
raise ValueError(e.msg)
597+
598+
if e.code == 'AWS.ECommerceService.ItemNotEligibleForCart':
599+
raise InvalidCartItem(e.msg)
600+
601+
# otherwise re-raise exception
602+
raise # pragma: no cover
603+
604+
def cart_get(self, cart_id, hmac, **params):
605+
"""
606+
The ``CartGet`` operation enables you to retrieve the IDs, quantities,
607+
and prices of all of the items, including SavedForLater items in a
608+
remote shopping cart.
609+
610+
Because the contents of a cart can change for different reasons, such
611+
as availability, you should not keep a copy of a cart locally. Instead,
612+
use ``CartGet`` to retrieve the items in a remote shopping cart.
613+
614+
To retrieve the items in a cart, you must specify the cart using the
615+
``CartId`` and ``HMAC`` values, which are returned in the
616+
``CartCreate`` operation. A value similar to HMAC, ``URLEncodedHMAC``,
617+
is also returned. This value is the URL encoded version of the
618+
``HMAC``. This encoding is necessary because some characters, such as
619+
``+`` and ``/``, cannot be included in a URL. Rather than encoding the
620+
``HMAC`` yourself, use the ``URLEncodedHMAC`` value for the HMAC
621+
parameter.
622+
623+
``CartGet`` does not work after the customer has used the
624+
``PurchaseURL`` to either purchase the items or merge them with the
625+
items in their Amazon cart.
626+
627+
If the associated ``CartCreate`` request specified an ``AssociateTag``,
628+
all ``CartGet`` requests must also include a value for ``AssociateTag``
629+
otherwise the request will fail.
630+
"""
631+
try:
632+
params.update({
633+
'CartId' : cart_id,
634+
'HMAC' : hmac,
635+
})
636+
return self.call(Operation='CartGet', **params)
637+
except AWSError, e:
638+
639+
if e.code == 'AWS.ECommerceService.CartInfoMismatch':
640+
raise CartInfoMismatch
641+
642+
# otherwise re-raise exception
643+
raise # pragma: no cover
644+
645+
def cart_clear(self, cart_id, hmac, **params):
646+
"""
647+
The ``CartClear`` operation enables you to remove all of the items in a
648+
remote shopping cart, including SavedForLater items. To remove only
649+
some of the items in a cart or to reduce the quantity of one or more
650+
items, use ``CartModify``.
651+
652+
To delete all of the items from a remote shopping cart, you must
653+
specify the cart using the ``CartId`` and ``HMAC`` values, which are
654+
returned by the ``CartCreate`` operation. A value similar to the
655+
``HMAC``, ``URLEncodedHMAC``, is also returned. This value is the URL
656+
encoded version of the ``HMAC``. This encoding is necessary because
657+
some characters, such as ``+`` and ``/``, cannot be included in a URL.
658+
Rather than encoding the ``HMAC`` yourself, use the U``RLEncodedHMAC``
659+
value for the HMAC parameter.
660+
661+
``CartClear`` does not work after the customer has used the
662+
``PurchaseURL`` to either purchase the items or merge them with the
663+
items in their Amazon cart.
664+
665+
Carts exist even though they have been emptied. The lifespan of a cart
666+
is 7 days since the last time it was acted upon. For example, if a cart
667+
created 6 days ago is modified, the cart lifespan is reset to 7 days.
668+
"""
669+
try:
670+
params.update({
671+
'CartId' : cart_id,
672+
'HMAC' : hmac,
673+
})
674+
return self.call(Operation='CartClear', **params)
675+
except AWSError, e:
676+
677+
if e.code == 'AWS.ECommerceService.CartInfoMismatch':
678+
raise CartInfoMismatch
679+
680+
# otherwise re-raise exception
681+
raise # pragma: no cover
682+
419683
def deprecated_operation(self, *args, **kwargs):
420684
"""
421685
Some operations are deprecated and will be answered with HTTP 410. To

amazonproduct/contrib/caching.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,10 @@ def _fetch(self, url):
4646

4747
if self.cache:
4848
fp = open(path, 'w+')
49-
node = xml.dom.minidom.parseString(resp.read())
50-
fp.write(node.toprettyxml())
51-
#from lxml import etree
52-
#fp.write(etree.tostring(etree.parse(resp), pretty_print=True))
49+
#node = xml.dom.minidom.parseString(resp.read())
50+
#fp.write(node.toprettyxml())
51+
from lxml import etree
52+
fp.write(etree.tostring(etree.parse(resp), pretty_print=True))
5353
fp.seek(0)
5454
return fp
5555

amazonproduct/errors.py

+37-2
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,32 @@ class InvalidOperation (Exception):
9393
The specified feature (operation) is invalid.
9494
"""
9595

96+
class InvalidCartItem (Exception):
97+
"""
98+
The item you specified, ???, is not eligible to be added to the cart. Check
99+
the item's availability to make sure it is available.
100+
"""
101+
102+
class ItemAlreadyInCart (Exception):
103+
"""
104+
The item you specified, ???, is already in your cart.
105+
"""
106+
107+
class CartInfoMismatch (Exception):
108+
"""
109+
Your request contains an invalid AssociateTag, CartId and HMAC combination.
110+
Please verify the AssociateTag, CartId, HMAC and retry.
111+
112+
Remember that all Cart operations must pass in the CartId and HMAC that were
113+
returned to you during the CartCreate operation.
114+
"""
115+
116+
class InvalidCartId (Exception):
117+
"""
118+
Your request contains an invalid value for CartId. Please check your CartId
119+
and retry your request.
120+
"""
121+
96122
DEFAULT_ERROR_REGS = {
97123
'invalid-value' : re.compile(
98124
'The value you specified for (?P<parameter>\w+) is invalid.'),
@@ -109,8 +135,11 @@ class InvalidOperation (Exception):
109135
'parameters: (?P<parameters>[\w ,]+).'),
110136

111137
'invalid-parameter-combination' : re.compile(
112-
'Your request contained a restricted parameter combination.'
113-
'\s*(?P<message>\w.*)$') # only the last bit is of interest here
138+
'Your request contained a restricted parameter combination.'
139+
'\s*(?P<message>\w.*)$'), # only the last bit is of interest here
140+
141+
'already-in-cart' : re.compile(
142+
'The item you specified, (?P<item>.*?), is already in your cart.'),
114143
}
115144

116145
JAPANESE_ERROR_REGS = {
@@ -134,5 +163,11 @@ class InvalidOperation (Exception):
134163
u'\u3059\uff1a(?P<parameters>.+)$'),
135164

136165
'invalid-parameter-combination' : re.compile('^(?P<message>.*)$'),
166+
167+
'already-in-cart' : re.compile(
168+
u'\u30ea\u30af\u30a8\u30b9\u30c8\u3067\u5546\u54c1\u3068\u3057\u3066'
169+
u'\u6307\u5b9a\u3055\u308c\u305f(?P<item>.*?)\u306f\u3001\u3059\u3067'
170+
u'\u306b\u30b7\u30e7\u30c3\u30d4\u30f3\u30b0\u30ab\u30fc\u30c8\u306e'
171+
u'\u4e2d\u306b\u5165\u3063\u3066\u3044\u307e\u3059\u3002'),
137172
}
138173

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<CartAddResponse xmlns="http://webservices.amazon.com/AWSECommerceService/2009-10-01">
2+
<OperationRequest>
3+
<HTTPHeaders>
4+
<Header Name="UserAgent" Value="python-amazon-product-api/0.2.5a2 +http://pypi.python.org/pypi/python-amazon-product-api/"/>
5+
</HTTPHeaders>
6+
<RequestId>1C7YQS0ZBKD7SB8SKXN9</RequestId>
7+
<Arguments>
8+
<Argument Name="Service" Value="AWSECommerceService"/>
9+
<Argument Name="Signature" Value="XXXXXXXXXXXXXXX"/>
10+
<Argument Name="HMAC" Value="LbWAmYX4mcMYHwSn4DSC4rwcZ4g="/>
11+
<Argument Name="Operation" Value="CartAdd"/>
12+
<Argument Name="CartId" Value="185-1888489-5106651"/>
13+
<Argument Name="AWSAccessKeyId" Value="XXXXXXXXXXXXXXX"/>
14+
<Argument Name="Version" Value="2009-10-01"/>
15+
<Argument Name="Timestamp" Value="2011-01-30T16:50:27Z"/>
16+
</Arguments>
17+
<RequestProcessingTime>0.00366497039794922</RequestProcessingTime>
18+
</OperationRequest>
19+
<Cart>
20+
<Request>
21+
<IsValid>False</IsValid>
22+
<CartAddRequest>
23+
<CartId>185-1888489-5106651</CartId>
24+
<HMAC>LbWAmYX4mcMYHwSn4DSC4rwcZ4g=</HMAC>
25+
</CartAddRequest>
26+
<Errors>
27+
<Error>
28+
<Code>AWS.MissingParameters</Code>
29+
<Message>Your request is missing required parameters. Required parameters include Items.</Message>
30+
</Error>
31+
</Errors>
32+
</Request>
33+
</Cart>
34+
</CartAddResponse>

0 commit comments

Comments
 (0)