Skip to main content

ELTA Shopify plugin 0.17.1

0.17.1 — product media display facts

  • ProductMediaFact (inside the display-only ProductMediaTargetFacts of shopify.admin.product_media.set) gains optional preview_url (HTTPS DisplayImageUrl, from Shopify's preview.image.url), media_type (open mediaContentType text) and alt_text, read in the same bounded ProductMediaState query (measured requested cost 72 -> 94). Facts stay display-only: not the drift token, the undo baseline or approval identity.
  • Absent values are omitted from stored and hashed bytes, so facts without them keep their 0.17.0 bytes and hashes. 0.17.0 rejects the new keys, so once a proposal stores facts with any of them the rollback floor is the backend that vendors 0.17.1. No new action, scope or permission.

0.17.0 — product image list SET

  • New shopify.admin.product_media.set (SET on PRODUCT, products family): the product's whole ordered image list; the first item is the main image (see "Product images" below). It requires read_products, write_products and write_files; write_files is declared on this action only, so a store without it gets PERMISSION_MISSING (grant hint + Sync now) before any call and no other action changes. Existing actions, change models, bytes and hashes are unchanged.
  • A stored proposal with this action cannot decode on 0.16.0, so once one is stored the rollback floor is the backend that vendors 0.17.0. Its undo also needs that backend's created_version SET fence.

0.16.0 — create status inputs and List on Online Store

Backend 0.31.0 vendors it with authz generation 5.

  • New default-off family shopify.admin.product_publication with shopify.admin.product.publish_online_store and its revert-only undo shopify.admin.product.unpublish_online_store; both require write_publications and read_products (see "Online Store listing" below). The family is off until a store's stored enabled list includes it. It is not fee-bearing, so the Allow-all choice covers it, but a store that chose Allow-all before 0.31.0 sees FAMILY_OFF with the existing "Turn on" remedy.
  • A publish is APPLIED only on empty userErrors plus a confirming re-read of the same publication id; otherwise it is UNKNOWN and never resent.

article.create and page.create accept is_published, defaulting to false; product.create accepts DRAFT or ACTIVE, defaulting to DRAFT. The approval fields and provider mutation inputs carry the selected values. ACTIVE makes the product ready to sell; whether it appears on the Online Store depends on the store's sales-channel settings (Shopify publishes it only if that channel auto-publishes); ELTA lists a product on the Online Store only through the separate "List on Online Store" action (shopify.admin.product.publish_online_store).

A stored proposal with status ACTIVE, is_published true or a publication action cannot decode on 0.15.1 (Literal/unknown action), so once one is stored the rollback floor is backend 0.31.0.

0.15.1 — plugin-contract compatibility

Accepts plugin-contract >=0.16.0,<0.17 in the coordinated backend 0.29.0 release. Constraint-only repin: no runtime code, declaration, catalog byte or facts emission changes.

0.15.0 — row thumbnails and merchant action titles

Previews now fill the existing display-only TargetState.image_url with the target's https image: products (description, delete, metafield and SEO rows) use featuredMedia's preview image, collections and articles (metafield and SEO rows, article update and delete) their image; pages have no image, so page rows stay without one. file_alt.update has carried the MediaImage URL since 0.13.0; a GenericFile has none. The image never enters identity, the version token or any proposal hash. Four action titles now use merchant words: article.create "New blog post"/"新博客文章", article.update "Blog post text"/"博客文章正文", page.update "Page text"/"页面正文" and product_description.update "Product description"/"商品描述". Catalog copy only: action keys, change schemas and stored records are unchanged. Backend 0.27.0 vendors it.

0.14.0 — lookup rows carry storefront handles

ShopifyProductDescriptionRead, ShopifyBlogRead and ShopifyArticleSummaryRead gain an optional handle, and ShopifyArticleRead an optional blog_handle, read in the existing queries, so a consumer can build the storefront URL without another lookup. All fields are additive and optional; no write, change schema, stored key or hash changed. Backend 0.25.0 vendors it.

0.13.0 — lookups say what they answer; an alt-text row shows its image

The ten store-reading lookups now declare a one-line meaning: Product list, Products and media, Blogs, Blog articles, Pages, Page content, Article content, Themes, Theme files and Theme preview render. Each names what the read returns and which other lookup supplies its inputs, and none claims a search, sort or filter the list query does not accept. The wording belongs to the plugin that answers the read.

An alt-text preview now carries the target image: the file-alt read selects a MediaImage's image { url }, and the read target reports it as a display-only image URL. A GenericFile has no image, and a non-https or malformed URL becomes null rather than failing the read. The shared "File alt text" lookup keeps parsing, and no provider call, change schema, stored key or hash changed.

Requires plugin-contract >=0.14.4,<0.15 for Lookup.meaning and the display image URL type; the vendored development wheel is that release. Backend 0.24.0 vendors it.

0.12.0 — new search changes use the search actions

New SEO changes must use the SEO actions; undo of earlier generic SEO changes still works. Generic *_metafield.set reads of global.title_tag, global.description_tag and seo.hidden now carry SEO_FIELD_REVERT_ONLY, meaning REVERT_ONLY. The typed *_seo.update actions and non-SEO metafields are unchanged. The refusal title directs callers to Manage search visibility.

Requires plugin-contract >=0.14.3,<0.15: older registration laws refuse this declaration. Backend 0.23.0 enforces the direct-only meaning and vendors both new wheels. No wire-contract change or consumer repin; the rollback floor stays 0.22.0. The stored seo.hidden="0" limitation is unchanged.

0.11.0 — typed search-visibility writes

Adds shopify.admin.{product,collection,page,article}_seo.update to Manage search visibility (shopify.admin.seo). Each row uses SeoFieldUpdate(seo_field=TITLE|DESCRIPTION|HIDDEN, value=...): TITLE/DESCRIPTION accept text or None; HIDDEN accepts only integer 1 to hide or None to clear the override and show again. Each field reuses the existing metafield read, compare-digest write and delete path, with the same conflict field as the generic set and an exactly typed undo. No new GraphQL document or permission is added.

This cut is additive. The generic metafield sets still accept SEO fields; a later release refuses them for new changes, so use *_seo.update. The generic change class and action declarations are unchanged. Once a consumer files a typed SEO change, ELTA must not roll back below 0.22.0; the rollback floor is otherwise 0.21.0. Inherited limitation: a stored seo.hidden="0" cannot be read by either metafield path; mapping it to absence would break exact undo, so this release does not change that behavior.

0.10.5 — repins plugin-contract 0.14.0

Repins plugin-contract 0.14.0 (>=0.14,<0.15), which lets a Source declare its removal reach and revoke page. Shopify declares neither, so its removal stays LOCAL without a URL: the grant is per shop, and a wrong link would be worse than none. No declaration, provider call, capture, lookup or write changed.

0.10.4 — an Admin 401 is a broken grant, not a missing permission

Shopify answers 401 when the stored Admin token is dead or refused, which is a reconnect rather than a scope to add, so it now maps to AUTH_INVALID. A 403 still maps to PERMISSION_MISSING with the permission to grant, and 429 and the 5xx codes are unchanged. Capture already renews one refused secret before giving up, so a token that merely expired is renewed rather than condemned.

0.10.3 — neutral customer text

The page, product, redirect and theme undo notes now name the original change instead of ELTA, and the theme-delete action description says which target is refused without naming the service. Display text only: no schema, action behavior, provider call, key or hash changed, so stored proposals decode and hash exactly as before.

0.10.2 — truthful theme-file undo notes

The three theme-file undo notes (theme_file.create, .update, .delete) now carry one static text that is true for any target theme: the shopper effect is stated as a live-theme condition, and an unpublished theme stays unseen unless someone shares its preview link. The display text changed; no schema, action behavior or provider call changed, and stored keys and hashes stay identical.

0.10.1 — callback-account-id exchange compatibility

The unused CREDENTIALS-source exchange now accepts and ignores the new optional callback_account_id, replacing the stale SP-API selling_partner_id. Repins plugin-contract 0.13.0 (>=0.13,<0.14); provider behavior is unchanged.

0.10.0 — Shopify's own levels under the 0.12 contract

Declares the eight store-object levels no other provider has (ShopifyLevel), with THEME_FILE scoped to THEME by its parent, so the shared contract keeps no Shopify word; the Shopify template prose moves out of the Protocol docstrings into the plugin. presence_reconcile is called through the protocol instead of reimplemented, comparisons use ==, and the pin becomes >=0.12,<0.13. Stored keys and hashes are unchanged.

0.9.2 — storefront renderer uses the shared identified-crawler UA

The transient storefront preview renderer now sends Keble's shared identified-crawler token ELTA/3.5 (+https://keble.ai/data-crawler) instead of ELTA/3.5 (+https://keble.ai; theme preview). Shopify's unsigned-bot storefront limits (in effect May 2026) answer other user-agent forms with HTTP 429, while this token passes the full render path (HEAD theme pin, /password POST, template GET). The UA stays identifiably ELTA/Keble and is never a browser user agent; this is interim until Web Bot Auth request signing lands (CG-80). No wire-contract change: plugin-contract stays 0.11.0.

0.9.1 — deleted-theme GraphQL NOT_FOUND

A theme read for a theme Shopify has deleted now recognizes the provider's typed GraphQL NOT_FOUND code as an absent theme. theme.delete previews it absent and applies NO_CHANGE (the copy is already gone), while theme-file writes and theme.duplicate keep their typed THEME_NOT_FOUND read issue. No wire-contract change: plugin-contract stays 0.11.0.

0.9.0 — ELTA 3.5 provider cut

Repins plugin-contract 0.11.0; adds transient storefront theme rendering, product listing, typed article images and truthful undo notes/version checks. Generated Admin dataset models preserve archive bytes; test orders are excluded, cancellations reverse net sales, and quantity-aware refund subtotals feed the same deduction. Full Admin reconnect repairs required authorization independently of optional storefront-password edits. Live storefront/provider acceptance remains separate.

0.8.1 — content File readiness

Forward-ports the reviewed ELTA 3.3.1 image-readiness fix onto the 3.4.0 / backend 0.11.x line. Uploads, image-preparation reads and READY polling share one 20-second apply deadline; rejected rows check cleanup receipts for their own created Files. The plugin-contract pin remains 0.10.0; backend's separate 0.11.1 cut is unchanged.

0.8.0 — coordinated contract repin

Repins the vendored plugin-contract to 0.10.0 for the ELTA 3.4.0 train; Shopify's provider behavior is unchanged. Consume the new wheel with backend 0.11.0.

elta-shopify is the Shopify provider plugin for ELTA. It implements elta_plugin_contract only and owns every Shopify-specific fact: the declaration (one shopify.admin source with orders, inventory and variant-cost datasets plus live theme lookups), merchant credential binding (client-credentials grant), GraphQL Admin reads, order and refund mapping, and the metric formulas.

ELTA core owns storage, timing and history; it never imports this package. The plugin never imports ELTA core or arch/.

Layout and E1 unit ownership

Path Protocol E1 unit
src/elta_shopify/declaration.py — (Shopify's declaration and its own ShopifyLevel keys) frozen
src/elta_shopify/plugin.py ProviderPlugin (handle-keyed dispatch) frozen
src/elta_shopify/admin/client.py Admin GraphQL client (new, no port source) Shopify
src/elta_shopify/theme_reader.py Shared theme GraphQL reader Theme actions and lookups
src/elta_shopify/theme_render.py Transient storefront preview reader Theme render
src/elta_shopify/lookups.py LiveLookups Themes and selected theme files
src/elta_shopify/actions.py ProviderActions router Declared writes
src/elta_shopify/publication_actions.py Online Store listing face Product publication writes
src/elta_shopify/media_actions.py Product image list face Product media writes
src/elta_shopify/authority.py ConnectionAuthority (client-credentials grant) Shopify
src/elta_shopify/readers.py DatasetReader Shopify
src/elta_shopify/dataset_documents.py Canonical dataset GraphQL operations Shopify
src/elta_shopify/_generated/ Schema-derived dataset query/node models Shopify
src/elta_shopify/mappers.py FactMapper Shopify
src/elta_shopify/calculator.py MetricCalculator Shopify

Dataset query-result models are generated offline from the pinned Admin schema; the transport client remains hand-written. No merchant Admin GraphQL client exists in the workspace (.artifacts/elta2/PORT_SOURCES.md §2), so admin/client.py is written from the Admin API contract. It posts one GraphQL document, respects the cost bucket Shopify reports in extensions.cost, and retries a THROTTLED response. Readers page GraphQL by cursor and archive each fetched page as self-contained JSON Lines parts (one provider record per line, at most 8 MiB each). Orders resume the updated_at change lane; refunds count on their processed day; inventory levels and variant costs are snapshots dayed on the capture day. The calculator computes the declared metrics from summed daily operands and leaves a ratio unmeasurable on a zero denominator.

Entered shop hosts normalize to *.myshopify.com. An invalid domain returns the typed credentials refusal before token exchange; arbitrary URLs never receive app credentials. The regional plugin signature is accepted, but Shopify accounts remain nonregional.

Version 0.5.0 exposes ShopifyActions.read_targets for the full canonical product-tag list and title, then apply sends only the approved full-list replacement. ELTA core owns policy, re-gating, diffs, and pre-write records. Shopify has no conditional tag write, so there is an unavoidable provider-side race after ELTA's final read.

The runtime-free declaration exports typed action payloads and live lookup schemas from the package root. shopify.admin.product_list is a registered, cursor-paged read_products lookup returning only product id, title and handle. Exact article reads include article/blog display labels, which do not enter signed identity, and one ShopifyArticleImage containing ArticleImage id, source URL and alt text (not a Files id). The seven exact-resource not-found codes are NOT_FOUND / CHECK_REQUEST; provider codes/messages remain support detail. The theme lookups are shopify.admin.themes and shopify.admin.theme_files, both requiring read_themes. ThemeFilesQuery selects 1–50 distinct paths from one gid://shopify/OnlineStoreTheme/<number>; include_body defaults to false, and requested bodies contain text only. Both lookups use Shopify cursors and the same shared theme reader as theme writes and page-template validation. An unknown theme returns the typed THEME_NOT_FOUND issue; a selected file that Shopify does not return yields no result row.

Online Store listing

shopify.admin.product.publish_online_store lists one existing product on the shop's Online Store publication (resolved per shop by the online_store app handle) in the default-off shopify.admin.product_publication family; its revert-only undo unpublishes only that publication and never changes product status. Both need write_publications and read_products; ELTA core refuses a missing one with PERMISSION_MISSING before any product or publication call. The drift token is the publication id plus the listed flag, so a reinstalled channel or a listing changed by someone else refuses BASE_CHANGED, and undo of a listing on a replaced publication refuses CHANGED_SINCE_APPLY. A product created in the same batch is listed by a second proposal on the returned product ref.

Product images

shopify.admin.product_media.set takes media, an ordered list of existing media ids (on the product, or a Files id to attach) and HTTPS URLs (Shopify fetches them). Apply runs: add each URL image (productUpdate(media), one per call) -> wait until READY or FAILED -> one fileUpdate that attaches listed Files and detaches omitted media (referencesToRemove; the file stays in Files, it is never deleted) -> productReorderMedia and its job -> reread. A reread showing the requested ids in order is APPLIED with created_version; a refused first write that changed nothing is REJECTED; anything else is UNKNOWN ("Images partly changed; check the product") and is never resent. An UNKNOWN row keeps the reread token as created_version only when every step settled first (each added image READY or FAILED, the reorder job done, every failure a real Shopify answer). A step still pending (an image processing or a job queued when the wait ended, a lost answer) makes the row unsettled: undo refused; re-file. It records created_version = "__ELTA_SHOPIFY_MEDIA_UNSETTLED__", which never equals a live token, so undo always refuses CHANGED_SINCE_APPLY, even after another writer sets the requested list. Only a lost apply answer (core's bare UNKNOWN, no token) keeps the value comparison. A FAILED image is reported at /media/<i>/original_source. An empty list detaches every image. Omitting a YouTube/Vimeo video is refused (it is not a File). Shopify product media in one change are limited to 250: a list of 251 items, a product already holding more than 250, or adds that would briefly take the product past 250 before the detach are refused before any write.

The drift token is media:<ordered ids> plus |missing:<ids> when a listed existing id is in neither the product nor Files. Undo is a SET back to the before ids, fenced by created_version, so a later edit or a deleted before-file refuses CHANGED_SINCE_APPLY. Fidelity is BEST_EFFORT: removing an image clears it from variants that use it, and undo does not re-select variant images. Preview facts (ProductMediaTargetFacts.media[].used_by_variants) flag each current image a variant shows, so an approval can warn only on removals that clear a variant image; variants_read_complete is false when the product has more than 100 variants or a variant shows more than 3 media.

Theme preview and file readiness (3.5 implementation)

shopify.admin.theme_render accepts a theme GID, a rooted storefront path, optional view and section_id. It pins the theme through preview_theme_id, then uses the storefront password form and _shopify_essential cookie as a visitor. It sends ELTA's own user agent, never the Admin access token or a Shopify CLI identity. Password protection is established from the actual password form, not a /password redirect. Missing/wrong passwords return PERMISSION_MISSING with STOREFRONT_PASSWORD_REQUIRED/INVALID; they do not put the Admin connection into reconsent. Rate limits and bot challenges return RATE_LIMITED with a retry instant. Redirects stay on the same shop's HTTPS origin.

The optional storefront_password may be omitted on CONNECT and is edited separately as an updatable secret on a healthy held connection. A RECONSENT_REQUIRED connection uses full Admin credentials through the existing reconnect path, never the password editor (PD-24). Admin-token refresh preserves the entered password. No lookup returns passwords or cookies. Only session cookies are cached, in process per connection/theme, for ELTA_SHOPIFY_STOREFRONT_COOKIE_TTL_SECONDS (default 1800 s). Credential changes invalidate that session. HTML is streamed to ELTA_SHOPIFY_THEME_RENDER_MAX_HTML_BYTES (default 2,000,000 bytes), marked truncated when capped, returned transiently and never cached, stored or logged. Page-reported theme name/role are absent for section-only HTML.

The themes lookup includes processing and processing_failed. Theme-file writes to a processing theme are REJECTED, retryable THEME_PROCESSING, before sending any mutation. Upserts wait at most ELTA_SHOPIFY_THEME_FILE_JOB_WAIT_SECONDS (default 10 s) for their returned job to finish; a deadline leaves the write UNKNOWN, never resends it, and the existing target body/checksum read supports reconciliation. Theme duplication remains APPLIED once Shopify returns the new theme, even if the copy is still processing.

Recorded-shape HTML fixtures use synthetic names/text only. Wave 2 runs mock tests; real storefront acceptance belongs to the separate read-only Wave 4 check.

Content image preparation

ShopifyContentSettings is the plugin-local settings owner, injected into the content writer when the action router is built. ELTA_SHOPIFY_FILE_READY_TIMEOUT_SECONDS defaults to 20 seconds per apply call and ELTA_SHOPIFY_FILE_READY_POLL_INTERVAL_SECONDS to 1 second. One request-local deadline starts at the public ShopifyActions.apply entry, before any row or upload, and is shared by every row's uploads, body/cover readiness polls, image-preparation reads (the article.delete cover restore-source reread) and processing-lock cleanup retries. Each of these, including its transport and throttle waits, is bounded by the remaining deadline; later rows needing Files are refused without uploading once it expires, and an article.delete whose restore-source reread cannot start or finish in time is REJECTED / FILE_NOT_READY before any delete is sent. Because its cover is unknown until that reread, an article.delete after earlier rows spent the budget is refused (retryable) even if it has no cover. Other rows without images can still apply. Created File ids remain per row, never shared cleanup candidates, and are recorded the moment the Admin client returns them, so a deadline cancellation after Shopify answered still leaves them for cleanup. A File whose id never reached the client is an unavoidable residual.

File creation and existing-file resolution wait for a CDN URL; processing failures reject the unsent content write at its image pointer, and readiness timeouts reject it with the existing PROVIDER_UNAVAILABLE issue (FILE_NOT_READY), which is retryable later. Upload timeouts also return REJECTED / PROVIDER_UNAVAILABLE / FILE_NOT_READY, never UNKNOWN, before sending the primary mutation. One-second polling avoids hammering an operation that polling cannot accelerate. Neither number is a Shopify guarantee. The authorized live C3 rerun measures real readiness latency; if routine preparation exceeds 20 seconds, async apply is the ELTA 3.5 answer.

The guarantee is narrow: image work is bounded at 20 s per apply, plus at most one 1 s cleanup allowance; pre-existing AdminClient throttling on non-image reads and on primary writes is unchanged. The caller's whole-apply timeout remains 30 seconds, but it is not an enforced bound on primary writes or on the page-template preflight read, a pre-existing 3.3.0 AdminClient throttle residual. A sent or ambiguous write must not be relabelled REJECTED or have referenced Files deleted.

Each rejected row attempts one fileDelete for only the Files ids it created, including a pre-delete cover copy. A fileDelete that Shopify still reports as locked or processing is retried, for the ids it did not confirm, only while the apply's shared preparation budget remains. After expiry, the one rejected row that was preparing still gets one attempt bounded by the polling interval, with no fresh processing-retry budget; later rows hold no new Files. A cleanup that leaves ids unresolved keeps the row's original issue or refusal and adds one FILE_CLEANUP_UNCONFIRMED row problem naming them, so the owner can see the remaining orphan risk. Confirmed or uncertain primary writes retain their Files because the content may reference them; existing Files references are never cleanup candidates.

0.8.1 release notes (forward-port of ELTA 3.3.1)

If Shopify throttles the main write (or a non-image read such as the page-template check), the apply may still take longer than 30s; the change then shows as not confirmed (结果待确认), never as failed. Image work alone is bounded at 20s per apply.

Checks

uv sync
uv run pytest -q
npx --yes pyright .
uv run ruff check .

tests/test_graphql_documents.py validates every module-level query and mutation against Shopify's Admin schema for DEFAULT_API_VERSION (tests/fixtures/admin_schema_<version>.graphql), and the offline action/lookup fakes also coerce each request's variables against it. After changing the API version or adding a document that reaches new schema types, regenerate the pruned fixture from Shopify's public, unauthenticated explorer proxy (no store credentials): uv run python scripts/build_admin_schema_fixture.py (or --introspection saved.json).

Dataset result generation (F-2)

Run uv run python scripts/build_dataset_models.py after changing a dataset operation or the pinned schema, then uv run python scripts/build_dataset_models.py --check. The Git-pinned script uses graphql-core==3.2.13 (also pinned in uv.lock) and records schema/operation SHA-256 in each generated module. It validates all three operations before writing. tests/test_generated_models.py checks exact declaration-key coverage, recursive selected-field totality, generated artifact parity, lossless archival and baseline fact hashes. Only dataset operations are generated; lookup/action results are outside F-2.

Generated models retain unknown fields (extra="allow"); omissions are test-visible, not runtime provider failures. Wire DateTime/Decimal values remain strings until mapping, and archival uses aliases plus exclude_unset=True, preserving unknown keys and historical absent/null fields without normalizing bytes. Explicit compatibility exceptions are Order.test (absent in older archives, represented as unknown), Refund.processedAt (historical unprocessed refunds accepted as null) and RefundLineItem.subtotalSet (absent in price-only legacy archives). They are documented in the generator.

Current refund facts use Shopify's quantity-aware subtotalSet, not the per-unit priceSet, and that same amount feeds cancellation deduction (PD-23). Price-only legacy archives keep their historical amount without multiplying quantity or rewriting bytes. Existing REFUNDS facts are re-derived under unchanged identities on the next capture; old archives are not reinterpreted.

The orders operation now captures test and cancelledAt; test orders produce no facts and complete their retirement parent so previously counted test children are removed. A cancellation is a sales reversal inside the existing shopify.refunds family, with no new family: one row per line under the stable identity (cancel:<order_id>, <line_item_id>), dated on the cancel instant's shop-local day, carrying the line's product/variant dims and the order parent. Its amount is max(0, line gross − line discounts − that line's actual refund rows known at this capture), re-derived under the same identity on every capture, so a refund arriving after the cancellation lowers it and the reversal never exceeds the line's net. It prices money only: PD-16 defines a cancellation as a monetary sales reversal, not a physical return, so refunded_quantity stays unknown rather than invented. The order count is unchanged — a placed order still counts on its creation day. No live writes run here.

Metadata

Release files for elta-shopify 0.17.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Built distribution (wheel)

Table of built distributions (wheels) for elta-shopify 0.17.1
File Interpreter ABI Platform Actions
elta_shopify-0.17.1-py3-none-any.whl Python 3 none any Details for elta_shopify-0.17.1-py3-none-any.whl

Release files / elta_shopify-0.17.1-py3-none-any.whl

Download URL elta_shopify-0.17.1-py3-none-any.whl
Size 162.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
c1b5b6619048af5cca22e502fc374e247183b9e3976c94bbacdd538750845f8e
BLAKE2b-256 checksum
How to use checksums
8cf4c9eb6a79f21813ee097f0291821fafed6f772a5335da5703927603f2f8fa
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.10.9 {"installer":{"name":"uv","version":"0.10.9","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Security for elta-shopify 0.17.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.17.1 This release

1 release file No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page