Theflame47 commited on
Commit
9a70e6d
·
verified ·
1 Parent(s): ad8645f

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +93 -22
app.py CHANGED
@@ -1,6 +1,7 @@
1
  import os
2
  import time
3
  import json
 
4
  from typing import Dict, Any, List, Generator, Tuple
5
 
6
  import requests
@@ -41,10 +42,22 @@ def _log(logs: List[str], msg: str):
41
  logs.append(f"[{_now()}] {msg}")
42
 
43
 
44
- def _find_first_valid_pair(logs: List[str]) -> Dict[str, Any]:
 
 
 
 
 
 
 
 
 
45
  _log(logs, "Listing blueprints")
46
  blueprints = _req("GET", "/v1/catalog/blueprints.json")
47
 
 
 
 
48
  for bp in blueprints:
49
  bp_id = str(bp["id"])
50
  _log(logs, f"Blueprint {bp_id}: fetching providers")
@@ -52,6 +65,7 @@ def _find_first_valid_pair(logs: List[str]) -> Dict[str, Any]:
52
  providers = _req("GET", f"/v1/catalog/blueprints/{bp_id}/print_providers.json")
53
  for p in providers:
54
  p_id = str(p["id"])
 
55
  _log(logs, f"Blueprint {bp_id} / Provider {p_id}: fetching variants")
56
 
57
  vr = _req(
@@ -59,22 +73,32 @@ def _find_first_valid_pair(logs: List[str]) -> Dict[str, Any]:
59
  f"/v1/catalog/blueprints/{bp_id}/print_providers/{p_id}/variants.json?show-out-of-stock=1",
60
  )
61
  variants = vr.get("variants")
62
- if isinstance(variants, list) and variants:
63
- _log(logs, f"FOUND {len(variants)} variants")
64
-
65
- return {
66
- "blueprint": bp,
67
- "provider": p,
68
- "variants": variants,
69
- "blueprintDetails": _req("GET", f"/v1/catalog/blueprints/{bp_id}.json"),
70
- "providerDetails": _req("GET", f"/v1/catalog/print_providers/{p_id}.json"),
71
- "shippingInfo": _req(
72
- "GET",
73
- f"/v1/catalog/blueprints/{bp_id}/print_providers/{p_id}/shipping.json",
74
- ),
75
- }
76
-
77
- raise RuntimeError("No blueprint/provider pair with variants found.")
 
 
 
 
 
 
 
 
 
 
78
 
79
 
80
  def _build_product(blob: Dict[str, Any], currency: str, logs: List[str]) -> Dict[str, Any]:
@@ -91,6 +115,7 @@ def _build_product(blob: Dict[str, Any], currency: str, logs: List[str]) -> Dict
91
  "color": (v.get("options") or {}).get("color"),
92
  "priceCents": cents,
93
  "price": round(cents / 100, 2) if cents is not None else None,
 
94
  })
95
 
96
  _log(logs, f"VARIANT_SNAPSHOT sample={json.dumps(snapshot[:20])}")
@@ -125,21 +150,60 @@ def _build_product(blob: Dict[str, Any], currency: str, logs: List[str]) -> Dict
125
  }
126
 
127
 
128
- def run(currency: str) -> Generator[Tuple[str, str], None, None]:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
129
  logs: List[str] = []
130
  result: Dict[str, Any] = {}
 
131
 
132
  def flush():
133
- return "\n".join(logs), json.dumps(result, indent=2)
134
 
135
  try:
136
  _log(logs, "START")
137
  yield flush()
138
 
139
- blob = _find_first_valid_pair(logs)
 
 
 
 
 
 
 
140
  yield flush()
141
 
142
- result = _build_product(blob, currency or "USD", logs)
 
 
 
 
 
 
 
 
 
 
 
 
143
  _log(logs, "DONE")
144
  yield flush()
145
 
@@ -153,10 +217,17 @@ with gr.Blocks(title="Printify Catalog Probe") as demo:
153
  gr.Markdown("Extract and normalize ONE Printify blueprint/provider into a structured JSON object.")
154
 
155
  currency = gr.Textbox(label="Currency", value="USD")
 
 
 
 
 
156
  btn = gr.Button("Run")
157
  logs = gr.Textbox(label="Logs", lines=18)
158
  out = gr.Textbox(label="Output JSON", lines=18)
 
159
 
160
- btn.click(run, inputs=[currency], outputs=[logs, out])
 
161
 
162
  demo.queue(concurrency_count=1).launch()
 
1
  import os
2
  import time
3
  import json
4
+ import tempfile
5
  from typing import Dict, Any, List, Generator, Tuple
6
 
7
  import requests
 
42
  logs.append(f"[{_now()}] {msg}")
43
 
44
 
45
+ def _list_shops(logs: List[str]) -> List[Dict[str, Any]]:
46
+ _log(logs, "Listing shops")
47
+ shops = _req("GET", "/v1/shops.json")
48
+ if not isinstance(shops, list):
49
+ raise RuntimeError("Unexpected shops response.")
50
+ _log(logs, f"FOUND {len(shops)} shops")
51
+ return shops
52
+
53
+
54
+ def _collect_phase_a(shop_id: int, logs: List[str]) -> Dict[str, Any]:
55
  _log(logs, "Listing blueprints")
56
  blueprints = _req("GET", "/v1/catalog/blueprints.json")
57
 
58
+ templates: List[Dict[str, Any]] = []
59
+ scanned_pairs = 0
60
+
61
  for bp in blueprints:
62
  bp_id = str(bp["id"])
63
  _log(logs, f"Blueprint {bp_id}: fetching providers")
 
65
  providers = _req("GET", f"/v1/catalog/blueprints/{bp_id}/print_providers.json")
66
  for p in providers:
67
  p_id = str(p["id"])
68
+ scanned_pairs += 1
69
  _log(logs, f"Blueprint {bp_id} / Provider {p_id}: fetching variants")
70
 
71
  vr = _req(
 
73
  f"/v1/catalog/blueprints/{bp_id}/print_providers/{p_id}/variants.json?show-out-of-stock=1",
74
  )
75
  variants = vr.get("variants")
76
+ if not (isinstance(variants, list) and variants):
77
+ continue
78
+
79
+ _log(logs, f"FOUND {len(variants)} variants")
80
+
81
+ blob = {
82
+ "blueprint": bp,
83
+ "provider": p,
84
+ "variants": variants,
85
+ "blueprintDetails": _req("GET", f"/v1/catalog/blueprints/{bp_id}.json"),
86
+ "providerDetails": _req("GET", f"/v1/catalog/print_providers/{p_id}.json"),
87
+ "shippingInfo": _req(
88
+ "GET",
89
+ f"/v1/catalog/blueprints/{bp_id}/print_providers/{p_id}/shipping.json",
90
+ ),
91
+ }
92
+
93
+ templates.append({
94
+ "shop_id": shop_id,
95
+ "blueprint_id": int(bp_id),
96
+ "print_provider_id": int(p_id),
97
+ "raw": blob,
98
+ })
99
+
100
+ _log(logs, f"PHASE_A_DONE templates={len(templates)} scanned_pairs={scanned_pairs}")
101
+ return {"shop_id": shop_id, "templates": templates}
102
 
103
 
104
  def _build_product(blob: Dict[str, Any], currency: str, logs: List[str]) -> Dict[str, Any]:
 
115
  "color": (v.get("options") or {}).get("color"),
116
  "priceCents": cents,
117
  "price": round(cents / 100, 2) if cents is not None else None,
118
+ "placeholders": v.get("placeholders") or [],
119
  })
120
 
121
  _log(logs, f"VARIANT_SNAPSHOT sample={json.dumps(snapshot[:20])}")
 
150
  }
151
 
152
 
153
+ def fetch_shops() -> Tuple[str, gr.Dropdown]:
154
+ logs: List[str] = []
155
+ shops = _list_shops(logs)
156
+
157
+ choices = []
158
+ default_val = None
159
+ for s in shops:
160
+ sid = s.get("id")
161
+ title = s.get("title") or "untitled"
162
+ chan = s.get("sales_channel") or "unknown"
163
+ label = f"{title} ({chan}) — {sid}"
164
+ val = str(sid)
165
+ choices.append((label, val))
166
+ if (title or "").strip().lower() == "atheria":
167
+ default_val = val
168
+
169
+ return "\n".join(logs), gr.Dropdown.update(choices=choices, value=default_val)
170
+
171
+
172
+ def run(currency: str, shop_id: str) -> Generator[Tuple[str, str, str], None, None]:
173
  logs: List[str] = []
174
  result: Dict[str, Any] = {}
175
+ dl_path = ""
176
 
177
  def flush():
178
+ return "\n".join(logs), json.dumps(result, indent=2), dl_path
179
 
180
  try:
181
  _log(logs, "START")
182
  yield flush()
183
 
184
+ if not shop_id:
185
+ raise RuntimeError("Missing shop_id. Click Fetch Shops and select Atheria.")
186
+
187
+ sid = int(str(shop_id).strip())
188
+ _log(logs, f"USING_SHOP_ID {sid}")
189
+ yield flush()
190
+
191
+ phase_a = _collect_phase_a(sid, logs)
192
  yield flush()
193
 
194
+ templates = phase_a.get("templates") or []
195
+ if templates:
196
+ first_raw = (templates[0].get("raw") or {})
197
+ result = _build_product(first_raw, currency or "USD", logs)
198
+ else:
199
+ result = {"shop_id": sid, "templates": []}
200
+
201
+ fd, path = tempfile.mkstemp(prefix="phase_a_", suffix=".json")
202
+ os.close(fd)
203
+ with open(path, "w", encoding="utf-8") as f:
204
+ json.dump(phase_a, f, indent=2)
205
+ dl_path = path
206
+
207
  _log(logs, "DONE")
208
  yield flush()
209
 
 
217
  gr.Markdown("Extract and normalize ONE Printify blueprint/provider into a structured JSON object.")
218
 
219
  currency = gr.Textbox(label="Currency", value="USD")
220
+
221
+ fetch_btn = gr.Button("Fetch Shops")
222
+ shops_log = gr.Textbox(label="Shop Logs", lines=6)
223
+ shop = gr.Dropdown(label="Shop (select Atheria)", choices=[])
224
+
225
  btn = gr.Button("Run")
226
  logs = gr.Textbox(label="Logs", lines=18)
227
  out = gr.Textbox(label="Output JSON", lines=18)
228
+ dl = gr.File(label="Download Phase A JSON")
229
 
230
+ fetch_btn.click(fetch_shops, inputs=[], outputs=[shops_log, shop])
231
+ btn.click(run, inputs=[currency, shop], outputs=[logs, out, dl])
232
 
233
  demo.queue(concurrency_count=1).launch()