Theflame47 commited on
Commit
63230f6
·
verified ·
1 Parent(s): b34569c

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +37 -91
app.py CHANGED
@@ -9,7 +9,6 @@ import gradio as gr
9
  import base64
10
 
11
  PRINTIFY_BASE = "https://api.printify.com"
12
- DEFAULT_BASE_PRICE = 24.99
13
  GRID_FILENAME = "grid.png"
14
 
15
 
@@ -90,7 +89,9 @@ def _build_product(blob: Dict[str, Any], currency: str, logs: List[str]) -> Dict
90
 
91
  snapshot = []
92
  for v in variants:
93
- cents = v.get("price")
 
 
94
  cents = int(cents) if isinstance(cents, (int, str)) and str(cents).isdigit() else None
95
 
96
  ph = v.get("placeholders")
@@ -112,8 +113,8 @@ def _build_product(blob: Dict[str, Any], currency: str, logs: List[str]) -> Dict
112
  "sku": v.get("sku"),
113
  "size": (v.get("options") or {}).get("size"),
114
  "color": (v.get("options") or {}).get("color"),
115
- "priceCents": cents,
116
- "price": round(cents / 100, 2) if cents is not None else None,
117
  "placeholders": placeholders,
118
  })
119
 
@@ -149,8 +150,10 @@ def _build_product(blob: Dict[str, Any], currency: str, logs: List[str]) -> Dict
149
  if ph.get("position")
150
  })
151
 
152
- all_cents = [v["priceCents"] for v in snapshot if v["priceCents"] is not None]
153
- min_price = round(min(all_cents) / 100, 2) if all_cents else DEFAULT_BASE_PRICE
 
 
154
 
155
  colors = sorted({v["color"] for v in snapshot if v["color"]})
156
  sizes = sorted({v["size"] for v in snapshot if v["size"]})
@@ -237,6 +240,29 @@ def _upload_grid_from_file(logs: List[str]) -> Dict[str, Any]:
237
  )
238
  return resp
239
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
240
 
241
  def _scale_fill(ph_w: float, ph_h: float, img_w: float, img_h: float) -> float:
242
  if ph_w <= 0 or ph_h <= 0 or img_w <= 0 or img_h <= 0:
@@ -318,7 +344,7 @@ def _create_one_product_with_grid(
318
  "print_provider_id": int(provider_id),
319
  "variants": [{
320
  "id": int(variant_id),
321
- "price": 1,
322
  "is_enabled": True,
323
  }],
324
  "print_areas": [{
@@ -330,7 +356,8 @@ def _create_one_product_with_grid(
330
  _log(
331
  logs,
332
  f"PHASE_B_CREATE shop_id={shop_id} "
333
- f"blueprint_id={bp_id} provider_id={provider_id} variant_id={variant_id}",
 
334
  )
335
 
336
  created = _req(
@@ -428,97 +455,16 @@ def phase_b(currency: str) -> Generator[Tuple[str, str], None, None]:
428
  yield flush()
429
 
430
 
431
- def phase_c(currency: str, product_id: str) -> Generator[Tuple[str, str], None, None]:
432
- logs: List[str] = []
433
- result: Dict[str, Any] = {}
434
-
435
- def flush():
436
- return "\n".join(logs), json.dumps(result, indent=2)
437
-
438
- try:
439
- _log(logs, "PHASE_C_START")
440
- yield flush()
441
-
442
- if not product_id or not str(product_id).strip():
443
- raise RuntimeError("Missing product_id.")
444
-
445
- shops = _req("GET", "/v1/shops.json")
446
- _log(logs, f"SHOP_LIST {json.dumps(shops)}")
447
- yield flush()
448
-
449
- shop_id = _pick_shop_id(shops)
450
- _log(logs, f"SHOP_ID {shop_id}")
451
- yield flush()
452
-
453
- pid = str(product_id).strip()
454
- _log(logs, f"PHASE_C_GET_PRODUCT product_id={pid}")
455
- prod = _req("GET", f"/v1/shops/{shop_id}/products/{pid}.json")
456
- result["productDetails"] = prod
457
- yield flush()
458
-
459
- variants = prod.get("variants") or []
460
- if not isinstance(variants, list) or not variants:
461
- raise RuntimeError("Product details missing variants.")
462
-
463
- update_variants = []
464
- for v in variants:
465
- vid = v.get("id")
466
- cost = v.get("cost")
467
- if vid is None or cost is None:
468
- _log(logs, f"COST_MISSING variant_id={vid} cost={cost}")
469
- continue
470
- try:
471
- vid_i = int(vid)
472
- cost_i = int(cost)
473
- except Exception:
474
- _log(logs, f"COST_BAD variant_id={vid} cost={cost}")
475
- continue
476
-
477
- update_variants.append({
478
- "id": vid_i,
479
- "price": cost_i,
480
- "is_enabled": bool(v.get("is_enabled")),
481
- })
482
-
483
- _log(
484
- logs,
485
- f"PRICE_RECONCILE variant_id={vid_i} cost={cost_i} "
486
- f"old_price={v.get('price')} enabled={bool(v.get('is_enabled'))}",
487
- )
488
-
489
- if not update_variants:
490
- raise RuntimeError("No variants with cost found to reconcile pricing.")
491
-
492
- payload = {"variants": update_variants}
493
-
494
- _log(logs, f"PHASE_C_UPDATE_PRICES count={len(update_variants)}")
495
- updated = _req("PUT", f"/v1/shops/{shop_id}/products/{pid}.json", json_body=payload)
496
- result["priceUpdateResponse"] = updated
497
- yield flush()
498
-
499
- _log(logs, "PHASE_C_DONE")
500
- yield flush()
501
-
502
- except Exception as e:
503
- _log(logs, f"ERROR: {e}")
504
- result = {"error": str(e)}
505
- yield flush()
506
-
507
-
508
  with gr.Blocks(title="Printify Catalog Probe") as demo:
509
  gr.Markdown("Extract and normalize ONE Printify blueprint/provider into a structured JSON object.")
510
 
511
  currency = gr.Textbox(label="Currency", value="USD")
512
- product_id = gr.Textbox(label="Product ID (for Phase C)", value="")
513
-
514
- btn = gr.Button("Run (A)")
515
- btn_b = gr.Button("Phase B (Create Test)")
516
- btn_c = gr.Button("Phase C (Pricing Reconciliation)")
517
  logs = gr.Textbox(label="Logs", lines=18)
518
  out = gr.Textbox(label="Output JSON", lines=18)
519
 
520
  btn.click(run, inputs=[currency], outputs=[logs, out])
521
  btn_b.click(phase_b, inputs=[currency], outputs=[logs, out])
522
- btn_c.click(phase_c, inputs=[currency, product_id], outputs=[logs, out])
523
 
524
  demo.queue().launch()
 
9
  import base64
10
 
11
  PRINTIFY_BASE = "https://api.printify.com"
 
12
  GRID_FILENAME = "grid.png"
13
 
14
 
 
89
 
90
  snapshot = []
91
  for v in variants:
92
+ cents = v.get("cost")
93
+ if cents is None:
94
+ cents = v.get("price")
95
  cents = int(cents) if isinstance(cents, (int, str)) and str(cents).isdigit() else None
96
 
97
  ph = v.get("placeholders")
 
113
  "sku": v.get("sku"),
114
  "size": (v.get("options") or {}).get("size"),
115
  "color": (v.get("options") or {}).get("color"),
116
+ "costCents": cents,
117
+ "cost": round(cents / 100, 2) if cents is not None else None,
118
  "placeholders": placeholders,
119
  })
120
 
 
150
  if ph.get("position")
151
  })
152
 
153
+ all_cost_cents = [v["costCents"] for v in snapshot if v["costCents"] is not None]
154
+ if not all_cost_cents:
155
+ raise RuntimeError("No variant cost returned by API (expected 'cost' or 'price' in cents).")
156
+ min_price = round(min(all_cost_cents) / 100, 2)
157
 
158
  colors = sorted({v["color"] for v in snapshot if v["color"]})
159
  sizes = sorted({v["size"] for v in snapshot if v["size"]})
 
240
  )
241
  return resp
242
 
243
+ with open(path, "rb") as f:
244
+ r = requests.post(
245
+ f"{PRINTIFY_BASE}/v1/uploads/images.json",
246
+ headers=_auth_headers(),
247
+ files={"file": (GRID_FILENAME, f, "image/png")},
248
+ timeout=60,
249
+ )
250
+
251
+ if r.status_code >= 400:
252
+ raise RuntimeError(f"UPLOAD_HTTP {r.status_code}: {r.text[:2000]}")
253
+
254
+ resp = r.json()
255
+ if not isinstance(resp, dict) or not resp.get("id"):
256
+ raise RuntimeError(f"Unexpected upload response: {str(resp)[:500]}")
257
+
258
+ _log(
259
+ logs,
260
+ f"GRID_UPLOAD id={resp.get('id')} "
261
+ f"file={resp.get('file_name') or resp.get('name')} "
262
+ f"w={resp.get('width')} h={resp.get('height')}",
263
+ )
264
+ return resp
265
+
266
 
267
  def _scale_fill(ph_w: float, ph_h: float, img_w: float, img_h: float) -> float:
268
  if ph_w <= 0 or ph_h <= 0 or img_w <= 0 or img_h <= 0:
 
344
  "print_provider_id": int(provider_id),
345
  "variants": [{
346
  "id": int(variant_id),
347
+ "price": int(product_info.get("price") * 100),
348
  "is_enabled": True,
349
  }],
350
  "print_areas": [{
 
356
  _log(
357
  logs,
358
  f"PHASE_B_CREATE shop_id={shop_id} "
359
+ f"blueprint_id={bp_id} provider_id={provider_id} variant_id={variant_id} "
360
+ f"price_cents={int(product_info.get('price') * 100)}",
361
  )
362
 
363
  created = _req(
 
455
  yield flush()
456
 
457
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
458
  with gr.Blocks(title="Printify Catalog Probe") as demo:
459
  gr.Markdown("Extract and normalize ONE Printify blueprint/provider into a structured JSON object.")
460
 
461
  currency = gr.Textbox(label="Currency", value="USD")
462
+ btn = gr.Button("Run")
463
+ btn_b = gr.Button("Phase B (Test)")
 
 
 
464
  logs = gr.Textbox(label="Logs", lines=18)
465
  out = gr.Textbox(label="Output JSON", lines=18)
466
 
467
  btn.click(run, inputs=[currency], outputs=[logs, out])
468
  btn_b.click(phase_b, inputs=[currency], outputs=[logs, out])
 
469
 
470
  demo.queue().launch()