amazon-orders 5.2.0__tar.gz → 5.2.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {amazon_orders-5.2.0 → amazon_orders-5.2.1}/CHANGELOG.md +11 -1
- {amazon_orders-5.2.0/amazon_orders.egg-info → amazon_orders-5.2.1}/PKG-INFO +1 -1
- {amazon_orders-5.2.0 → amazon_orders-5.2.1/amazon_orders.egg-info}/PKG-INFO +1 -1
- {amazon_orders-5.2.0 → amazon_orders-5.2.1}/amazonorders/__init__.py +2 -1
- {amazon_orders-5.2.0 → amazon_orders-5.2.1}/amazonorders/entity/order.py +4 -0
- {amazon_orders-5.2.0 → amazon_orders-5.2.1}/amazonorders/entity/parsable.py +29 -10
- {amazon_orders-5.2.0 → amazon_orders-5.2.1}/LICENSE +0 -0
- {amazon_orders-5.2.0 → amazon_orders-5.2.1}/MANIFEST.in +0 -0
- {amazon_orders-5.2.0 → amazon_orders-5.2.1}/README.md +0 -0
- {amazon_orders-5.2.0 → amazon_orders-5.2.1}/amazon_orders.egg-info/SOURCES.txt +0 -0
- {amazon_orders-5.2.0 → amazon_orders-5.2.1}/amazon_orders.egg-info/dependency_links.txt +0 -0
- {amazon_orders-5.2.0 → amazon_orders-5.2.1}/amazon_orders.egg-info/entry_points.txt +0 -0
- {amazon_orders-5.2.0 → amazon_orders-5.2.1}/amazon_orders.egg-info/requires.txt +0 -0
- {amazon_orders-5.2.0 → amazon_orders-5.2.1}/amazon_orders.egg-info/top_level.txt +0 -0
- {amazon_orders-5.2.0 → amazon_orders-5.2.1}/amazonorders/banner.txt +0 -0
- {amazon_orders-5.2.0 → amazon_orders-5.2.1}/amazonorders/cli.py +0 -0
- {amazon_orders-5.2.0 → amazon_orders-5.2.1}/amazonorders/conf.py +0 -0
- {amazon_orders-5.2.0 → amazon_orders-5.2.1}/amazonorders/constants.py +0 -0
- {amazon_orders-5.2.0 → amazon_orders-5.2.1}/amazonorders/contrib/__init__.py +0 -0
- {amazon_orders-5.2.0 → amazon_orders-5.2.1}/amazonorders/contrib/browser/__init__.py +0 -0
- {amazon_orders-5.2.0 → amazon_orders-5.2.1}/amazonorders/contrib/browser/playwright.py +0 -0
- {amazon_orders-5.2.0 → amazon_orders-5.2.1}/amazonorders/contrib/waf/__init__.py +0 -0
- {amazon_orders-5.2.0 → amazon_orders-5.2.1}/amazonorders/contrib/waf/anticaptcha.py +0 -0
- {amazon_orders-5.2.0 → amazon_orders-5.2.1}/amazonorders/contrib/waf/base.py +0 -0
- {amazon_orders-5.2.0 → amazon_orders-5.2.1}/amazonorders/contrib/waf/capsolver.py +0 -0
- {amazon_orders-5.2.0 → amazon_orders-5.2.1}/amazonorders/contrib/waf/twocaptcha.py +0 -0
- {amazon_orders-5.2.0 → amazon_orders-5.2.1}/amazonorders/entity/__init__.py +0 -0
- {amazon_orders-5.2.0 → amazon_orders-5.2.1}/amazonorders/entity/family_member.py +0 -0
- {amazon_orders-5.2.0 → amazon_orders-5.2.1}/amazonorders/entity/gift_card_activity.py +0 -0
- {amazon_orders-5.2.0 → amazon_orders-5.2.1}/amazonorders/entity/invoice.py +0 -0
- {amazon_orders-5.2.0 → amazon_orders-5.2.1}/amazonorders/entity/item.py +0 -0
- {amazon_orders-5.2.0 → amazon_orders-5.2.1}/amazonorders/entity/order_search_result.py +0 -0
- {amazon_orders-5.2.0 → amazon_orders-5.2.1}/amazonorders/entity/prime_payment.py +0 -0
- {amazon_orders-5.2.0 → amazon_orders-5.2.1}/amazonorders/entity/recipient.py +0 -0
- {amazon_orders-5.2.0 → amazon_orders-5.2.1}/amazonorders/entity/seller.py +0 -0
- {amazon_orders-5.2.0 → amazon_orders-5.2.1}/amazonorders/entity/shipment.py +0 -0
- {amazon_orders-5.2.0 → amazon_orders-5.2.1}/amazonorders/entity/tracking.py +0 -0
- {amazon_orders-5.2.0 → amazon_orders-5.2.1}/amazonorders/entity/transaction.py +0 -0
- {amazon_orders-5.2.0 → amazon_orders-5.2.1}/amazonorders/exception.py +0 -0
- {amazon_orders-5.2.0 → amazon_orders-5.2.1}/amazonorders/forms.py +0 -0
- {amazon_orders-5.2.0 → amazon_orders-5.2.1}/amazonorders/gift_cards.py +0 -0
- {amazon_orders-5.2.0 → amazon_orders-5.2.1}/amazonorders/orders.py +0 -0
- {amazon_orders-5.2.0 → amazon_orders-5.2.1}/amazonorders/output.py +0 -0
- {amazon_orders-5.2.0 → amazon_orders-5.2.1}/amazonorders/paging.py +0 -0
- {amazon_orders-5.2.0 → amazon_orders-5.2.1}/amazonorders/prime.py +0 -0
- {amazon_orders-5.2.0 → amazon_orders-5.2.1}/amazonorders/py.typed +0 -0
- {amazon_orders-5.2.0 → amazon_orders-5.2.1}/amazonorders/region_data.py +0 -0
- {amazon_orders-5.2.0 → amazon_orders-5.2.1}/amazonorders/selectors.py +0 -0
- {amazon_orders-5.2.0 → amazon_orders-5.2.1}/amazonorders/session.py +0 -0
- {amazon_orders-5.2.0 → amazon_orders-5.2.1}/amazonorders/transactions.py +0 -0
- {amazon_orders-5.2.0 → amazon_orders-5.2.1}/amazonorders/util.py +0 -0
- {amazon_orders-5.2.0 → amazon_orders-5.2.1}/pyproject.toml +0 -0
- {amazon_orders-5.2.0 → amazon_orders-5.2.1}/setup.cfg +0 -0
- {amazon_orders-5.2.0 → amazon_orders-5.2.1}/tests/testcase.py +0 -0
|
@@ -4,7 +4,17 @@ All notable changes to this project will be documented in this file.
|
|
|
4
4
|
|
|
5
5
|
This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
6
|
|
|
7
|
-
## [Unreleased](https://github.com/alexdlaird/amazon-orders/compare/5.2.
|
|
7
|
+
## [Unreleased](https://github.com/alexdlaird/amazon-orders/compare/5.2.1...HEAD)
|
|
8
|
+
|
|
9
|
+
## [5.2.1](https://github.com/alexdlaird/amazon-orders/compare/5.2.0...5.2.1) - 2026-10-31
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- `parse_failures` on every entity, the fields that failed to parse and were left `None`, to tell them apart from fields that are `None` by design.
|
|
14
|
+
|
|
15
|
+
### Changed
|
|
16
|
+
|
|
17
|
+
- `safe_simple_parse()`'s warning names the selector that failed, instead of `simple_parse`.
|
|
8
18
|
|
|
9
19
|
## [5.2.0](https://github.com/alexdlaird/amazon-orders/compare/5.1.0...5.2.0) - 2026-10-25
|
|
10
20
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: amazon-orders
|
|
3
|
-
Version: 5.2.
|
|
3
|
+
Version: 5.2.1
|
|
4
4
|
Summary: A Python library (and CLI) for Amazon order history, line items, and transactions
|
|
5
5
|
Author-email: Alex Laird <contact@alexlaird.com>
|
|
6
6
|
Maintainer-email: Alex Laird <contact@alexlaird.com>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: amazon-orders
|
|
3
|
-
Version: 5.2.
|
|
3
|
+
Version: 5.2.1
|
|
4
4
|
Summary: A Python library (and CLI) for Amazon order history, line items, and transactions
|
|
5
5
|
Author-email: Alex Laird <contact@alexlaird.com>
|
|
6
6
|
Maintainer-email: Alex Laird <contact@alexlaird.com>
|
|
@@ -38,6 +38,10 @@ class Order(Parsable):
|
|
|
38
38
|
order_number: Optional[str] = None) -> None:
|
|
39
39
|
super().__init__(parsed, config)
|
|
40
40
|
|
|
41
|
+
if clone:
|
|
42
|
+
# Fields copied from the clone keep its failures; fields parsed again here clear their own
|
|
43
|
+
self.parse_failures = list(clone.parse_failures)
|
|
44
|
+
|
|
41
45
|
#: If the Orders full details were populated from its details page.
|
|
42
46
|
self.full_details: bool = full_details
|
|
43
47
|
|
|
@@ -3,7 +3,7 @@ __license__ = "MIT"
|
|
|
3
3
|
|
|
4
4
|
import logging
|
|
5
5
|
from datetime import date
|
|
6
|
-
from typing import Any, Callable, Dict, Optional, Type, Union
|
|
6
|
+
from typing import Any, Callable, Dict, List, Optional, Type, Union
|
|
7
7
|
|
|
8
8
|
from bs4 import Tag
|
|
9
9
|
|
|
@@ -14,6 +14,17 @@ from amazonorders.exception import AmazonOrdersEntityError, AmazonOrdersError
|
|
|
14
14
|
logger = logging.getLogger(__name__)
|
|
15
15
|
|
|
16
16
|
|
|
17
|
+
def _field_name(parse_function: Callable[..., Any],
|
|
18
|
+
kwargs: Dict[str, Any]) -> str:
|
|
19
|
+
"""
|
|
20
|
+
The name a field's parse failure is logged and recorded under: the field, or for ``simple_parse`` its selector.
|
|
21
|
+
"""
|
|
22
|
+
if parse_function.__name__ != "simple_parse":
|
|
23
|
+
return parse_function.__name__.split("_parse_")[1]
|
|
24
|
+
selector = kwargs.get("selector", "")
|
|
25
|
+
return selector if isinstance(selector, str) else ", ".join(selector)
|
|
26
|
+
|
|
27
|
+
|
|
17
28
|
class Parsable:
|
|
18
29
|
"""
|
|
19
30
|
A base class that contains a parsed representation of the entity, which can be extended to build an entity that
|
|
@@ -27,6 +38,9 @@ class Parsable:
|
|
|
27
38
|
self.parsed: Tag = parsed
|
|
28
39
|
#: The config to use.
|
|
29
40
|
self.config: AmazonOrdersConfig = config
|
|
41
|
+
#: The fields :func:`safe_parse` could not parse and left ``None`` (the selector, for
|
|
42
|
+
#: :func:`safe_simple_parse`), so a failed field can be told apart from one that is ``None`` by design.
|
|
43
|
+
self.parse_failures: List[str] = []
|
|
30
44
|
|
|
31
45
|
def __getstate__(self) -> Dict:
|
|
32
46
|
state = self.__dict__.copy()
|
|
@@ -38,7 +52,7 @@ class Parsable:
|
|
|
38
52
|
"""
|
|
39
53
|
Serialize the entity to a ``dict`` of primitives, suitable for JSON, YAML, or CSV output.
|
|
40
54
|
Nested entities and lists of them are converted recursively, dates become ISO 8601 strings,
|
|
41
|
-
and the parsed ``Tag
|
|
55
|
+
and the parsed ``Tag``, the config, and ``parse_failures`` are omitted.
|
|
42
56
|
|
|
43
57
|
:param exclude_none: Leave out fields whose value is ``None``, in nested entities too. Only ``None`` is left
|
|
44
58
|
out: ``False``, ``0``, and empty lists are values.
|
|
@@ -46,7 +60,7 @@ class Parsable:
|
|
|
46
60
|
"""
|
|
47
61
|
serialized: Dict[str, Any] = {}
|
|
48
62
|
for field, value in vars(self).items():
|
|
49
|
-
if field in ["parsed", "config"] or (exclude_none and value is None):
|
|
63
|
+
if field in ["parsed", "config", "parse_failures"] or (exclude_none and value is None):
|
|
50
64
|
continue
|
|
51
65
|
|
|
52
66
|
if isinstance(value, Parsable):
|
|
@@ -66,7 +80,8 @@ class Parsable:
|
|
|
66
80
|
**kwargs: Any) -> Any:
|
|
67
81
|
"""
|
|
68
82
|
Execute the given parse function on a field, handling any common parse exceptions and passing
|
|
69
|
-
them as warnings to the logger (suppressing them as exceptions).
|
|
83
|
+
them as warnings to the logger (suppressing them as exceptions). A field that fails is listed in
|
|
84
|
+
:attr:`parse_failures` until it parses.
|
|
70
85
|
|
|
71
86
|
:param parse_function: The parse function to attempt safe execution.
|
|
72
87
|
:param kwargs: The ``kwargs`` will be passed to ``parse_function``.
|
|
@@ -76,19 +91,23 @@ class Parsable:
|
|
|
76
91
|
raise AmazonOrdersError("The name of the \"parse_function\" passed to this method must start with "
|
|
77
92
|
"\"_parse_\".")
|
|
78
93
|
|
|
94
|
+
field = _field_name(parse_function, kwargs)
|
|
79
95
|
try:
|
|
80
|
-
|
|
96
|
+
value = parse_function(**kwargs)
|
|
81
97
|
except (AttributeError, IndexError, ValueError, TypeError, RecursionError):
|
|
82
|
-
function = "simple_parse"
|
|
83
|
-
if parse_function.__name__ != function:
|
|
84
|
-
function = parse_function.__name__.split("_parse_")[1]
|
|
85
98
|
logger.warning(
|
|
86
|
-
"When building {name}, `{
|
|
99
|
+
"When building {name}, `{field}` "
|
|
87
100
|
"could not be parsed.".format(name=self.__class__.__name__,
|
|
88
|
-
|
|
101
|
+
field=field),
|
|
89
102
|
exc_info=True)
|
|
103
|
+
if field not in self.parse_failures:
|
|
104
|
+
self.parse_failures.append(field)
|
|
90
105
|
return None
|
|
91
106
|
|
|
107
|
+
if field in self.parse_failures:
|
|
108
|
+
self.parse_failures.remove(field)
|
|
109
|
+
return value
|
|
110
|
+
|
|
92
111
|
def simple_parse(self,
|
|
93
112
|
selector: Union[str, list],
|
|
94
113
|
attr_name: Optional[str] = None,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|