ELTA Shopify plugin 0.17.1
0.17.1 — product media display facts
ProductMediaFact(inside the display-onlyProductMediaTargetFactsofshopify.admin.product_media.set) gains optionalpreview_url(HTTPSDisplayImageUrl, from Shopify'spreview.image.url),media_type(openmediaContentTypetext) andalt_text, read in the same boundedProductMediaStatequery (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 onPRODUCT, products family): the product's whole ordered image list; the first item is the main image (see "Product images" below). It requiresread_products,write_productsandwrite_files;write_filesis declared on this action only, so a store without it getsPERMISSION_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_publicationwithshopify.admin.product.publish_online_storeand its revert-only undoshopify.admin.product.unpublish_online_store; both requirewrite_publicationsandread_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 seesFAMILY_OFFwith the existing "Turn on" remedy. - A publish is APPLIED only on empty
userErrorsplus 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)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| 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.