etsy-python 1.0.20__tar.gz → 1.1.0__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.
- etsy_python-1.1.0/MANIFEST.in +13 -0
- {etsy_python-1.0.20 → etsy_python-1.1.0}/PKG-INFO +50 -16
- {etsy_python-1.0.20 → etsy_python-1.1.0}/README.md +49 -15
- {etsy_python-1.0.20 → etsy_python-1.1.0}/etsy_python/_version.py +1 -1
- {etsy_python-1.0.20 → etsy_python-1.1.0}/etsy_python/v3/common/Utils.py +9 -7
- etsy_python-1.1.0/etsy_python/v3/enums/HolidayPreferences.py +42 -0
- {etsy_python-1.0.20 → etsy_python-1.1.0}/etsy_python/v3/enums/Listing.py +12 -4
- etsy_python-1.1.0/etsy_python/v3/enums/ProcessingProfile.py +11 -0
- {etsy_python-1.0.20 → etsy_python-1.1.0}/etsy_python/v3/enums/ShippingProfile.py +2 -2
- {etsy_python-1.0.20 → etsy_python-1.1.0}/etsy_python/v3/models/Listing.py +21 -1
- etsy_python-1.1.0/etsy_python/v3/models/ProcessingProfile.py +61 -0
- {etsy_python-1.0.20 → etsy_python-1.1.0}/etsy_python/v3/models/Request.py +2 -1
- {etsy_python-1.0.20 → etsy_python-1.1.0}/etsy_python/v3/models/ShippingProfile.py +11 -5
- {etsy_python-1.0.20 → etsy_python-1.1.0}/etsy_python/v3/resources/HolidayPreferences.py +1 -1
- {etsy_python-1.0.20 → etsy_python-1.1.0}/etsy_python/v3/resources/Listing.py +94 -27
- {etsy_python-1.0.20 → etsy_python-1.1.0}/etsy_python/v3/resources/ListingInventory.py +8 -4
- {etsy_python-1.0.20 → etsy_python-1.1.0}/etsy_python/v3/resources/ListingOffering.py +5 -3
- {etsy_python-1.0.20 → etsy_python-1.1.0}/etsy_python/v3/resources/ListingProduct.py +5 -3
- {etsy_python-1.0.20 → etsy_python-1.1.0}/etsy_python/v3/resources/Payment.py +18 -5
- {etsy_python-1.0.20 → etsy_python-1.1.0}/etsy_python/v3/resources/PaymentLedgerEntry.py +2 -2
- etsy_python-1.1.0/etsy_python/v3/resources/ProcessingProfile.py +56 -0
- {etsy_python-1.0.20 → etsy_python-1.1.0}/etsy_python/v3/resources/Receipt.py +14 -6
- etsy_python-1.1.0/etsy_python/v3/resources/ReceiptTransactions.py +52 -0
- {etsy_python-1.0.20 → etsy_python-1.1.0}/etsy_python/v3/resources/Review.py +4 -4
- {etsy_python-1.0.20 → etsy_python-1.1.0}/etsy_python/v3/resources/Session.py +2 -2
- {etsy_python-1.0.20 → etsy_python-1.1.0}/etsy_python/v3/resources/ShippingProfile.py +20 -5
- {etsy_python-1.0.20 → etsy_python-1.1.0}/etsy_python/v3/resources/Shop.py +2 -2
- {etsy_python-1.0.20 → etsy_python-1.1.0}/etsy_python/v3/resources/UserAddress.py +2 -2
- {etsy_python-1.0.20 → etsy_python-1.1.0}/etsy_python/v3/resources/__init__.py +2 -0
- {etsy_python-1.0.20 → etsy_python-1.1.0}/etsy_python.egg-info/PKG-INFO +50 -16
- {etsy_python-1.0.20 → etsy_python-1.1.0}/etsy_python.egg-info/SOURCES.txt +5 -2
- {etsy_python-1.0.20 → etsy_python-1.1.0}/setup.py +1 -1
- etsy_python-1.0.20/etsy_python/v3/enums/HolidayPreferences.py +0 -41
- etsy_python-1.0.20/etsy_python/v3/resources/ReceiptTransactions.py +0 -37
- etsy_python-1.0.20/etsy_python/v3/tests/__init__.py +0 -0
- {etsy_python-1.0.20 → etsy_python-1.1.0}/LICENSE +0 -0
- {etsy_python-1.0.20 → etsy_python-1.1.0}/etsy_python/__init__.py +0 -0
- {etsy_python-1.0.20 → etsy_python-1.1.0}/etsy_python/v3/__init__.py +0 -0
- {etsy_python-1.0.20 → etsy_python-1.1.0}/etsy_python/v3/auth/OAuth.py +0 -0
- {etsy_python-1.0.20 → etsy_python-1.1.0}/etsy_python/v3/auth/__init__.py +0 -0
- {etsy_python-1.0.20 → etsy_python-1.1.0}/etsy_python/v3/common/Env.py +0 -0
- {etsy_python-1.0.20 → etsy_python-1.1.0}/etsy_python/v3/common/Request.py +0 -0
- {etsy_python-1.0.20 → etsy_python-1.1.0}/etsy_python/v3/common/__init__.py +0 -0
- {etsy_python-1.0.20 → etsy_python-1.1.0}/etsy_python/v3/enums/Language.py +0 -0
- {etsy_python-1.0.20 → etsy_python-1.1.0}/etsy_python/v3/enums/ListingInventory.py +0 -0
- {etsy_python-1.0.20 → etsy_python-1.1.0}/etsy_python/v3/enums/ShopReceipt.py +0 -0
- {etsy_python-1.0.20 → etsy_python-1.1.0}/etsy_python/v3/enums/__init__.py +0 -0
- {etsy_python-1.0.20 → etsy_python-1.1.0}/etsy_python/v3/exceptions/BaseAPIException.py +0 -0
- {etsy_python-1.0.20 → etsy_python-1.1.0}/etsy_python/v3/exceptions/RequestException.py +0 -0
- {etsy_python-1.0.20 → etsy_python-1.1.0}/etsy_python/v3/exceptions/__init__.py +0 -0
- {etsy_python-1.0.20 → etsy_python-1.1.0}/etsy_python/v3/models/FileRequest.py +0 -0
- {etsy_python-1.0.20 → etsy_python-1.1.0}/etsy_python/v3/models/HolidayPreferences.py +0 -0
- {etsy_python-1.0.20 → etsy_python-1.1.0}/etsy_python/v3/models/Miscellaneous.py +0 -0
- {etsy_python-1.0.20 → etsy_python-1.1.0}/etsy_python/v3/models/Product.py +0 -0
- {etsy_python-1.0.20 → etsy_python-1.1.0}/etsy_python/v3/models/Receipt.py +0 -0
- {etsy_python-1.0.20 → etsy_python-1.1.0}/etsy_python/v3/models/Shop.py +0 -0
- {etsy_python-1.0.20 → etsy_python-1.1.0}/etsy_python/v3/models/ShopReturnPolicy.py +0 -0
- {etsy_python-1.0.20 → etsy_python-1.1.0}/etsy_python/v3/models/Utils.py +0 -0
- {etsy_python-1.0.20 → etsy_python-1.1.0}/etsy_python/v3/models/__init__.py +0 -0
- {etsy_python-1.0.20 → etsy_python-1.1.0}/etsy_python/v3/resources/ListingFile.py +0 -0
- {etsy_python-1.0.20 → etsy_python-1.1.0}/etsy_python/v3/resources/ListingImage.py +0 -0
- {etsy_python-1.0.20 → etsy_python-1.1.0}/etsy_python/v3/resources/ListingTranslation.py +0 -0
- {etsy_python-1.0.20 → etsy_python-1.1.0}/etsy_python/v3/resources/ListingVariationImages.py +0 -0
- {etsy_python-1.0.20 → etsy_python-1.1.0}/etsy_python/v3/resources/ListingVideo.py +0 -0
- {etsy_python-1.0.20 → etsy_python-1.1.0}/etsy_python/v3/resources/Miscellaneous.py +0 -0
- {etsy_python-1.0.20 → etsy_python-1.1.0}/etsy_python/v3/resources/Response.py +0 -0
- {etsy_python-1.0.20 → etsy_python-1.1.0}/etsy_python/v3/resources/ShopProductionPartner.py +0 -0
- {etsy_python-1.0.20 → etsy_python-1.1.0}/etsy_python/v3/resources/ShopReturnPolicy.py +0 -0
- {etsy_python-1.0.20 → etsy_python-1.1.0}/etsy_python/v3/resources/ShopSection.py +0 -0
- {etsy_python-1.0.20 → etsy_python-1.1.0}/etsy_python/v3/resources/Taxonomy.py +0 -0
- {etsy_python-1.0.20 → etsy_python-1.1.0}/etsy_python/v3/resources/User.py +0 -0
- {etsy_python-1.0.20 → etsy_python-1.1.0}/etsy_python/v3/resources/enums/RateLimit.py +0 -0
- {etsy_python-1.0.20 → etsy_python-1.1.0}/etsy_python/v3/resources/enums/Request.py +0 -0
- {etsy_python-1.0.20 → etsy_python-1.1.0}/etsy_python/v3/resources/enums/__init__.py +0 -0
- {etsy_python-1.0.20 → etsy_python-1.1.0}/etsy_python.egg-info/dependency_links.txt +0 -0
- {etsy_python-1.0.20 → etsy_python-1.1.0}/etsy_python.egg-info/requires.txt +0 -0
- {etsy_python-1.0.20 → etsy_python-1.1.0}/etsy_python.egg-info/top_level.txt +0 -0
- {etsy_python-1.0.20 → etsy_python-1.1.0}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: etsy-python
|
|
3
|
-
Version: 1.0
|
|
3
|
+
Version: 1.1.0
|
|
4
4
|
Summary: Etsy API Client Library for Python
|
|
5
5
|
Author: Amit Ray
|
|
6
6
|
Author-email: mail@amitray.dev
|
|
@@ -328,19 +328,25 @@ The SDK provides comprehensive coverage of Etsy API v3 resources:
|
|
|
328
328
|
- **Listing** - Create, read, update, delete listings
|
|
329
329
|
- **Shop** - Manage shop information and settings
|
|
330
330
|
- **Receipt** - Handle orders and transactions
|
|
331
|
+
- **ReceiptTransactions** - Individual transaction details
|
|
331
332
|
- **User** - User profiles and addresses
|
|
332
|
-
- **
|
|
333
|
+
- **UserAddress** - User address management
|
|
334
|
+
- **ShippingProfile** - Configure shipping options and destinations
|
|
333
335
|
|
|
334
336
|
### Media Resources
|
|
335
337
|
|
|
336
338
|
- **ListingImage** - Upload and manage listing images
|
|
337
339
|
- **ListingVideo** - Upload and manage listing videos
|
|
338
340
|
- **ListingFile** - Digital file management
|
|
341
|
+
- **ListingVariationImages** - Variation-specific images
|
|
339
342
|
|
|
340
343
|
### Commerce Resources
|
|
341
344
|
|
|
342
345
|
- **ListingInventory** - Stock and SKU management
|
|
343
|
-
- **
|
|
346
|
+
- **ListingOffering** - Product offering details
|
|
347
|
+
- **ListingProduct** - Product variant management
|
|
348
|
+
- **Payment** - Payment processing
|
|
349
|
+
- **PaymentLedgerEntry** - Payment ledger entries
|
|
344
350
|
- **Review** - Customer reviews management
|
|
345
351
|
|
|
346
352
|
### Shop Management
|
|
@@ -348,6 +354,14 @@ The SDK provides comprehensive coverage of Etsy API v3 resources:
|
|
|
348
354
|
- **ShopSection** - Organize listings into sections
|
|
349
355
|
- **ShopReturnPolicy** - Define return policies
|
|
350
356
|
- **ShopProductionPartner** - Manage production partners
|
|
357
|
+
- **HolidayPreferences** - Shop holiday schedule
|
|
358
|
+
- **ProcessingProfile** - Processing time profiles
|
|
359
|
+
|
|
360
|
+
### Taxonomy & Translation
|
|
361
|
+
|
|
362
|
+
- **BuyerTaxonomy** / **SellerTaxonomy** - Product categories and attributes
|
|
363
|
+
- **ListingTranslation** - Listing localization
|
|
364
|
+
- **Miscellaneous** - Ping and other utility endpoints
|
|
351
365
|
|
|
352
366
|
## Error Handling
|
|
353
367
|
|
|
@@ -383,16 +397,24 @@ export ETSY_ENV=PROD
|
|
|
383
397
|
```
|
|
384
398
|
etsy-python-sdk/
|
|
385
399
|
├── etsy_python/
|
|
400
|
+
│ ├── _version.py # Single source of truth for version
|
|
386
401
|
│ └── v3/
|
|
387
|
-
│ ├── auth/
|
|
388
|
-
│ ├── common/
|
|
389
|
-
│ ├── enums/
|
|
390
|
-
│ ├── exceptions/
|
|
391
|
-
│ ├── models/
|
|
392
|
-
│ └── resources/
|
|
393
|
-
├──
|
|
394
|
-
|
|
395
|
-
|
|
402
|
+
│ ├── auth/ # OAuth 2.0 PKCE authentication
|
|
403
|
+
│ ├── common/ # Shared utilities and HTTP constants
|
|
404
|
+
│ ├── enums/ # Type-safe API parameter constants
|
|
405
|
+
│ ├── exceptions/ # Custom exceptions with rate limit info
|
|
406
|
+
│ ├── models/ # Request data models with validation
|
|
407
|
+
│ └── resources/ # ~28 API endpoint resource classes
|
|
408
|
+
├── tests/ # pytest test suite
|
|
409
|
+
│ └── fixtures/ # Shared test fixtures and mock responses
|
|
410
|
+
├── scripts/ # Maintenance and release scripts
|
|
411
|
+
├── specs/ # OAS spec files and audit reports
|
|
412
|
+
├── .github/
|
|
413
|
+
│ ├── workflows/ # CI/CD and PR automation
|
|
414
|
+
│ └── CODEOWNERS # Required reviewers for sensitive files
|
|
415
|
+
├── setup.py # Package configuration
|
|
416
|
+
├── requirements-dev.txt # Development/testing dependencies
|
|
417
|
+
└── README.md # Documentation
|
|
396
418
|
```
|
|
397
419
|
|
|
398
420
|
## Contributing
|
|
@@ -459,16 +481,28 @@ python scripts/release.py patch --no-push
|
|
|
459
481
|
4. Install dependencies:
|
|
460
482
|
```bash
|
|
461
483
|
pip install -r etsy_python/requirements.txt
|
|
484
|
+
pip install -r requirements-dev.txt
|
|
485
|
+
```
|
|
486
|
+
5. Run the test suite:
|
|
487
|
+
```bash
|
|
488
|
+
pytest -v
|
|
489
|
+
pytest --cov=etsy_python --cov-report=term-missing
|
|
462
490
|
```
|
|
463
|
-
|
|
491
|
+
6. Create a feature branch:
|
|
464
492
|
```bash
|
|
465
493
|
git checkout -b feature/your-feature-name
|
|
466
494
|
```
|
|
467
|
-
|
|
495
|
+
7. Make your changes and commit:
|
|
468
496
|
```bash
|
|
469
|
-
git commit -m "
|
|
497
|
+
git commit -m "feat: add your feature"
|
|
470
498
|
```
|
|
471
|
-
|
|
499
|
+
8. Push and create a pull request
|
|
500
|
+
|
|
501
|
+
### CI on Pull Requests
|
|
502
|
+
|
|
503
|
+
Pull requests automatically trigger:
|
|
504
|
+
- **pr-tests.yml** — Runs the full test suite with coverage reporting (posts/updates a comment on the PR)
|
|
505
|
+
- **pr-coverage.yml** — SDK coverage audit against the Etsy OAS spec (triggered by the `sdk-check` label)
|
|
472
506
|
|
|
473
507
|
## Support
|
|
474
508
|
|
|
@@ -307,19 +307,25 @@ The SDK provides comprehensive coverage of Etsy API v3 resources:
|
|
|
307
307
|
- **Listing** - Create, read, update, delete listings
|
|
308
308
|
- **Shop** - Manage shop information and settings
|
|
309
309
|
- **Receipt** - Handle orders and transactions
|
|
310
|
+
- **ReceiptTransactions** - Individual transaction details
|
|
310
311
|
- **User** - User profiles and addresses
|
|
311
|
-
- **
|
|
312
|
+
- **UserAddress** - User address management
|
|
313
|
+
- **ShippingProfile** - Configure shipping options and destinations
|
|
312
314
|
|
|
313
315
|
### Media Resources
|
|
314
316
|
|
|
315
317
|
- **ListingImage** - Upload and manage listing images
|
|
316
318
|
- **ListingVideo** - Upload and manage listing videos
|
|
317
319
|
- **ListingFile** - Digital file management
|
|
320
|
+
- **ListingVariationImages** - Variation-specific images
|
|
318
321
|
|
|
319
322
|
### Commerce Resources
|
|
320
323
|
|
|
321
324
|
- **ListingInventory** - Stock and SKU management
|
|
322
|
-
- **
|
|
325
|
+
- **ListingOffering** - Product offering details
|
|
326
|
+
- **ListingProduct** - Product variant management
|
|
327
|
+
- **Payment** - Payment processing
|
|
328
|
+
- **PaymentLedgerEntry** - Payment ledger entries
|
|
323
329
|
- **Review** - Customer reviews management
|
|
324
330
|
|
|
325
331
|
### Shop Management
|
|
@@ -327,6 +333,14 @@ The SDK provides comprehensive coverage of Etsy API v3 resources:
|
|
|
327
333
|
- **ShopSection** - Organize listings into sections
|
|
328
334
|
- **ShopReturnPolicy** - Define return policies
|
|
329
335
|
- **ShopProductionPartner** - Manage production partners
|
|
336
|
+
- **HolidayPreferences** - Shop holiday schedule
|
|
337
|
+
- **ProcessingProfile** - Processing time profiles
|
|
338
|
+
|
|
339
|
+
### Taxonomy & Translation
|
|
340
|
+
|
|
341
|
+
- **BuyerTaxonomy** / **SellerTaxonomy** - Product categories and attributes
|
|
342
|
+
- **ListingTranslation** - Listing localization
|
|
343
|
+
- **Miscellaneous** - Ping and other utility endpoints
|
|
330
344
|
|
|
331
345
|
## Error Handling
|
|
332
346
|
|
|
@@ -362,16 +376,24 @@ export ETSY_ENV=PROD
|
|
|
362
376
|
```
|
|
363
377
|
etsy-python-sdk/
|
|
364
378
|
├── etsy_python/
|
|
379
|
+
│ ├── _version.py # Single source of truth for version
|
|
365
380
|
│ └── v3/
|
|
366
|
-
│ ├── auth/
|
|
367
|
-
│ ├── common/
|
|
368
|
-
│ ├── enums/
|
|
369
|
-
│ ├── exceptions/
|
|
370
|
-
│ ├── models/
|
|
371
|
-
│ └── resources/
|
|
372
|
-
├──
|
|
373
|
-
|
|
374
|
-
|
|
381
|
+
│ ├── auth/ # OAuth 2.0 PKCE authentication
|
|
382
|
+
│ ├── common/ # Shared utilities and HTTP constants
|
|
383
|
+
│ ├── enums/ # Type-safe API parameter constants
|
|
384
|
+
│ ├── exceptions/ # Custom exceptions with rate limit info
|
|
385
|
+
│ ├── models/ # Request data models with validation
|
|
386
|
+
│ └── resources/ # ~28 API endpoint resource classes
|
|
387
|
+
├── tests/ # pytest test suite
|
|
388
|
+
│ └── fixtures/ # Shared test fixtures and mock responses
|
|
389
|
+
├── scripts/ # Maintenance and release scripts
|
|
390
|
+
├── specs/ # OAS spec files and audit reports
|
|
391
|
+
├── .github/
|
|
392
|
+
│ ├── workflows/ # CI/CD and PR automation
|
|
393
|
+
│ └── CODEOWNERS # Required reviewers for sensitive files
|
|
394
|
+
├── setup.py # Package configuration
|
|
395
|
+
├── requirements-dev.txt # Development/testing dependencies
|
|
396
|
+
└── README.md # Documentation
|
|
375
397
|
```
|
|
376
398
|
|
|
377
399
|
## Contributing
|
|
@@ -438,16 +460,28 @@ python scripts/release.py patch --no-push
|
|
|
438
460
|
4. Install dependencies:
|
|
439
461
|
```bash
|
|
440
462
|
pip install -r etsy_python/requirements.txt
|
|
463
|
+
pip install -r requirements-dev.txt
|
|
464
|
+
```
|
|
465
|
+
5. Run the test suite:
|
|
466
|
+
```bash
|
|
467
|
+
pytest -v
|
|
468
|
+
pytest --cov=etsy_python --cov-report=term-missing
|
|
441
469
|
```
|
|
442
|
-
|
|
470
|
+
6. Create a feature branch:
|
|
443
471
|
```bash
|
|
444
472
|
git checkout -b feature/your-feature-name
|
|
445
473
|
```
|
|
446
|
-
|
|
474
|
+
7. Make your changes and commit:
|
|
447
475
|
```bash
|
|
448
|
-
git commit -m "
|
|
476
|
+
git commit -m "feat: add your feature"
|
|
449
477
|
```
|
|
450
|
-
|
|
478
|
+
8. Push and create a pull request
|
|
479
|
+
|
|
480
|
+
### CI on Pull Requests
|
|
481
|
+
|
|
482
|
+
Pull requests automatically trigger:
|
|
483
|
+
- **pr-tests.yml** — Runs the full test suite with coverage reporting (posts/updates a comment on the PR)
|
|
484
|
+
- **pr-coverage.yml** — SDK coverage audit against the Etsy OAS spec (triggered by the `sdk-check` label)
|
|
451
485
|
|
|
452
486
|
## Support
|
|
453
487
|
|
|
@@ -2,14 +2,15 @@ from enum import Enum
|
|
|
2
2
|
from typing import Any, Dict, List, Optional
|
|
3
3
|
|
|
4
4
|
|
|
5
|
-
def generate_get_uri(uri: str,
|
|
6
|
-
if
|
|
5
|
+
def generate_get_uri(uri: str, params: Optional[Dict[str, Any]] = None) -> str:
|
|
6
|
+
if not params:
|
|
7
7
|
return uri
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
formatted = "&".join(
|
|
9
|
+
f"{key}={str(value).lower() if isinstance(value, bool) else value}"
|
|
10
|
+
for key, value in params.items()
|
|
11
|
+
if value is not None
|
|
10
12
|
)
|
|
11
|
-
|
|
12
|
-
return uri
|
|
13
|
+
return f"{uri}?{formatted}" if formatted else uri
|
|
13
14
|
|
|
14
15
|
|
|
15
16
|
def todict(
|
|
@@ -31,9 +32,10 @@ def todict(
|
|
|
31
32
|
elif hasattr(obj, "__dict__"):
|
|
32
33
|
data = dict(
|
|
33
34
|
[
|
|
35
|
+
# _type -> "type": avoids shadowing Python's builtin in model attrs
|
|
34
36
|
("type" if key == "_type" else key, todict(value, classkey))
|
|
35
37
|
if key not in nullable
|
|
36
|
-
|
|
38
|
+
or (value != [] and value != "" and (value != 0 or isinstance(value, bool)))
|
|
37
39
|
else (key, None)
|
|
38
40
|
for key, value in obj.__dict__.items()
|
|
39
41
|
if not callable(value)
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
from enum import Enum
|
|
2
|
+
|
|
3
|
+
"""
|
|
4
|
+
Reference:
|
|
5
|
+
Official Documentation: https://developer.etsy.com/documentation/tutorials/fulfillment/#country-holidays
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
class HOLIDAYS(Enum):
|
|
9
|
+
"""
|
|
10
|
+
# Note:
|
|
11
|
+
Integer values from 1 to 105 are supported by Etsy based on selected regions.
|
|
12
|
+
Use US_HOLIDAYS or CA_HOLIDAYS for named constants, or pass integer IDs directly
|
|
13
|
+
for holidays not yet mapped to named constants.
|
|
14
|
+
"""
|
|
15
|
+
pass
|
|
16
|
+
|
|
17
|
+
class US_HOLIDAYS(Enum):
|
|
18
|
+
NEW_YEARS_DAY = 1
|
|
19
|
+
MARTIN_LUTHER_KING_JR_DAY = 2
|
|
20
|
+
PRESIDENTS_DAY = 3
|
|
21
|
+
MEMORIAL_DAY = 4
|
|
22
|
+
JUNETEENTH = 5
|
|
23
|
+
INDEPENDENCE_DAY = 6
|
|
24
|
+
LABOR_DAY = 7
|
|
25
|
+
COLUMBUS_DAY = 8
|
|
26
|
+
VETERANS_DAY = 9
|
|
27
|
+
THANKSGIVING_DAY = 10
|
|
28
|
+
CHRISTMAS_DAY = 11
|
|
29
|
+
|
|
30
|
+
class CA_HOLIDAYS(Enum):
|
|
31
|
+
GOOD_FRIDAY = 12
|
|
32
|
+
EASTER = 13
|
|
33
|
+
VICTORIA_DAY = 14
|
|
34
|
+
CANADA_DAY = 15
|
|
35
|
+
TRUTH_AND_RECONCILIATION_DAY = 16
|
|
36
|
+
REMEMBRANCE_DAY = 17
|
|
37
|
+
CIVIC_HOLIDAY = 18
|
|
38
|
+
BOXING_DAY = 19
|
|
39
|
+
NEW_YEARS_DAY = 20
|
|
40
|
+
LABOR_DAY = 21
|
|
41
|
+
THANKSGIVING_DAY = 22
|
|
42
|
+
CHRISTMAS_DAY = 23
|
|
@@ -9,11 +9,11 @@ class WhoMade(Enum):
|
|
|
9
9
|
|
|
10
10
|
class WhenMade(Enum):
|
|
11
11
|
MADE_TO_ORDER = "made_to_order"
|
|
12
|
-
TWENTY_TWENTIES = "
|
|
12
|
+
TWENTY_TWENTIES = "2020_2026"
|
|
13
13
|
TWENTY_TENS = "2010_2019"
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
14
|
+
TWENTY_OH_SEVEN_TO_NINE = "2007_2009"
|
|
15
|
+
BEFORE_2007 = "before_2007"
|
|
16
|
+
TWO_THOUSAND_TO_SIX = "2000_2006"
|
|
17
17
|
NINETEEN_NINETIES = "1990s"
|
|
18
18
|
NINETEEN_EIGHTIES = "1980s"
|
|
19
19
|
NINETEEN_SEVENTIES = "1970s"
|
|
@@ -58,6 +58,14 @@ class State(Enum):
|
|
|
58
58
|
SOLD_OUT = "sold_out"
|
|
59
59
|
DRAFT = "draft"
|
|
60
60
|
EXPIRED = "expired"
|
|
61
|
+
REMOVED = "removed"
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
class VideoState(Enum):
|
|
65
|
+
ACTIVE = "active"
|
|
66
|
+
INACTIVE = "inactive"
|
|
67
|
+
DELETED = "deleted"
|
|
68
|
+
FLAGGED = "flagged"
|
|
61
69
|
|
|
62
70
|
|
|
63
71
|
class SortOn(Enum):
|
|
@@ -31,6 +31,7 @@ class CreateDraftListingRequest(Request):
|
|
|
31
31
|
"item_dimensions_unit",
|
|
32
32
|
"production_partner_ids",
|
|
33
33
|
"image_ids",
|
|
34
|
+
"readiness_state_id",
|
|
34
35
|
]
|
|
35
36
|
mandatory = [
|
|
36
37
|
"quantity",
|
|
@@ -76,6 +77,7 @@ class CreateDraftListingRequest(Request):
|
|
|
76
77
|
should_auto_renew: Optional[bool] = None,
|
|
77
78
|
is_taxable: Optional[bool] = None,
|
|
78
79
|
listing_type: Optional[Type] = None,
|
|
80
|
+
readiness_state_id: Optional[int] = None,
|
|
79
81
|
):
|
|
80
82
|
self.quantity = quantity
|
|
81
83
|
self.title = title
|
|
@@ -109,6 +111,7 @@ class CreateDraftListingRequest(Request):
|
|
|
109
111
|
self.should_auto_renew = should_auto_renew
|
|
110
112
|
self.is_taxable = is_taxable
|
|
111
113
|
self._type = listing_type
|
|
114
|
+
self.readiness_state_id = readiness_state_id
|
|
112
115
|
super().__init__(
|
|
113
116
|
nullable=CreateDraftListingRequest.nullable,
|
|
114
117
|
mandatory=CreateDraftListingRequest.mandatory,
|
|
@@ -201,7 +204,7 @@ class UpdateListingRequest(Request):
|
|
|
201
204
|
|
|
202
205
|
|
|
203
206
|
class UpdateListingInventoryRequest(Request):
|
|
204
|
-
nullable: List[str] = []
|
|
207
|
+
nullable: List[str] = ["readiness_state_on_property"]
|
|
205
208
|
mandatory: List[str] = ["products"]
|
|
206
209
|
|
|
207
210
|
def __init__(
|
|
@@ -210,11 +213,13 @@ class UpdateListingInventoryRequest(Request):
|
|
|
210
213
|
price_on_property: Optional[List[int]] = None,
|
|
211
214
|
quantity_on_property: Optional[List[int]] = None,
|
|
212
215
|
sku_on_property: Optional[List[int]] = None,
|
|
216
|
+
readiness_state_on_property: Optional[List[int]] = None,
|
|
213
217
|
):
|
|
214
218
|
self.products = products
|
|
215
219
|
self.price_on_property = price_on_property
|
|
216
220
|
self.quantity_on_property = quantity_on_property
|
|
217
221
|
self.sku_on_property = sku_on_property
|
|
222
|
+
self.readiness_state_on_property = readiness_state_on_property
|
|
218
223
|
super().__init__(
|
|
219
224
|
nullable=UpdateListingInventoryRequest.nullable,
|
|
220
225
|
mandatory=UpdateListingInventoryRequest.mandatory,
|
|
@@ -349,6 +354,21 @@ class UpdateListingTranslationRequest(Request):
|
|
|
349
354
|
)
|
|
350
355
|
|
|
351
356
|
|
|
357
|
+
class UpdateListingPersonalizationRequest(Request):
|
|
358
|
+
nullable: List[str] = []
|
|
359
|
+
mandatory: List[str] = ["personalization_questions"]
|
|
360
|
+
|
|
361
|
+
def __init__(
|
|
362
|
+
self,
|
|
363
|
+
personalization_questions: Optional[List[Dict[str, Any]]] = None,
|
|
364
|
+
):
|
|
365
|
+
self.personalization_questions = personalization_questions
|
|
366
|
+
super().__init__(
|
|
367
|
+
nullable=UpdateListingPersonalizationRequest.nullable,
|
|
368
|
+
mandatory=UpdateListingPersonalizationRequest.mandatory,
|
|
369
|
+
)
|
|
370
|
+
|
|
371
|
+
|
|
352
372
|
class UpdateListingVideoRequest(FileRequest):
|
|
353
373
|
nullable: List[str] = ["file"]
|
|
354
374
|
mandatory: List[str] = []
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
from typing import List, Optional
|
|
2
|
+
|
|
3
|
+
from etsy_python.v3.enums.ProcessingProfile import ProcessingTimeUnit, ReadinessState
|
|
4
|
+
from etsy_python.v3.models.Request import Request
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class CreateShopReadinessStateDefinitionRequest(Request):
|
|
8
|
+
nullable: List[str] = [
|
|
9
|
+
"processing_time_unit",
|
|
10
|
+
]
|
|
11
|
+
mandatory: List[str] = [
|
|
12
|
+
"readiness_state",
|
|
13
|
+
"min_processing_time",
|
|
14
|
+
"max_processing_time",
|
|
15
|
+
]
|
|
16
|
+
|
|
17
|
+
def __init__(
|
|
18
|
+
self,
|
|
19
|
+
readiness_state: Optional[ReadinessState] = None,
|
|
20
|
+
min_processing_time: Optional[int] = None,
|
|
21
|
+
max_processing_time: Optional[int] = None,
|
|
22
|
+
processing_time_unit: Optional[ProcessingTimeUnit] = None,
|
|
23
|
+
):
|
|
24
|
+
self.readiness_state = readiness_state.value if readiness_state else None
|
|
25
|
+
self.min_processing_time = min_processing_time
|
|
26
|
+
self.max_processing_time = max_processing_time
|
|
27
|
+
self.processing_time_unit = (
|
|
28
|
+
processing_time_unit.value if processing_time_unit else None
|
|
29
|
+
)
|
|
30
|
+
super().__init__(
|
|
31
|
+
nullable=CreateShopReadinessStateDefinitionRequest.nullable,
|
|
32
|
+
mandatory=CreateShopReadinessStateDefinitionRequest.mandatory,
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class UpdateShopReadinessStateDefinitionRequest(Request):
|
|
37
|
+
nullable: List[str] = [
|
|
38
|
+
"readiness_state",
|
|
39
|
+
"min_processing_time",
|
|
40
|
+
"max_processing_time",
|
|
41
|
+
"processing_time_unit",
|
|
42
|
+
]
|
|
43
|
+
mandatory: List[str] = []
|
|
44
|
+
|
|
45
|
+
def __init__(
|
|
46
|
+
self,
|
|
47
|
+
readiness_state: Optional[ReadinessState] = None,
|
|
48
|
+
min_processing_time: Optional[int] = None,
|
|
49
|
+
max_processing_time: Optional[int] = None,
|
|
50
|
+
processing_time_unit: Optional[ProcessingTimeUnit] = None,
|
|
51
|
+
):
|
|
52
|
+
self.readiness_state = readiness_state.value if readiness_state else None
|
|
53
|
+
self.min_processing_time = min_processing_time
|
|
54
|
+
self.max_processing_time = max_processing_time
|
|
55
|
+
self.processing_time_unit = (
|
|
56
|
+
processing_time_unit.value if processing_time_unit else None
|
|
57
|
+
)
|
|
58
|
+
super().__init__(
|
|
59
|
+
nullable=UpdateShopReadinessStateDefinitionRequest.nullable,
|
|
60
|
+
mandatory=UpdateShopReadinessStateDefinitionRequest.mandatory,
|
|
61
|
+
)
|
|
@@ -15,6 +15,7 @@ class Request:
|
|
|
15
15
|
raise ValueError
|
|
16
16
|
|
|
17
17
|
def check_mandatory(self) -> bool:
|
|
18
|
+
# Keys must match the attribute name (e.g. "_type", not "type").
|
|
18
19
|
if self._mandatory is not None:
|
|
19
20
|
for key in self._mandatory:
|
|
20
21
|
try:
|
|
@@ -28,7 +29,7 @@ class Request:
|
|
|
28
29
|
return [
|
|
29
30
|
key
|
|
30
31
|
for key, value in self.__dict__.items()
|
|
31
|
-
if key in self._nullable and (value == [] or value == "" or value == 0)
|
|
32
|
+
if key in self._nullable and (value == [] or value == "" or (value == 0 and not isinstance(value, bool)))
|
|
32
33
|
]
|
|
33
34
|
|
|
34
35
|
def get_dict(self) -> Any:
|
|
@@ -10,6 +10,8 @@ from etsy_python.v3.models.Request import Request
|
|
|
10
10
|
|
|
11
11
|
class CreateShopShippingProfileRequest(Request):
|
|
12
12
|
nullable: List[str] = [
|
|
13
|
+
"min_processing_time",
|
|
14
|
+
"max_processing_time",
|
|
13
15
|
"destination_country_iso",
|
|
14
16
|
"mail_class",
|
|
15
17
|
"min_delivery_days",
|
|
@@ -20,8 +22,6 @@ class CreateShopShippingProfileRequest(Request):
|
|
|
20
22
|
"origin_country_iso",
|
|
21
23
|
"primary_cost",
|
|
22
24
|
"secondary_cost",
|
|
23
|
-
"min_processing_time",
|
|
24
|
-
"max_processing_time",
|
|
25
25
|
]
|
|
26
26
|
|
|
27
27
|
def __init__(
|
|
@@ -131,7 +131,8 @@ class CreateShopShippingProfileDestinationRequest(Request):
|
|
|
131
131
|
class UpdateShopShippingProfileDestinationRequest(Request):
|
|
132
132
|
nullable: List[str] = [
|
|
133
133
|
"primary_cost",
|
|
134
|
-
"secondary_cost"
|
|
134
|
+
"secondary_cost",
|
|
135
|
+
"destination_country_iso",
|
|
135
136
|
"shipping_carrier_id",
|
|
136
137
|
"mail_class",
|
|
137
138
|
"min_delivery_days",
|
|
@@ -172,7 +173,7 @@ class CreateShopShippingProfileUpgradeRequest(Request):
|
|
|
172
173
|
"max_delivery_days",
|
|
173
174
|
]
|
|
174
175
|
mandatory: List[str] = [
|
|
175
|
-
"
|
|
176
|
+
"_type",
|
|
176
177
|
"upgrade_name",
|
|
177
178
|
"price",
|
|
178
179
|
"secondary_price",
|
|
@@ -189,6 +190,8 @@ class CreateShopShippingProfileUpgradeRequest(Request):
|
|
|
189
190
|
min_delivery_days: Optional[int] = None,
|
|
190
191
|
max_delivery_days: Optional[int] = None,
|
|
191
192
|
) -> None:
|
|
193
|
+
# Stored as _type to avoid shadowing Python's builtin `type`.
|
|
194
|
+
# todict() maps _type -> "type" for API serialization.
|
|
192
195
|
self._type = profile_type.value if profile_type else None
|
|
193
196
|
self.upgrade_name = upgrade_name
|
|
194
197
|
self.price = price
|
|
@@ -209,7 +212,8 @@ class UpdateShopShippingProfileUpgradeRequest(Request):
|
|
|
209
212
|
"upgrade_name",
|
|
210
213
|
"price",
|
|
211
214
|
"secondary_price",
|
|
212
|
-
"shipping_carrier_id"
|
|
215
|
+
"shipping_carrier_id",
|
|
216
|
+
"mail_class",
|
|
213
217
|
"min_delivery_days",
|
|
214
218
|
"max_delivery_days",
|
|
215
219
|
]
|
|
@@ -227,6 +231,8 @@ class UpdateShopShippingProfileUpgradeRequest(Request):
|
|
|
227
231
|
max_delivery_days: Optional[int] = None,
|
|
228
232
|
) -> None:
|
|
229
233
|
self.upgrade_name = upgrade_name
|
|
234
|
+
# Stored as _type to avoid shadowing Python's builtin `type`.
|
|
235
|
+
# todict() maps _type -> "type" for API serialization.
|
|
230
236
|
self._type = profile_type.value if profile_type else None
|
|
231
237
|
self.price = price
|
|
232
238
|
self.secondary_price = secondary_price
|
|
@@ -20,7 +20,7 @@ class HolidayPreferencesResource:
|
|
|
20
20
|
def update_holiday_preferences(
|
|
21
21
|
self,
|
|
22
22
|
shop_id: int,
|
|
23
|
-
holiday_id: Optional[Union[HOLIDAYS, US_HOLIDAYS, CA_HOLIDAYS,
|
|
23
|
+
holiday_id: Optional[Union[HOLIDAYS, US_HOLIDAYS, CA_HOLIDAYS, int]],
|
|
24
24
|
holiday_preference: UpdateHolidayPreferencesRequest,
|
|
25
25
|
) -> Union[Response, RequestException]:
|
|
26
26
|
endpoint = f"/shops/{shop_id}/holiday-preferences/{holiday_id}"
|