← back to Dw Material Envelope Canary
chore: lint, refactor, TOK guard, v1.0.1 (session close)
1a28aa59910ba305781cf3499434e6eb57bb88f8 · 2026-07-07 12:47:40 -0700 · steve
Files touched
A VERSIONM __pycache__/check-bulk.cpython-314.pycM __pycache__/check.cpython-314.pycM check-bulk.pyM check.py
Diff
commit 1a28aa59910ba305781cf3499434e6eb57bb88f8
Author: steve <steve@designerwallcoverings.com>
Date: Tue Jul 7 12:47:40 2026 -0700
chore: lint, refactor, TOK guard, v1.0.1 (session close)
---
VERSION | 1 +
__pycache__/check-bulk.cpython-314.pyc | Bin 7381 -> 8008 bytes
__pycache__/check.cpython-314.pyc | Bin 8613 -> 9000 bytes
check-bulk.py | 35 ++++++++++++++++++++++-----------
check.py | 15 ++++++++------
5 files changed, 33 insertions(+), 18 deletions(-)
diff --git a/VERSION b/VERSION
new file mode 100644
index 0000000..7dea76e
--- /dev/null
+++ b/VERSION
@@ -0,0 +1 @@
+1.0.1
diff --git a/__pycache__/check-bulk.cpython-314.pyc b/__pycache__/check-bulk.cpython-314.pyc
index b2989af..ca4456d 100644
Binary files a/__pycache__/check-bulk.cpython-314.pyc and b/__pycache__/check-bulk.cpython-314.pyc differ
diff --git a/__pycache__/check.cpython-314.pyc b/__pycache__/check.cpython-314.pyc
index 49cd414..0027881 100644
Binary files a/__pycache__/check.cpython-314.pyc and b/__pycache__/check.cpython-314.pyc differ
diff --git a/check-bulk.py b/check-bulk.py
index e6cbb33..d68b38c 100644
--- a/check-bulk.py
+++ b/check-bulk.py
@@ -11,10 +11,13 @@ def load_env():
if os.path.exists(p):
for ln in open(p):
if "=" in ln and not ln.strip().startswith("#"):
- k, v = ln.strip().split("=", 1); os.environ.setdefault(k, v.strip().strip('"').strip("'"))
+ k, v = ln.strip().split("=", 1)
+ os.environ.setdefault(k, v.strip().strip('"').strip("'"))
load_env()
DOMAIN = os.environ.get("SHOPIFY_STORE_DOMAIN", "designer-laboratory-sandbox.myshopify.com")
TOK = os.environ.get("SHOPIFY_ADMIN_TOKEN") or os.environ.get("SHOPIFY_ADMIN_ACCESS_TOKEN")
+if not TOK:
+ sys.exit("ERROR: SHOPIFY_ADMIN_TOKEN not set (check ~/Projects/Designer-Wallcoverings/.env)")
URL = f"https://{DOMAIN}/admin/api/2024-01/graphql.json"
CNCP = "http://127.0.0.1:3333/api/parking_lot"
def gql(q):
@@ -26,9 +29,11 @@ def is_env(v):
START = 'mutation { bulkOperationRunQuery(query: """{ products { edges { node { id handle metafields { edges { node { namespace key value } } } } } } }""") { bulkOperation { id status } userErrors { message } } }'
POLL = '{ currentBulkOperation { status url objectCount } }'
def main():
+ os.makedirs(os.path.join(HERE, "data"), exist_ok=True)
r = gql(START)
ue = r["data"]["bulkOperationRunQuery"]["userErrors"]
- if ue: print("start err", ue); return 2
+ if ue:
+ print("start err", ue); return 2
while True:
op = gql(POLL)["data"]["currentBulkOperation"]
if op["status"] in ("COMPLETED", "FAILED", "CANCELED"): break
@@ -38,18 +43,24 @@ def main():
path = os.path.join(HERE, "data", "bulk.jsonl")
urllib.request.urlretrieve(op["url"], path)
hits = {}; nprod = 0; nmf = 0
- for ln in open(path):
- try: o = json.loads(ln)
- except: continue
- if "namespace" in o and "key" in o:
- nmf += 1
- if is_env(o.get("value")):
- hits.setdefault(f'{o["namespace"]}.{o["key"]}', 0); hits[f'{o["namespace"]}.{o["key"]}'] += 1
- elif "handle" in o: nprod += 1
+ with open(path) as fh:
+ for ln in fh:
+ try:
+ o = json.loads(ln)
+ except (json.JSONDecodeError, ValueError):
+ continue
+ if "namespace" in o and "key" in o:
+ nmf += 1
+ if is_env(o.get("value")):
+ field_key = f'{o["namespace"]}.{o["key"]}'
+ hits[field_key] = hits.get(field_key, 0) + 1
+ elif "handle" in o:
+ nprod += 1
os.remove(path) # 800MB — don't keep
verdict = "FAIL" if hits else "PASS"
- json.dump({"ts": datetime.datetime.now().isoformat(), "products": nprod, "metafields": nmf,
- "verdict": verdict, "hits": hits}, open(os.path.join(HERE, "data", "latest-bulk.json"), "w"), indent=1)
+ with open(os.path.join(HERE, "data", "latest-bulk.json"), "w") as fh:
+ json.dump({"ts": datetime.datetime.now().isoformat(), "products": nprod, "metafields": nmf,
+ "verdict": verdict, "hits": hits}, fh, indent=1)
print(f"{verdict}: {nprod} products, {nmf} metafields, {sum(hits.values())} enveloped across {len(hits)} keys")
if hits:
try:
diff --git a/check.py b/check.py
index 5872ac9..b02658f 100644
--- a/check.py
+++ b/check.py
@@ -23,6 +23,8 @@ def load_env():
load_env()
DOMAIN = os.environ.get("SHOPIFY_STORE_DOMAIN", "designer-laboratory-sandbox.myshopify.com")
TOK = os.environ.get("SHOPIFY_ADMIN_TOKEN") or os.environ.get("SHOPIFY_ADMIN_ACCESS_TOKEN")
+if not TOK:
+ sys.exit("ERROR: SHOPIFY_ADMIN_TOKEN not set (check ~/Projects/Designer-Wallcoverings/.env)")
URL = f"https://{DOMAIN}/admin/api/2024-01/graphql.json"
CNCP = "http://127.0.0.1:3333/api/parking_lot"
@@ -37,15 +39,15 @@ def gql(cursor):
body = json.dumps({"query": QUERY, "variables": {"c": cursor}}).encode()
req = urllib.request.Request(URL, data=body, headers={
"X-Shopify-Access-Token": TOK, "Content-Type": "application/json"})
- for a in range(6):
+ for attempt in range(6):
try:
with urllib.request.urlopen(req, timeout=60) as r:
d = json.loads(r.read())
if d.get("errors") and any("throttl" in str(e).lower() for e in d["errors"]):
- time.sleep(2 + a); continue
+ time.sleep(2 + attempt); continue
return d
except Exception:
- time.sleep(2 + a)
+ time.sleep(2 + attempt)
raise SystemExit("gql failed")
def is_env(v):
@@ -55,16 +57,16 @@ def is_env(v):
return isinstance(v, str) and "single_line_text_field" in v
def main():
+ os.makedirs(os.path.join(HERE, "data"), exist_ok=True)
total = 0; bad = []
cursor = None
while True:
conn = gql(cursor)["data"]["products"]
for e in conn["edges"]:
n = e["node"]; total += 1
- for i in range(len(CHECK_KEYS)):
+ for i, (ns, k) in enumerate(CHECK_KEYS):
mf = n.get(f"k{i}")
if mf and is_env(mf.get("value")):
- ns, k = CHECK_KEYS[i]
bad.append({"handle": n["handle"], "status": n["status"], "field": f"{ns}.{k}"})
break
if not conn["pageInfo"]["hasNextPage"]:
@@ -73,7 +75,8 @@ def main():
verdict = "FAIL" if bad else "PASS"
result = {"ts": datetime.datetime.now().isoformat(), "scanned": total,
"broken": len(bad), "verdict": verdict, "sample": bad[:20]}
- json.dump(result, open(os.path.join(HERE, "data", "latest.json"), "w"), indent=1)
+ with open(os.path.join(HERE, "data", "latest.json"), "w") as fh:
+ json.dump(result, fh, indent=1)
print(f"{verdict}: scanned {total}, {len(bad)} envelope-corrupted")
if bad:
try:
← f11d1f0 canary: robust envelope detector + weekly all-metafields bul
·
back to Dw Material Envelope Canary
·
auto-save: 2026-07-08T06:04:21 (1 files) — data/latest.json 97d15db →