← back to Kravet Sheet Sync 2026 04 20
attach_images.py
95 lines
#!/usr/bin/env python3
"""
Build Kravet image URLs from sheet filenames and attach to the 2 test products.
URL pattern: https://www.kravet.com/media/catalog/product + {sheet.image_file_hires}
"""
import json, subprocess, urllib.request, urllib.error
TOKEN = os.environ.get('SHOPIFY_ADMIN_TOKEN','')
URL = 'https://designer-laboratory-sandbox.myshopify.com/admin/api/2024-10/graphql.json'
KRAVET_BASE = 'https://www.kravet.com/media/catalog/product'
TARGETS = [
{"pid": "gid://shopify/Product/7821427441715",
"dw_sku": "DWKK-141031", "mfr_sku": "109/11053.CS.0"},
{"pid": "gid://shopify/Product/7821427474483",
"dw_sku": "DWKK-141042", "mfr_sku": "94/4021.CS.0"},
]
def pg_rows(q):
r = subprocess.run(["ssh","root@45.61.58.125",
f'PGPASSWORD=DW2024! psql -h 127.0.0.1 -U dw_admin -d dw_unified -At -F "|" -c "{q}"'],
capture_output=True, text=True, check=True)
return [line.split("|") for line in r.stdout.strip().split("\n") if line]
def gql(q, v=None):
body = json.dumps({"query": q, "variables": v or {}}).encode()
req = urllib.request.Request(URL, data=body, method="POST",
headers={"Content-Type":"application/json","X-Shopify-Access-Token":TOKEN})
d = json.loads(urllib.request.urlopen(req, timeout=30).read())
if "errors" in d: raise RuntimeError(d["errors"])
return d["data"]
def probe(url: str) -> int:
try:
req = urllib.request.Request(url, headers={"User-Agent":"Mozilla/5.0"}, method="HEAD")
return urllib.request.urlopen(req, timeout=10).status
except urllib.error.HTTPError as e:
return e.code
except Exception:
return 0
CREATE_MEDIA = """
mutation productCreateMedia($productId: ID!, $media: [CreateMediaInput!]!) {
productCreateMedia(productId: $productId, media: $media) {
media { ... on MediaImage { id status image { url } } }
mediaUserErrors { field message }
}
}
"""
for t in TARGETS:
# Fetch sheet image filenames
esc = t["mfr_sku"].replace("'", "''")
rows = pg_rows(f"SELECT image_file_hires, image_file_lores FROM kravet_sheet_fields "
f"WHERE mfr_sku_raw = '{esc}'")
if not rows:
print(f"{t['dw_sku']}: no sheet row for {t['mfr_sku']}"); continue
hires, lores = rows[0]
hires_url = KRAVET_BASE + hires if hires else ""
lores_url = KRAVET_BASE + lores if lores else ""
print(f"\n=== {t['dw_sku']} ({t['mfr_sku']}) ===")
for label, u in [("HIRES", hires_url), ("LORES", lores_url)]:
if u:
print(f" {label} {probe(u)} {u}")
# Attach HIRES as primary (Shopify fetches async)
if not hires_url: continue
data = gql(CREATE_MEDIA, {
"productId": t["pid"],
"media": [{
"originalSource": hires_url,
"mediaContentType": "IMAGE",
"alt": f"{t['mfr_sku']} — Kravet manufacturer image",
}],
})
errs = data["productCreateMedia"]["mediaUserErrors"]
if errs:
print(f" ERROR: {errs}")
else:
m = data["productCreateMedia"]["media"][0]
print(f" attached: {m['id']} status={m['status']}")
# Persist to kravet_catalog.image_url
esc_sku = t["dw_sku"].replace("'", "''")
pg_rows(f"UPDATE kravet_catalog SET image_url = '{hires_url}' "
f"WHERE dw_sku = '{esc_sku}'")
print(f" pg: kravet_catalog.image_url set")