← back to Kravet Sheet Sync 2026 04 20

fix_test_images.py

52 lines

#!/usr/bin/env python3
"""Replace placeholder images on the 2 test products with real Brandfolder URLs."""
import json, urllib.request

TOKEN=os.environ.get('SHOPIFY_ADMIN_TOKEN','')
URL='https://designer-laboratory-sandbox.myshopify.com/admin/api/2024-10/graphql.json'

FIXES = [
  {"pid": "gid://shopify/Product/7821427441715", "dw_sku": "DWKK-141031",
   "real_image": "https://cdn.brandfolder.io/UT8SLOWQ/at/q45qrr-1lxo3s-1588d2/109-11053_CS.jpg?width=2000&height=2000&pad=true",
   "alt": "Acacia Grey & White | Cole & Son"},
  {"pid": "gid://shopify/Product/7821427474483", "dw_sku": "DWKK-141042",
   "real_image": "https://cdn.brandfolder.io/UT8SLOWQ/at/q45qtr-b17qw8-9az01h/94-4021_CS.jpg?width=2000&height=2000&pad=true",
   "alt": "Albery Aqua | Cole & Son"},
]

def gql(q,v=None):
    body=json.dumps({"query":q,"variables":v or {}}).encode()
    r=urllib.request.urlopen(urllib.request.Request(URL,data=body,method="POST",
      headers={"Content-Type":"application/json","X-Shopify-Access-Token":TOKEN}),timeout=30)
    d=json.loads(r.read())
    if "errors" in d: raise RuntimeError(d["errors"])
    return d["data"]

GET_MEDIA = """query($id:ID!){ product(id:$id){ media(first:20){ nodes{ id mediaContentType ... on MediaImage{ image{ url } } } } } }"""
DEL_MEDIA = """mutation($id:ID!,$ids:[ID!]!){ productDeleteMedia(productId:$id,mediaIds:$ids){ deletedMediaIds mediaUserErrors{ field message } } }"""
CREATE_MEDIA = """mutation($id:ID!,$media:[CreateMediaInput!]!){ productCreateMedia(productId:$id,media:$media){ media{ ... on MediaImage{ id status } } mediaUserErrors{ field message } } }"""

for f in FIXES:
    print(f"\n=== {f['dw_sku']} ===")
    cur = gql(GET_MEDIA, {"id": f["pid"]})["product"]["media"]["nodes"]
    print(f"  current media: {len(cur)}")
    # Delete ALL existing images — we're replacing with the real Brandfolder source
    img_ids = [m["id"] for m in cur if m["mediaContentType"] == "IMAGE"]
    if img_ids:
        d = gql(DEL_MEDIA, {"id": f["pid"], "ids": img_ids})
        errs = d["productDeleteMedia"]["mediaUserErrors"]
        print(f"  deleted {len(d['productDeleteMedia']['deletedMediaIds'])} image(s); errs={errs}")
    # Attach new
    a = gql(CREATE_MEDIA, {"id": f["pid"], "media":[{
        "originalSource": f["real_image"],
        "mediaContentType": "IMAGE",
        "alt": f["alt"],
    }]})
    errs = a["productCreateMedia"]["mediaUserErrors"]
    if errs:
        print(f"  ATTACH ERRORS: {errs}")
    else:
        m = a["productCreateMedia"]["media"][0]
        print(f"  attached: {m['id']} status={m['status']}")
    print(f"  src: {f['real_image']}")