Skip to content

Sync SDK with Etsy API spec — extend personalization deprecation warning - #27

Merged
amitray007 merged 5 commits into
masterfrom
release/sdk-audit-2026-05-17
May 18, 2026
Merged

Sync SDK with Etsy API spec — extend personalization deprecation warning#27
amitray007 merged 5 commits into
masterfrom
release/sdk-audit-2026-05-17

Conversation

@amitray007

Copy link
Copy Markdown
Owner

Summary

Output of /maintain-audit against the current Etsy OAS spec. The audit reported 100% endpoint coverage (103/103) and no schema/parameter drift; the only actionable item was a small completeness gap in the personalization deprecation warning.

  • 0 Must Fix
  • 1 Should Fixis_personalizable is [DEPRECATED] in the spec but CreateDraftListingRequest / UpdateListingRequest only warned when one of the other three personalization fields was set.
  • 6 Informational — all flagged "extra SDK methods", enum staleness, and "implicit string concatenation" findings are intentional and documented (deprecation aliases, CA_HOLIDAYS design, State.REMOVED backward-compat, multi-line warnings.warn strings).

Changes

Commit 1 — fix: extend personalization deprecation warning to include is_personalizable

  • Added is_personalizable to the warning trigger and message in both model __init__s.
  • Refreshed specs/baseline.json from the freshly-fetched specs/latest.json. The only differences from prior baseline are description-text changes on createDraftListing.styles (45-char-per-style note) and updateListingInventory (mentions processing-profile compatibility) — no schema/field changes.

Commit 2 — refactor: extract personalization deprecation helper; warn only on truthy values
Addresses code-review feedback on commit 1:

  • Switched trigger from is not None to truthy. The API documents false / 0 / empty string as default-equivalent for these fields; they remain no-ops after the Apr. 9th, 2026 removal, so they should not warn.
  • Extracted _PERSONALIZATION_DEPRECATION_MSG constant and _warn_if_personalization_used() helper to remove the 15-line block duplicated across CreateDraftListingRequest and UpdateListingRequest. Helper uses stacklevel=3 so the warning still points to the user's call site.
  • Added tests for: is_personalizable=False (no warn), zero char-count + empty instructions (no warn), all four fields set together (exactly one warn).

Test plan

  • pytest -v — 251 passed, 0 failed
  • python scripts/audit_sdk.py --spec specs/latest.json — 100% coverage, no drift, no missing endpoints
  • python scripts/diff_spec.py — empty (baseline matches latest)
  • python scripts/check_releases.py — up to date with 3.0.0-general-release-2026-03-24
  • Manually verify a downstream caller setting is_personalizable=True sees the deprecation warning
  • Manually verify a downstream caller setting is_personalizable=False (or omitting it) sees no warning

🤖 Generated with Claude Code

amitray007 and others added 2 commits May 17, 2026 19:29
…lizable

The Etsy API marks all four listing personalization fields as
[DEPRECATED] (is_personalizable, personalization_is_required,
personalization_char_count_max, personalization_instructions), but
CreateDraftListingRequest and UpdateListingRequest only emitted a
DeprecationWarning when one of the latter three was set. Setting only
is_personalizable now also triggers the warning, with the message
updated to name all four fields.

Also refresh specs/baseline.json — the latest spec only differs from
the previous baseline in description text on createDraftListing.styles
(adds the 45-char-per-style note) and updateListingInventory (mentions
processing profile compatibility), so no further code changes are
required.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…uthy values

Addresses code review on prior commit (7db1898):

1. Switch warning trigger from "is not None" to truthy. The API documents
   `false` (and by extension `0` / empty string) as the default-equivalent
   for the deprecated personalization fields; these remain no-ops after
   the Apr. 9th, 2026 removal, so they should not warn. Setting True /
   non-zero int / non-empty string still warns.

2. Extract `_PERSONALIZATION_DEPRECATION_MSG` constant and
   `_warn_if_personalization_used()` helper to remove the 15-line block
   duplicated across CreateDraftListingRequest and UpdateListingRequest.
   Helper uses `stacklevel=3` so the warning still points at the user's
   call site.

3. Add tests covering:
   - is_personalizable=False (no warning, opt-out)
   - char_count_max=0 + empty instructions (no warning)
   - all four fields set together (exactly one warning, not four)

All 251 tests pass.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings May 18, 2026 15:31
@amitray007 amitray007 added enhancement New feature or request api-drift Auto-created when Etsy API spec changes are detected by weekly maintenance check labels May 18, 2026
@amitray007 amitray007 self-assigned this May 18, 2026
@github-actions

github-actions Bot commented May 18, 2026

Copy link
Copy Markdown
Contributor

Test Coverage Report

Overall: 100% (1672/1672 statements covered)

Coverage by file
File Statements Missing Coverage
etsy_python/__init__.py 2 0 100%
etsy_python/_version.py 1 0 100%
etsy_python/v3/auth/OAuth.py 33 0 100%
etsy_python/v3/auth/__init__.py 1 0 100%
etsy_python/v3/common/Env.py 10 0 100%
etsy_python/v3/common/Request.py 3 0 100%
etsy_python/v3/common/Utils.py 31 0 100%
etsy_python/v3/enums/HolidayPreferences.py 29 0 100%
etsy_python/v3/enums/Language.py 12 0 100%
etsy_python/v3/enums/Listing.py 78 0 100%
etsy_python/v3/enums/ListingInventory.py 6 0 100%
etsy_python/v3/enums/ProcessingProfile.py 7 0 100%
etsy_python/v3/enums/ShippingProfile.py 261 0 100%
etsy_python/v3/enums/ShopReceipt.py 12 0 100%
etsy_python/v3/exceptions/BaseAPIException.py 10 0 100%
etsy_python/v3/exceptions/RequestException.py 8 0 100%
etsy_python/v3/exceptions/__init__.py 2 0 100%
etsy_python/v3/models/FileRequest.py 7 0 100%
etsy_python/v3/models/HolidayPreferences.py 8 0 100%
etsy_python/v3/models/Listing.py 150 0 100%
etsy_python/v3/models/Miscellaneous.py 8 0 100%
etsy_python/v3/models/ProcessingProfile.py 21 0 100%
etsy_python/v3/models/Product.py 7 0 100%
etsy_python/v3/models/Receipt.py 39 0 100%
etsy_python/v3/models/Request.py 22 0 100%
etsy_python/v3/models/ShippingProfile.py 85 0 100%
etsy_python/v3/models/Shop.py 24 0 100%
etsy_python/v3/models/ShopReturnPolicy.py 25 0 100%
etsy_python/v3/models/Utils.py 19 0 100%
etsy_python/v3/models/__init__.py 10 0 100%
etsy_python/v3/resources/HolidayPreferences.py 19 0 100%
etsy_python/v3/resources/Listing.py 81 0 100%
etsy_python/v3/resources/ListingFile.py 22 0 100%
etsy_python/v3/resources/ListingImage.py 22 0 100%
etsy_python/v3/resources/ListingInventory.py 20 0 100%
etsy_python/v3/resources/ListingOffering.py 12 0 100%
etsy_python/v3/resources/ListingProduct.py 12 0 100%
etsy_python/v3/resources/ListingTranslation.py 19 0 100%
etsy_python/v3/resources/ListingVariationImages.py 16 0 100%
etsy_python/v3/resources/ListingVideo.py 22 0 100%
etsy_python/v3/resources/Miscellaneous.py 16 0 100%
etsy_python/v3/resources/Payment.py 23 0 100%
etsy_python/v3/resources/PaymentLedgerEntry.py 15 0 100%
etsy_python/v3/resources/ProcessingProfile.py 26 0 100%
etsy_python/v3/resources/Receipt.py 25 0 100%
etsy_python/v3/resources/ReceiptTransactions.py 27 0 100%
etsy_python/v3/resources/Response.py 9 0 100%
etsy_python/v3/resources/Review.py 16 0 100%
etsy_python/v3/resources/Session.py 94 0 100%
etsy_python/v3/resources/ShippingProfile.py 58 0 100%
etsy_python/v3/resources/Shop.py 23 0 100%
etsy_python/v3/resources/ShopProductionPartner.py 11 0 100%
etsy_python/v3/resources/ShopReturnPolicy.py 28 0 100%
etsy_python/v3/resources/ShopSection.py 25 0 100%
etsy_python/v3/resources/Taxonomy.py 23 0 100%
etsy_python/v3/resources/User.py 14 0 100%
etsy_python/v3/resources/UserAddress.py 19 0 100%
etsy_python/v3/resources/__init__.py 29 0 100%
etsy_python/v3/resources/enums/RateLimit.py 8 0 100%
etsy_python/v3/resources/enums/Request.py 7 0 100%

Updated by PR Tests

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Extends the existing personalization deprecation warning in CreateDraftListingRequest and UpdateListingRequest to also trigger when is_personalizable is set, aligning with Etsy's OAS spec which marks it as [DEPRECATED]. The warning logic was refactored into a shared helper, and the trigger now uses truthy checks so explicit falsy/default values don't warn. The spec baseline is refreshed with minor description-text updates.

Changes:

  • Added is_personalizable to deprecation trigger and message; switched to truthy check.
  • Extracted _PERSONALIZATION_DEPRECATION_MSG and _warn_if_personalization_used() helper (with stacklevel=3) to eliminate duplication.
  • Refreshed specs/baseline.json (description-only updates) and added tests covering the new behavior.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.

File Description
etsy_python/v3/models/Listing.py Extracted shared personalization deprecation helper and added is_personalizable to the trigger.
tests/test_listing_models.py Added tests for is_personalizable warning, falsy no-warn cases, and single-warn-on-multi-field.
specs/baseline.json Refreshed baseline with description-only changes (no schema drift).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

amitray007 and others added 3 commits May 18, 2026 21:04
The PR coverage report flagged three files at 0%:

  - etsy_python/v3/auth/OAuth.py      (33 stmts)
  - etsy_python/v3/auth/__init__.py    (1 stmt)
  - etsy_python/v3/enums/Language.py  (12 stmts)

Adds two test modules:

* tests/test_oauth.py — 13 tests covering EtsyOAuth: constructor with
  and without optional args (code_verifier, state, scopes), PKCE
  challenge derivation against a known SHA-256 base64url-no-padding
  value, get_auth_code's call into OAuth2Session.authorization_url,
  set_authorisation_code happy path and state-mismatch PermissionError,
  and get_access_token's call into OAuth2Session.fetch_token. The
  underlying OAuth2Session is patched so no network I/O occurs.

* tests/test_language_enum.py — 2 tests verifying every Language member
  value is its name lowercased and exactly the ten ISO 639-1 codes the
  Etsy API supports.

All three target files are now 100% covered. Overall coverage rises
from 94% to 96% across 266 tests.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Brings every source file to ≤5 missing statements and ≥80% coverage.
Adds 31 new tests across six files.

New test files:
* test_processing_profile_models.py — CreateShopReadinessStateDefinitionRequest
  and UpdateShopReadinessStateDefinitionRequest constructors, including
  enum unwrapping into raw string values and partial-update behavior.
* test_processing_profile_resource.py — all five
  ProcessingProfileResource methods (create, list with default + custom
  pagination, get, update, delete). The resource had zero prior tests.
* test_shop_return_policy_models.py — ConsolidateShopReturnPoliciesRequest,
  CreateShopReturnPolicyRequest, UpdateShopReturnPolicyRequest. Includes
  a False-preservation test guarding the bool/nullable behavior in
  CLAUDE.md.
* test_misc_and_holiday_models.py — GetTokenScopes and
  UpdateHolidayPreferencesRequest, including is_working=False
  preservation.

Extended:
* test_listing_models.py — UpdateListingTranslationRequest,
  UpdateListingPersonalizationRequest, UpdateListingVideoRequest
  constructor tests (request-body uploads exercising the file/data
  dicts).
* test_listing_resource.py — TestListingPersonalizationEndpoints:
  get_listing_personalization, update_listing_personalization (with
  and without supports_multiple_personalization_questions query
  param), delete_listing_personalization.

Result: 297 passing tests, 99% overall coverage. All ten remaining
uncovered lines are in five files (Utils.py: 4, Request.py: 2, three
single-line gaps in Session/Response/exceptions). Per-file floor is
87%, per-file gap ceiling is 4 lines.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Adds 9 small tests covering the remaining uncovered branches and
helpers:

* test_utils.py — TestTodict.test_ast_attribute_is_expanded covers the
  todict branch that delegates to obj._ast(). TestGenerateBytesFromFile
  exercises generate_bytes_from_file against a tmp_path file and an
  empty file (the file-bytes helper used by FileRequest uploads).

* test_request_model.py — test_mandatory_key_with_no_attribute_raises_value_error
  covers the except-Exception branch of Request.check_mandatory()
  triggered when a mandatory key isn't an instance attribute (KeyError
  on self.__dict__[key]).

* test_session.py — test_invalid_method_payload_combo_raises_value_error
  passes a non-Request payload to a PUT call, which slips past the
  "Improper payload" guard and hits the final
  "Invalid method or payload" else.

* test_exceptions_and_response.py (new) — covers __str__ for
  BaseAPIException, RequestException (verifies the [EtsyRequestException]
  prefix), and Response.

Result: 306 tests, 100.0% coverage, no missing statements anywhere
in etsy_python/.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@amitray007 amitray007 linked an issue May 18, 2026 that may be closed by this pull request
@amitray007
amitray007 merged commit 02726e2 into master May 18, 2026
6 checks passed
@amitray007
amitray007 deleted the release/sdk-audit-2026-05-17 branch May 18, 2026 16:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

api-drift Auto-created when Etsy API spec changes are detected by weekly maintenance check enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

audit: Spec Drift [2026-05-18] — low

2 participants