Skip to content

feat: sync SDK with Etsy API spec — stop sending removed personalization fields - #41

Merged
amitray007 merged 2 commits into
masterfrom
release/sdk-audit-2026-09-06
Sep 6, 2026
Merged

feat: sync SDK with Etsy API spec — stop sending removed personalization fields#41
amitray007 merged 2 commits into
masterfrom
release/sdk-audit-2026-09-06

Conversation

@amitray007

Copy link
Copy Markdown
Owner

Summary

Full SDK audit against the latest Etsy OAS spec (2026-09). Coverage is 105/105 operations, 100%, with 0 active findings and 0 stale ignores after this branch.

Found 0 Must Fix, 1 Should Fix, 4 Informational items. The one real change:

Etsy removed is_personalizable, personalization_is_required, personalization_char_count_max and personalization_instructions from the createDraftListing and updateListing request bodies. Personalization now lives on the dedicated personalization endpoints, which this SDK already implements (get_listing_personalization, update_listing_personalization, delete_listing_personalization).

The SDK already warned when these fields were set, but still serialized and transmitted them.

⚠️ Behavior change

Callers who set these four fields will no longer have them sent to the API. They are now stored under underscore-prefixed names that todict excludes, so they never reach the wire.

Etsy already removed them from the request bodies, so they were being rejected regardless — this stops sending data the API no longer accepts. Source compatibility is fully preserved:

  • The constructor keyword arguments still exist.
  • Attribute reads and writes still work, via properties.
  • Setting any of them (constructor or assignment) emits a DeprecationWarning pointing at the caller's line.

The kwargs are slated for removal in the next major version. This branch uses a feat: prefix on HEAD so the merge produces a minor version bump rather than a patch, given the wire-behavior change.

Audit tooling

Request body drift previously bypassed specs/audit-ignore.json entirely, so a reviewed and accepted body-drift finding could only be left as permanent report noise. It now flows through the same suppression pipeline as the other finding types, as a value-bearing body_drift type:

  • Suppression is scoped to named fields — a newly drifted field on an already-suppressed operation still surfaces.
  • Entries matching nothing are reported under Stale Ignores.
  • The extraction into compute_body_findings is behavior-preserving; verified by diffing the full generated report against the previous implementation (byte-identical).

Two body_drift entries were added for the accepted personalization finding, bringing the ignore file to 21 entries.

Suppression re-verification

All 19 pre-existing suppressions were re-read against current code and spec, and re-confirmed valid — 0 removed, 0 stale, 0 newly surfaced enum values:

Type Count Verification
param_drift (legacy, 8 ops) 8 warn_removed_legacy_param still called at all 8 sites; value discarded
extra_method (deprecated aliases) 4 All still delegate to the canonical method and emit DeprecationWarning
enum_staleness (State.REMOVED) 3 Still absent from spec, still documented inline
enum_staleness (Includes shipping/inventory) 2 Confirmed still valid on getListingsByShop
enum_staleness (holiday_id) 2 Country-split design intact; spec range still 1-105

Test plan

  • pytest433 passed (was 408; 25 new tests).
    • Removed fields are absent from get_dict() on both models, while other fields serialize normally.
    • Attribute reads and post-construction writes still work.
    • DeprecationWarning fires once per construction, blames the caller's line on both the constructor and setter paths, and stays silent for falsy values.
    • compute_body_findings: both drift directions, listing_typetype alias normalization, multipart skip, and no false drift for body fields sharing a path-param name.
    • body_drift suppression: value-scoped hiding, newly drifted fields staying active, stale detection, direction matching.
  • python scripts/audit_sdk.py --spec specs/latest.json — 100% coverage, 0 active findings, 0 stale ignores.
  • python scripts/check_version_consistency.py — versions consistent.
  • specs/baseline.json updated to the current spec; diff_spec.py now reports no changes.

🤖 Generated with Claude Code

Etsy removed is_personalizable, personalization_is_required,
personalization_char_count_max and personalization_instructions from the
createDraftListing and updateListing request bodies (2026-09 spec).
Personalization now lives on the dedicated personalization endpoints, which
the SDK already implements.

The SDK already warned when these fields were set, but still serialized and
transmitted them. They are now stored under underscore-prefixed names that
todict excludes, so they never reach the wire. The constructor kwargs and the
DeprecationWarning are kept so existing callers don't break, and read access
is preserved via properties. Remove the kwargs in the next major version.

Also route request body drift through the audit suppression pipeline as a
value-bearing `body_drift` finding type, matching enum_staleness and
param_drift. Body drift previously bypassed specs/audit-ignore.json entirely,
so an accepted finding could only be left as permanent noise. Suppression is
scoped to named fields, so newly drifted fields on an already-suppressed
operation still surface.

Audit: 105/105 operations, 100% coverage, 0 active findings, 0 stale ignores.
- compute_body_findings: restore the original subtraction semantics in the
  no-model-class branch. Path/query param names are now excluded from the
  "extra" direction only, as before. Subtracting them from the shared field set
  made a body field that shares a path-param name (taxonomy_id,
  shipping_profile_id, shop_section_id, return_policy_id) falsely report as
  "In spec but not SDK".

- Personalization fields: add setters alongside the properties. Making them
  getter-only broke post-construction assignment with AttributeError, which
  the back-compat goal was meant to avoid. A write now stores the value and
  warns, exactly like the constructor kwarg, and still never serializes.
  _warn_if_personalization_used takes the stacklevel so both paths blame the
  caller's line.

Uses a feat: prefix so the merge produces a minor version bump: the branch
changes wire behavior for callers that relied on the four personalization
fields being transmitted. Etsy already removed them from the request bodies,
so they were being rejected regardless, but the change warrants more than a
patch bump.
@amitray007 amitray007 added python Pull requests that update python code api-drift Auto-created when Etsy API spec changes are detected by weekly maintenance check severity: medium Medium severity — new/changed endpoints need review labels Sep 6, 2026
@amitray007 amitray007 self-assigned this Sep 6, 2026
@github-actions

github-actions Bot commented Sep 6, 2026

Copy link
Copy Markdown
Contributor

Test Coverage Report

Overall: 100% (1726/1726 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 34 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 4 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 177 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 102 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 25 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

@amitray007 amitray007 linked an issue Sep 6, 2026 that may be closed by this pull request
@amitray007
amitray007 merged commit 791bedf into master Sep 6, 2026
8 checks passed
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 python Pull requests that update python code severity: medium Medium severity — new/changed endpoints need review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

audit: Spec Drift [2026-08-31] — medium

1 participant