amazon-sp-cli 0.2.3__tar.gz → 0.2.4__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_sp_cli-0.2.3/amazon_sp_cli.egg-info → amazon_sp_cli-0.2.4}/PKG-INFO +1 -1
- {amazon_sp_cli-0.2.3 → amazon_sp_cli-0.2.4}/README.md +2 -3
- amazon_sp_cli-0.2.4/amazon_sp_cli/__init__.py +2 -0
- {amazon_sp_cli-0.2.3 → amazon_sp_cli-0.2.4}/amazon_sp_cli/models/a_plus.py +23 -3
- {amazon_sp_cli-0.2.3 → amazon_sp_cli-0.2.4/amazon_sp_cli.egg-info}/PKG-INFO +1 -1
- {amazon_sp_cli-0.2.3 → amazon_sp_cli-0.2.4}/tests/test_a_plus.py +84 -1
- amazon_sp_cli-0.2.3/amazon_sp_cli/__init__.py +0 -2
- {amazon_sp_cli-0.2.3 → amazon_sp_cli-0.2.4}/LICENSE +0 -0
- {amazon_sp_cli-0.2.3 → amazon_sp_cli-0.2.4}/MANIFEST.in +0 -0
- {amazon_sp_cli-0.2.3 → amazon_sp_cli-0.2.4}/amazon_sp_cli/__main__.py +0 -0
- {amazon_sp_cli-0.2.3 → amazon_sp_cli-0.2.4}/amazon_sp_cli/auth.py +0 -0
- {amazon_sp_cli-0.2.3 → amazon_sp_cli-0.2.4}/amazon_sp_cli/cli.py +0 -0
- {amazon_sp_cli-0.2.3 → amazon_sp_cli-0.2.4}/amazon_sp_cli/client.py +0 -0
- {amazon_sp_cli-0.2.3 → amazon_sp_cli-0.2.4}/amazon_sp_cli/commands/__init__.py +0 -0
- {amazon_sp_cli-0.2.3 → amazon_sp_cli-0.2.4}/amazon_sp_cli/commands/a_plus.py +0 -0
- {amazon_sp_cli-0.2.3 → amazon_sp_cli-0.2.4}/amazon_sp_cli/commands/auth.py +0 -0
- {amazon_sp_cli-0.2.3 → amazon_sp_cli-0.2.4}/amazon_sp_cli/commands/pricing.py +0 -0
- {amazon_sp_cli-0.2.3 → amazon_sp_cli-0.2.4}/amazon_sp_cli/main.py +0 -0
- {amazon_sp_cli-0.2.3 → amazon_sp_cli-0.2.4}/amazon_sp_cli/models/__init__.py +0 -0
- {amazon_sp_cli-0.2.3 → amazon_sp_cli-0.2.4}/amazon_sp_cli.egg-info/SOURCES.txt +0 -0
- {amazon_sp_cli-0.2.3 → amazon_sp_cli-0.2.4}/amazon_sp_cli.egg-info/dependency_links.txt +0 -0
- {amazon_sp_cli-0.2.3 → amazon_sp_cli-0.2.4}/amazon_sp_cli.egg-info/entry_points.txt +0 -0
- {amazon_sp_cli-0.2.3 → amazon_sp_cli-0.2.4}/amazon_sp_cli.egg-info/requires.txt +0 -0
- {amazon_sp_cli-0.2.3 → amazon_sp_cli-0.2.4}/amazon_sp_cli.egg-info/top_level.txt +0 -0
- {amazon_sp_cli-0.2.3 → amazon_sp_cli-0.2.4}/pyproject.toml +0 -0
- {amazon_sp_cli-0.2.3 → amazon_sp_cli-0.2.4}/setup.cfg +0 -0
- {amazon_sp_cli-0.2.3 → amazon_sp_cli-0.2.4}/setup.py +0 -0
- {amazon_sp_cli-0.2.3 → amazon_sp_cli-0.2.4}/tests/__init__.py +0 -0
- {amazon_sp_cli-0.2.3 → amazon_sp_cli-0.2.4}/tests/test_auth.py +0 -0
- {amazon_sp_cli-0.2.3 → amazon_sp_cli-0.2.4}/tests/test_client.py +0 -0
- {amazon_sp_cli-0.2.3 → amazon_sp_cli-0.2.4}/tests/test_pricing.py +0 -0
|
@@ -120,10 +120,9 @@ python3 -m amazon_sp_cli get-price PAW2603190101-BLU
|
|
|
120
120
|
|
|
121
121
|
This repository uses automated releases. To publish a new version:
|
|
122
122
|
|
|
123
|
-
1. Open a **standalone PR** that only bumps `
|
|
123
|
+
1. Open a **standalone PR** that only bumps `__version__` in `amazon_sp_cli/__init__.py`.
|
|
124
124
|
2. The PR must not include code, test, or documentation changes — a CI check enforces this.
|
|
125
|
-
3. Once the PR is merged to `main`, the `Auto Release` workflow
|
|
126
|
-
4. The tag push triggers the `Publish to PyPI` workflow, which runs the full test suite and publishes the package.
|
|
125
|
+
3. Once the PR is merged to `main`, the `Auto Release` workflow runs the full test suite, creates a tag (e.g. `v0.2.1`), creates a GitHub release, and publishes to PyPI.
|
|
127
126
|
|
|
128
127
|
Do not create tags manually.
|
|
129
128
|
|
|
@@ -18,14 +18,26 @@ class TextComponent:
|
|
|
18
18
|
class ImageComponent:
|
|
19
19
|
"""Image component for A+ Content modules."""
|
|
20
20
|
|
|
21
|
-
def __init__(
|
|
21
|
+
def __init__(
|
|
22
|
+
self,
|
|
23
|
+
upload_destination_id: str,
|
|
24
|
+
image_crop: dict = None,
|
|
25
|
+
alt_text: str = None,
|
|
26
|
+
image_crop_specification: dict = None,
|
|
27
|
+
):
|
|
22
28
|
self.upload_destination_id = upload_destination_id
|
|
23
29
|
self.image_crop = image_crop
|
|
30
|
+
self.alt_text = alt_text
|
|
31
|
+
self.image_crop_specification = image_crop_specification
|
|
24
32
|
|
|
25
33
|
def to_dict(self) -> dict:
|
|
26
34
|
result = {"uploadDestinationId": self.upload_destination_id}
|
|
27
35
|
if self.image_crop:
|
|
28
36
|
result["imageCrop"] = self.image_crop
|
|
37
|
+
if self.alt_text:
|
|
38
|
+
result["altText"] = self.alt_text
|
|
39
|
+
if self.image_crop_specification:
|
|
40
|
+
result["imageCropSpecification"] = self.image_crop_specification
|
|
29
41
|
return result
|
|
30
42
|
|
|
31
43
|
|
|
@@ -166,7 +178,7 @@ class StandardCompanyLogoModule:
|
|
|
166
178
|
def to_dict(self) -> dict:
|
|
167
179
|
result = {}
|
|
168
180
|
if self.company_logo:
|
|
169
|
-
result["companyLogo"] =
|
|
181
|
+
result["companyLogo"] = self.company_logo.to_dict()
|
|
170
182
|
return result
|
|
171
183
|
|
|
172
184
|
|
|
@@ -372,7 +384,15 @@ def build_module_from_json(data: dict) -> ContentModule:
|
|
|
372
384
|
return ContentModule(
|
|
373
385
|
module_type=module_type,
|
|
374
386
|
standard_company_logo=StandardCompanyLogoModule(
|
|
375
|
-
company_logo=
|
|
387
|
+
company_logo=(
|
|
388
|
+
ImageComponent(
|
|
389
|
+
data["imageId"],
|
|
390
|
+
alt_text=data.get("altText"),
|
|
391
|
+
image_crop_specification=data.get("imageCropSpecification"),
|
|
392
|
+
)
|
|
393
|
+
if data.get("imageId")
|
|
394
|
+
else None
|
|
395
|
+
),
|
|
376
396
|
),
|
|
377
397
|
)
|
|
378
398
|
else:
|
|
@@ -113,11 +113,24 @@ class TestBuildFromJson:
|
|
|
113
113
|
data = {
|
|
114
114
|
"contentModuleType": "STANDARD_COMPANY_LOGO",
|
|
115
115
|
"imageId": "logo-123",
|
|
116
|
+
"altText": "Company Logo",
|
|
117
|
+
"imageCropSpecification": {
|
|
118
|
+
"size": {
|
|
119
|
+
"width": {"value": 600, "units": "pixels"},
|
|
120
|
+
"height": {"value": 180, "units": "pixels"},
|
|
121
|
+
},
|
|
122
|
+
"offset": {
|
|
123
|
+
"x": {"value": 0, "units": "pixels"},
|
|
124
|
+
"y": {"value": 0, "units": "pixels"},
|
|
125
|
+
},
|
|
126
|
+
},
|
|
116
127
|
}
|
|
117
128
|
mod = build_module_from_json(data)
|
|
118
129
|
assert mod.module_type == "STANDARD_COMPANY_LOGO"
|
|
119
130
|
result = mod.to_dict()
|
|
120
|
-
assert result["standardCompanyLogo"]["companyLogo"]["
|
|
131
|
+
assert result["standardCompanyLogo"]["companyLogo"]["uploadDestinationId"] == "logo-123"
|
|
132
|
+
assert result["standardCompanyLogo"]["companyLogo"]["altText"] == "Company Logo"
|
|
133
|
+
assert result["standardCompanyLogo"]["companyLogo"]["imageCropSpecification"]["size"]["width"]["value"] == 600
|
|
121
134
|
|
|
122
135
|
def test_standard_company_logo_module_to_dict_empty(self):
|
|
123
136
|
mod = StandardCompanyLogoModule()
|
|
@@ -148,6 +161,76 @@ class TestBuildFromJson:
|
|
|
148
161
|
assert result["standardComparisonTable"]["headline"]["value"] == "Compare"
|
|
149
162
|
assert result["standardComparisonTable"]["comparisonTableRows"][0]["name"] == "Feature"
|
|
150
163
|
|
|
164
|
+
def test_integration_full_document_from_json(self):
|
|
165
|
+
data = {
|
|
166
|
+
"modules": [
|
|
167
|
+
{
|
|
168
|
+
"moduleType": "STANDARD_COMPANY_LOGO",
|
|
169
|
+
"imageId": "aplus-media/sc/76a7fb65-607b-4e96-a3fa-a145d1397725.jpg",
|
|
170
|
+
"altText": "Pawified Logo",
|
|
171
|
+
"imageCropSpecification": {
|
|
172
|
+
"size": {
|
|
173
|
+
"width": {"value": 600, "units": "pixels"},
|
|
174
|
+
"height": {"value": 180, "units": "pixels"},
|
|
175
|
+
},
|
|
176
|
+
"offset": {
|
|
177
|
+
"x": {"value": 0, "units": "pixels"},
|
|
178
|
+
"y": {"value": 0, "units": "pixels"},
|
|
179
|
+
},
|
|
180
|
+
},
|
|
181
|
+
},
|
|
182
|
+
{
|
|
183
|
+
"moduleType": "STANDARD_IMAGE_TEXT",
|
|
184
|
+
"headline": "Pure Joy in Every Bite",
|
|
185
|
+
"body": "Treat your feline friend to the finest premium catnip...",
|
|
186
|
+
"imageId": "aplus-media/sc/77967e76-a03c-4514-85e1-371e7f2395d1.jpg",
|
|
187
|
+
},
|
|
188
|
+
{
|
|
189
|
+
"moduleType": "STANDARD_IMAGE_TEXT",
|
|
190
|
+
"headline": "100% Natural & Safe",
|
|
191
|
+
"body": "Made in the USA with all-natural...",
|
|
192
|
+
"imageId": "aplus-media/sc/215948ec-b306-4a0b-8491-f1342dc83f91.jpg",
|
|
193
|
+
},
|
|
194
|
+
{
|
|
195
|
+
"moduleType": "STANDARD_IMAGE_TEXT",
|
|
196
|
+
"headline": "Perfect for Playtime",
|
|
197
|
+
"body": "Each 2-pack includes convenient 5g sachets...",
|
|
198
|
+
"imageId": "aplus-media/sc/2e6493d5-e7a4-4c3a-8e47-a78e5f5b4802.jpg",
|
|
199
|
+
},
|
|
200
|
+
{
|
|
201
|
+
"moduleType": "STANDARD_IMAGE_TEXT",
|
|
202
|
+
"headline": "Premium Quality You Can Trust",
|
|
203
|
+
"body": "Pawified is committed to delivering premium pet products...",
|
|
204
|
+
"imageId": "aplus-media/sc/ef864286-0fec-4472-ad20-8b7dfee4922e.jpg",
|
|
205
|
+
},
|
|
206
|
+
]
|
|
207
|
+
}
|
|
208
|
+
doc = build_content_from_json("pawified-catnip", data)
|
|
209
|
+
assert doc.name == "pawified-catnip"
|
|
210
|
+
assert len(doc.content_module_list) == 5
|
|
211
|
+
assert doc.content_module_list[0].module_type == "STANDARD_COMPANY_LOGO"
|
|
212
|
+
assert doc.content_module_list[1].module_type == "STANDARD_IMAGE_TEXT"
|
|
213
|
+
|
|
214
|
+
result = doc.to_dict()
|
|
215
|
+
modules = result["contentModuleList"]
|
|
216
|
+
assert len(modules) == 5
|
|
217
|
+
|
|
218
|
+
logo_module = modules[0]["standardCompanyLogo"]
|
|
219
|
+
assert "image" not in logo_module["companyLogo"]
|
|
220
|
+
assert (
|
|
221
|
+
logo_module["companyLogo"]["uploadDestinationId"]
|
|
222
|
+
== "aplus-media/sc/76a7fb65-607b-4e96-a3fa-a145d1397725.jpg"
|
|
223
|
+
)
|
|
224
|
+
assert logo_module["companyLogo"]["altText"] == "Pawified Logo"
|
|
225
|
+
assert logo_module["companyLogo"]["imageCropSpecification"]["size"]["width"]["value"] == 600
|
|
226
|
+
|
|
227
|
+
for i in range(1, 5):
|
|
228
|
+
mod = modules[i]["standardImageText"]
|
|
229
|
+
assert "headline" in mod
|
|
230
|
+
assert "body" in mod
|
|
231
|
+
assert "image" in mod
|
|
232
|
+
assert mod["image"]["uploadDestinationId"].startswith("aplus-media/sc/")
|
|
233
|
+
|
|
151
234
|
|
|
152
235
|
class TestAPlusCLI:
|
|
153
236
|
@pytest.fixture
|
|
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
|