Technologic101 commited on
Commit
09f7b3d
·
1 Parent(s): 5896930

task: converts analyzer to Anthropic API

Browse files
data_collection/analyze_designs.py CHANGED
@@ -5,18 +5,36 @@ import asyncio
5
  import base64
6
  from openai import AsyncOpenAI
7
  from dotenv import load_dotenv
8
- from anthropic import Anthropic
9
  from .prompts import get_prompt
10
 
11
  load_dotenv()
12
- client = Anthropic()
13
 
14
  VISION_MODEL = "claude-3-7-sonnet-20250219"
15
 
16
- async def analyze_screenshot(design_id: str, design_path: Path):
17
- """Analyze screenshots and return description, categories, and visual characteristics"""
 
 
 
 
 
 
 
 
 
 
 
18
  try:
19
- # Check files exist
 
 
 
 
 
 
 
20
  metadata_path = design_path / "metadata.json"
21
  desktop_img = design_path / "screenshot_desktop.png"
22
  mobile_img = design_path / "screenshot_mobile.png"
@@ -41,68 +59,79 @@ async def analyze_screenshot(design_id: str, design_path: Path):
41
 
42
  print(f"Analyzing design {design_id}...")
43
 
44
- # Get response first
45
- response = await client.chat.completions.create(
46
  model=VISION_MODEL,
47
- messages=[
48
- {
49
- "role": "system",
50
- "content": get_prompt(detailed=True)
51
- },
52
- {
53
- "role": "user",
54
- "content": [
55
- {
56
- "type": "text",
57
- "text": "Analyze this visual design. Output only the JSON object."
58
- },
59
- {
60
- "type": "image_url",
61
- "image_url": {
62
- "url": f"data:image/png;base64,{desktop_base64}",
63
- "detail": "high"
64
- }
65
- },
66
- {
67
- "type": "image_url",
68
- "image_url": {
69
- "url": f"data:image/png;base64,{mobile_base64}",
70
- "detail": "high"
71
- }
72
  }
73
- ]
74
- }
75
- ],
76
- max_tokens=1000
 
 
 
 
 
 
 
77
  )
78
 
79
- # Then get the content
80
- response_content = response.choices[0].message.content.strip()
81
 
82
- # Ensure the response is not empty
83
  if not response_content:
84
  print(f"Empty response for design {design_id}")
85
  return design_id, None, None, None
86
 
87
  # Extract JSON content from markdown code block
88
  if "```json" in response_content:
89
- # Remove the ```json prefix and ``` suffix
90
  response_content = response_content.split("```json")[1].split("```")[0].strip()
91
 
92
- # Parse the JSON response
93
  try:
94
  analysis = json.loads(response_content)
95
 
96
- # Update metadata with all fields
97
- metadata.update(analysis)
 
 
 
 
98
 
99
- # Save updated metadata
100
- with open(metadata_path, "w") as f:
101
- json.dump(metadata, f, indent=2)
102
 
103
  print(f"Successfully analyzed design {design_id}")
104
- # Return visual_characteristics as fourth element
105
- return design_id, analysis["description"]["summary"], analysis["categories"], analysis["visual_characteristics"]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
106
 
107
  except json.JSONDecodeError as e:
108
  print(f"Error parsing JSON response for design {design_id}: {str(e)}")
 
5
  import base64
6
  from openai import AsyncOpenAI
7
  from dotenv import load_dotenv
8
+ from anthropic import AsyncAnthropic
9
  from .prompts import get_prompt
10
 
11
  load_dotenv()
12
+ client = AsyncAnthropic(api_key=os.getenv("ANTHROPIC_API_KEY"))
13
 
14
  VISION_MODEL = "claude-3-7-sonnet-20250219"
15
 
16
+ async def analyze_screenshot(design_id: str, design_path: Path, detailed: bool = True, output_path: Path = None):
17
+ """
18
+ Analyze screenshots and return description, categories, and visual characteristics
19
+
20
+ Args:
21
+ design_id (str): ID of the design to analyze
22
+ design_path (Path): Path to the design's source files
23
+ detailed (bool): Whether to use detailed or core analysis prompt
24
+ output_path (Path): Path to save analysis results. If None, uses analyses/default
25
+
26
+ Returns:
27
+ tuple: (design_id, description, categories, visual_characteristics)
28
+ """
29
  try:
30
+ # Use output_path if provided, otherwise use default analyses path
31
+ save_path = output_path or Path("analyses/default")
32
+
33
+ # Ensure output directory exists
34
+ if not save_path.exists():
35
+ save_path.mkdir(parents=True, exist_ok=True)
36
+
37
+ # Check source files exist
38
  metadata_path = design_path / "metadata.json"
39
  desktop_img = design_path / "screenshot_desktop.png"
40
  mobile_img = design_path / "screenshot_mobile.png"
 
59
 
60
  print(f"Analyzing design {design_id}...")
61
 
62
+ # Get response using specified detail level
63
+ response = await client.messages.create(
64
  model=VISION_MODEL,
65
+ max_tokens=8000 if detailed else 4000, # More tokens for detailed analysis
66
+ system=get_prompt(detailed=detailed),
67
+ messages=[{
68
+ "role": "user",
69
+ "content": [
70
+ {
71
+ "type": "text",
72
+ "text": "Analyze this visual design. Output only the JSON object."
73
+ },
74
+ {
75
+ "type": "image",
76
+ "source": {
77
+ "type": "base64",
78
+ "media_type": "image/png",
79
+ "data": desktop_base64
 
 
 
 
 
 
 
 
 
 
80
  }
81
+ },
82
+ {
83
+ "type": "image",
84
+ "source": {
85
+ "type": "base64",
86
+ "media_type": "image/png",
87
+ "data": mobile_base64
88
+ }
89
+ }
90
+ ]
91
+ }]
92
  )
93
 
94
+ response_content = response.content[0].text
 
95
 
 
96
  if not response_content:
97
  print(f"Empty response for design {design_id}")
98
  return design_id, None, None, None
99
 
100
  # Extract JSON content from markdown code block
101
  if "```json" in response_content:
 
102
  response_content = response_content.split("```json")[1].split("```")[0].strip()
103
 
 
104
  try:
105
  analysis = json.loads(response_content)
106
 
107
+ # Create design-specific directory in output path
108
+ design_output_path = save_path / design_id
109
+ design_output_path.mkdir(parents=True, exist_ok=True)
110
+
111
+ # Save metadata.json inside the design folder
112
+ output_metadata_path = design_output_path / "metadata.json"
113
 
114
+ # Save analysis to output path
115
+ with open(output_metadata_path, "w") as f:
116
+ json.dump(analysis, f, indent=2)
117
 
118
  print(f"Successfully analyzed design {design_id}")
119
+
120
+ # Return appropriate fields based on detail level
121
+ if detailed:
122
+ return (
123
+ design_id,
124
+ analysis["description"]["summary"],
125
+ analysis["categories"],
126
+ analysis["visual_characteristics"]
127
+ )
128
+ else:
129
+ return (
130
+ design_id,
131
+ analysis["description"],
132
+ analysis["categories"],
133
+ analysis["visual_characteristics"]
134
+ )
135
 
136
  except json.JSONDecodeError as e:
137
  print(f"Error parsing JSON response for design {design_id}: {str(e)}")
data_collection/notebook.ipynb CHANGED
@@ -13,43 +13,551 @@
13
  },
14
  {
15
  "cell_type": "code",
16
- "execution_count": null,
17
  "metadata": {},
18
  "outputs": [
19
  {
20
  "name": "stdout",
21
  "output_type": "stream",
22
  "text": [
23
- "Testing scraper with design 001...\n",
 
 
24
  "001: Response status: 200\n",
25
- "Success!\n",
26
- "Testing scraper with design 002...\n",
27
  "002: Response status: 200\n",
28
- "Success!\n",
29
- "Testing scraper with design 003...\n",
30
- "003: Response status: 200\n"
31
- ]
32
- },
33
- {
34
- "ename": "CancelledError",
35
- "evalue": "",
36
- "output_type": "error",
37
- "traceback": [
38
- "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
39
- "\u001b[0;31mCancelledError\u001b[0m Traceback (most recent call last)",
40
- "Cell \u001b[0;32mIn[1], line 16\u001b[0m\n\u001b[1;32m 13\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mException\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m e:\n\u001b[1;32m 14\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mError: \u001b[39m\u001b[38;5;132;01m{\u001b[39;00m\u001b[38;5;28mstr\u001b[39m(e)\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m\"\u001b[39m)\n\u001b[0;32m---> 16\u001b[0m \u001b[38;5;28;01mawait\u001b[39;00m test_scraper(test_set)\n",
41
- "Cell \u001b[0;32mIn[1], line 11\u001b[0m, in \u001b[0;36mtest_scraper\u001b[0;34m(ids)\u001b[0m\n\u001b[1;32m 9\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m 10\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mTesting scraper with design \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mtest_design_id\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m...\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[0;32m---> 11\u001b[0m \u001b[38;5;28;01mawait\u001b[39;00m scrape_design(test_design_id)\n\u001b[1;32m 12\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mSuccess!\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m 13\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mException\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m e:\n",
42
- "File \u001b[0;32m~/Desktop/Projects/ai-maker-space/code/ImagineUI/data_collection/scraper.py:90\u001b[0m, in \u001b[0;36mscrape_design\u001b[0;34m(design_id)\u001b[0m\n\u001b[1;32m 88\u001b[0m save_css(css_url, directory)\n\u001b[1;32m 89\u001b[0m save_metadata(metadata, directory)\n\u001b[0;32m---> 90\u001b[0m \u001b[38;5;28;01mawait\u001b[39;00m take_screenshot(design_url, directory)\n",
43
- "File \u001b[0;32m~/Desktop/Projects/ai-maker-space/code/ImagineUI/data_collection/scraper.py:52\u001b[0m, in \u001b[0;36mtake_screenshot\u001b[0;34m(url, directory)\u001b[0m\n\u001b[1;32m 50\u001b[0m \u001b[38;5;28;01mawait\u001b[39;00m page\u001b[38;5;241m.\u001b[39mwait_for_load_state(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mnetworkidle\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m 51\u001b[0m \u001b[38;5;66;03m# Add a significant delay to ensure background images are loaded\u001b[39;00m\n\u001b[0;32m---> 52\u001b[0m \u001b[38;5;28;01mawait\u001b[39;00m page\u001b[38;5;241m.\u001b[39mwait_for_timeout(\u001b[38;5;241m2000\u001b[39m)\n\u001b[1;32m 54\u001b[0m \u001b[38;5;66;03m# Get full height\u001b[39;00m\n\u001b[1;32m 55\u001b[0m height \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mawait\u001b[39;00m page\u001b[38;5;241m.\u001b[39mevaluate(\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mdocument.body.scrollHeight\u001b[39m\u001b[38;5;124m'\u001b[39m)\n",
44
- "File \u001b[0;32m~/Desktop/Projects/ai-maker-space/code/ImagineUI/.venv/lib/python3.11/site-packages/playwright/async_api/_generated.py:11401\u001b[0m, in \u001b[0;36mPage.wait_for_timeout\u001b[0;34m(self, timeout)\u001b[0m\n\u001b[1;32m 11379\u001b[0m \u001b[38;5;28;01masync\u001b[39;00m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;21mwait_for_timeout\u001b[39m(\u001b[38;5;28mself\u001b[39m, timeout: \u001b[38;5;28mfloat\u001b[39m) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[1;32m 11380\u001b[0m \u001b[38;5;250m \u001b[39m\u001b[38;5;124;03m\"\"\"Page.wait_for_timeout\u001b[39;00m\n\u001b[1;32m 11381\u001b[0m \n\u001b[1;32m 11382\u001b[0m \u001b[38;5;124;03m Waits for the given `timeout` in milliseconds.\u001b[39;00m\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 11397\u001b[0m \u001b[38;5;124;03m A timeout to wait for\u001b[39;00m\n\u001b[1;32m 11398\u001b[0m \u001b[38;5;124;03m \"\"\"\u001b[39;00m\n\u001b[1;32m 11400\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m mapping\u001b[38;5;241m.\u001b[39mfrom_maybe_impl(\n\u001b[0;32m> 11401\u001b[0m \u001b[38;5;28;01mawait\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_impl_obj\u001b[38;5;241m.\u001b[39mwait_for_timeout(timeout\u001b[38;5;241m=\u001b[39mtimeout)\n\u001b[1;32m 11402\u001b[0m )\n",
45
- "File \u001b[0;32m~/Desktop/Projects/ai-maker-space/code/ImagineUI/.venv/lib/python3.11/site-packages/playwright/_impl/_page.py:1073\u001b[0m, in \u001b[0;36mPage.wait_for_timeout\u001b[0;34m(self, timeout)\u001b[0m\n\u001b[1;32m 1072\u001b[0m \u001b[38;5;28;01masync\u001b[39;00m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;21mwait_for_timeout\u001b[39m(\u001b[38;5;28mself\u001b[39m, timeout: \u001b[38;5;28mfloat\u001b[39m) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[0;32m-> 1073\u001b[0m \u001b[38;5;28;01mawait\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_main_frame\u001b[38;5;241m.\u001b[39mwait_for_timeout(timeout)\n",
46
- "File \u001b[0;32m~/Desktop/Projects/ai-maker-space/code/ImagineUI/.venv/lib/python3.11/site-packages/playwright/_impl/_frame.py:756\u001b[0m, in \u001b[0;36mFrame.wait_for_timeout\u001b[0;34m(self, timeout)\u001b[0m\n\u001b[1;32m 755\u001b[0m \u001b[38;5;28;01masync\u001b[39;00m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;21mwait_for_timeout\u001b[39m(\u001b[38;5;28mself\u001b[39m, timeout: \u001b[38;5;28mfloat\u001b[39m) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[0;32m--> 756\u001b[0m \u001b[38;5;28;01mawait\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_channel\u001b[38;5;241m.\u001b[39msend(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mwaitForTimeout\u001b[39m\u001b[38;5;124m\"\u001b[39m, locals_to_params(\u001b[38;5;28mlocals\u001b[39m()))\n",
47
- "File \u001b[0;32m~/Desktop/Projects/ai-maker-space/code/ImagineUI/.venv/lib/python3.11/site-packages/playwright/_impl/_connection.py:61\u001b[0m, in \u001b[0;36mChannel.send\u001b[0;34m(self, method, params)\u001b[0m\n\u001b[1;32m 60\u001b[0m \u001b[38;5;28;01masync\u001b[39;00m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;21msend\u001b[39m(\u001b[38;5;28mself\u001b[39m, method: \u001b[38;5;28mstr\u001b[39m, params: Dict \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m Any:\n\u001b[0;32m---> 61\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;01mawait\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_connection\u001b[38;5;241m.\u001b[39mwrap_api_call(\n\u001b[1;32m 62\u001b[0m \u001b[38;5;28;01mlambda\u001b[39;00m: \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_inner_send(method, params, \u001b[38;5;28;01mFalse\u001b[39;00m),\n\u001b[1;32m 63\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_is_internal_type,\n\u001b[1;32m 64\u001b[0m )\n",
48
- "File \u001b[0;32m~/Desktop/Projects/ai-maker-space/code/ImagineUI/.venv/lib/python3.11/site-packages/playwright/_impl/_connection.py:526\u001b[0m, in \u001b[0;36mConnection.wrap_api_call\u001b[0;34m(self, cb, is_internal)\u001b[0m\n\u001b[1;32m 524\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_api_zone\u001b[38;5;241m.\u001b[39mset(parsed_st)\n\u001b[1;32m 525\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m--> 526\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;01mawait\u001b[39;00m cb()\n\u001b[1;32m 527\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mException\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m error:\n\u001b[1;32m 528\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m rewrite_error(error, \u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;132;01m{\u001b[39;00mparsed_st[\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mapiName\u001b[39m\u001b[38;5;124m'\u001b[39m]\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m: \u001b[39m\u001b[38;5;132;01m{\u001b[39;00merror\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m\"\u001b[39m) \u001b[38;5;28;01mfrom\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;28;01mNone\u001b[39;00m\n",
49
- "File \u001b[0;32m~/Desktop/Projects/ai-maker-space/code/ImagineUI/.venv/lib/python3.11/site-packages/playwright/_impl/_connection.py:92\u001b[0m, in \u001b[0;36mChannel._inner_send\u001b[0;34m(self, method, params, return_as_dict)\u001b[0m\n\u001b[1;32m 88\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m error\n\u001b[1;32m 89\u001b[0m callback \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_connection\u001b[38;5;241m.\u001b[39m_send_message_to_server(\n\u001b[1;32m 90\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_object, method, _filter_none(params)\n\u001b[1;32m 91\u001b[0m )\n\u001b[0;32m---> 92\u001b[0m done, _ \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mawait\u001b[39;00m asyncio\u001b[38;5;241m.\u001b[39mwait(\n\u001b[1;32m 93\u001b[0m {\n\u001b[1;32m 94\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_connection\u001b[38;5;241m.\u001b[39m_transport\u001b[38;5;241m.\u001b[39mon_error_future,\n\u001b[1;32m 95\u001b[0m callback\u001b[38;5;241m.\u001b[39mfuture,\n\u001b[1;32m 96\u001b[0m },\n\u001b[1;32m 97\u001b[0m return_when\u001b[38;5;241m=\u001b[39masyncio\u001b[38;5;241m.\u001b[39mFIRST_COMPLETED,\n\u001b[1;32m 98\u001b[0m )\n\u001b[1;32m 99\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m callback\u001b[38;5;241m.\u001b[39mfuture\u001b[38;5;241m.\u001b[39mdone():\n\u001b[1;32m 100\u001b[0m callback\u001b[38;5;241m.\u001b[39mfuture\u001b[38;5;241m.\u001b[39mcancel()\n",
50
- "File \u001b[0;32m~/.local/share/uv/python/cpython-3.11.11-macos-x86_64-none/lib/python3.11/asyncio/tasks.py:428\u001b[0m, in \u001b[0;36mwait\u001b[0;34m(fs, timeout, return_when)\u001b[0m\n\u001b[1;32m 425\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mTypeError\u001b[39;00m(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mPassing coroutines is forbidden, use tasks explicitly.\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m 427\u001b[0m loop \u001b[38;5;241m=\u001b[39m events\u001b[38;5;241m.\u001b[39mget_running_loop()\n\u001b[0;32m--> 428\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;01mawait\u001b[39;00m _wait(fs, timeout, return_when, loop)\n",
51
- "File \u001b[0;32m~/.local/share/uv/python/cpython-3.11.11-macos-x86_64-none/lib/python3.11/asyncio/tasks.py:535\u001b[0m, in \u001b[0;36m_wait\u001b[0;34m(fs, timeout, return_when, loop)\u001b[0m\n\u001b[1;32m 532\u001b[0m f\u001b[38;5;241m.\u001b[39madd_done_callback(_on_completion)\n\u001b[1;32m 534\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m--> 535\u001b[0m \u001b[38;5;28;01mawait\u001b[39;00m waiter\n\u001b[1;32m 536\u001b[0m \u001b[38;5;28;01mfinally\u001b[39;00m:\n\u001b[1;32m 537\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m timeout_handle \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n",
52
- "\u001b[0;31mCancelledError\u001b[0m: "
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
53
  ]
54
  }
55
  ],
@@ -109,45 +617,164 @@
109
  "source": [
110
  "## 2. Analyze\n",
111
  "\n",
112
- "Now, using the screenshots and styles we downloaded, we analyze the design for characteristics that will be useful for retrieval."
113
  ]
114
  },
115
  {
116
  "cell_type": "code",
117
- "execution_count": 2,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
118
  "metadata": {},
119
  "outputs": [
120
  {
121
  "name": "stdout",
122
  "output_type": "stream",
123
  "text": [
124
- "Analyzing design 010...\n",
125
- "Successfully analyzed design 010\n",
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
126
  "\n",
127
- "Analysis for design 010:\n",
128
- "Description: The design features a harmonious combination of earthy tones and soft gradients, creating a serene and inviting atmosphere. The layout leverages clear headings and subheadings for readability while integrating subtle decorative elements for visual interest. Functionally, the design is divided into a main content area and a sidebar, enhancing navigability.\n",
129
- "Categories: Web Design, Educational, Inspirational, Aesthetic, Textual\n",
130
- "Visual Characteristics: Earthy Color Palette, Soft Gradients, Informative Layout, Balanced Composition, Text-focused Design\n"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
131
  ]
132
  }
133
  ],
134
  "source": [
135
- "from data_collection.analyze_designs import analyze_screenshot\n",
136
- "from pathlib import Path\n",
137
- "import asyncio\n",
138
  "\n",
139
- "async def test_analyzer():\n",
140
- " for design_id in test_set:\n",
141
- " design_path = Path(f\"../designs/{design_id}\")\n",
142
- " result = await analyze_screenshot(design_id, design_path)\n",
143
- " \n",
144
- " if result[1] is not None: # If analysis was successful\n",
145
- " print(f\"\\nAnalysis for design {design_id}:\")\n",
146
- " print(f\"Description: {result[1]}\")\n",
147
- " print(f\"Categories: {', '.join(result[2])}\")\n",
148
- " print(f\"Visual Characteristics: {', '.join(result[3])}\")\n",
149
  "\n",
150
- "await test_analyzer()"
 
 
 
 
 
 
 
151
  ]
152
  }
153
  ],
 
13
  },
14
  {
15
  "cell_type": "code",
16
+ "execution_count": 2,
17
  "metadata": {},
18
  "outputs": [
19
  {
20
  "name": "stdout",
21
  "output_type": "stream",
22
  "text": [
23
+ "Starting scrape of 221 designs...\n",
24
+ "\n",
25
+ "Processing batch 1 (5 designs)...\n",
26
  "001: Response status: 200\n",
 
 
27
  "002: Response status: 200\n",
28
+ "003: Response status: 200\n",
29
+ "004: Response status: 200\n",
30
+ "005: Response status: 200\n",
31
+ "Successfully scraped design 001\n",
32
+ "Successfully scraped design 002\n",
33
+ "Successfully scraped design 003\n",
34
+ "Successfully scraped design 004\n",
35
+ "Successfully scraped design 005\n",
36
+ "\n",
37
+ "Processing batch 2 (5 designs)...\n",
38
+ "006: Response status: 200\n",
39
+ "007: Response status: 200\n",
40
+ "008: Response status: 200\n",
41
+ "009: Response status: 200\n",
42
+ "010: Response status: 200\n",
43
+ "Successfully scraped design 006\n",
44
+ "Successfully scraped design 007\n",
45
+ "Successfully scraped design 008\n",
46
+ "Successfully scraped design 009\n",
47
+ "Successfully scraped design 010\n",
48
+ "\n",
49
+ "Processing batch 3 (5 designs)...\n",
50
+ "011: Response status: 200\n",
51
+ "012: Response status: 200\n",
52
+ "013: Response status: 200\n",
53
+ "014: Response status: 200\n",
54
+ "015: Response status: 200\n",
55
+ "Successfully scraped design 011\n",
56
+ "Successfully scraped design 012\n",
57
+ "Successfully scraped design 013\n",
58
+ "Successfully scraped design 014\n",
59
+ "Successfully scraped design 015\n",
60
+ "\n",
61
+ "Processing batch 4 (5 designs)...\n",
62
+ "016: Response status: 200\n",
63
+ "017: Response status: 200\n",
64
+ "018: Response status: 200\n",
65
+ "019: Response status: 200\n",
66
+ "020: Response status: 200\n",
67
+ "Successfully scraped design 016\n",
68
+ "Successfully scraped design 017\n",
69
+ "Successfully scraped design 018\n",
70
+ "Successfully scraped design 019\n",
71
+ "Successfully scraped design 020\n",
72
+ "\n",
73
+ "Processing batch 5 (5 designs)...\n",
74
+ "021: Response status: 200\n",
75
+ "022: Response status: 200\n",
76
+ "023: Response status: 200\n",
77
+ "024: Response status: 200\n",
78
+ "025: Response status: 200\n",
79
+ "Successfully scraped design 021\n",
80
+ "Successfully scraped design 022\n",
81
+ "Successfully scraped design 023\n",
82
+ "Successfully scraped design 024\n",
83
+ "Successfully scraped design 025\n",
84
+ "\n",
85
+ "Processing batch 6 (5 designs)...\n",
86
+ "026: Response status: 200\n",
87
+ "027: Response status: 200\n",
88
+ "028: Response status: 200\n",
89
+ "029: Response status: 200\n",
90
+ "030: Response status: 200\n",
91
+ "Successfully scraped design 026\n",
92
+ "Successfully scraped design 027\n",
93
+ "Successfully scraped design 028\n",
94
+ "Successfully scraped design 029\n",
95
+ "Successfully scraped design 030\n",
96
+ "\n",
97
+ "Processing batch 7 (5 designs)...\n",
98
+ "031: Response status: 200\n",
99
+ "032: Response status: 200\n",
100
+ "033: Response status: 200\n",
101
+ "034: Response status: 200\n",
102
+ "035: Response status: 200\n",
103
+ "Successfully scraped design 031\n",
104
+ "Successfully scraped design 032\n",
105
+ "Successfully scraped design 033\n",
106
+ "Successfully scraped design 034\n",
107
+ "Successfully scraped design 035\n",
108
+ "\n",
109
+ "Processing batch 8 (5 designs)...\n",
110
+ "036: Response status: 200\n",
111
+ "037: Response status: 200\n",
112
+ "038: Response status: 200\n",
113
+ "039: Response status: 200\n",
114
+ "040: Response status: 200\n",
115
+ "Successfully scraped design 036\n",
116
+ "Successfully scraped design 037\n",
117
+ "Successfully scraped design 038\n",
118
+ "Successfully scraped design 039\n",
119
+ "Successfully scraped design 040\n",
120
+ "\n",
121
+ "Processing batch 9 (5 designs)...\n",
122
+ "041: Response status: 200\n",
123
+ "042: Response status: 200\n",
124
+ "043: Response status: 200\n",
125
+ "044: Response status: 200\n",
126
+ "045: Response status: 200\n",
127
+ "Successfully scraped design 041\n",
128
+ "Successfully scraped design 042\n",
129
+ "Successfully scraped design 043\n",
130
+ "Successfully scraped design 044\n",
131
+ "Successfully scraped design 045\n",
132
+ "\n",
133
+ "Processing batch 10 (5 designs)...\n",
134
+ "046: Response status: 200\n",
135
+ "047: Response status: 200\n",
136
+ "048: Response status: 200\n",
137
+ "049: Response status: 200\n",
138
+ "050: Response status: 200\n",
139
+ "Successfully scraped design 046\n",
140
+ "Successfully scraped design 047\n",
141
+ "Successfully scraped design 048\n",
142
+ "Successfully scraped design 049\n",
143
+ "Successfully scraped design 050\n",
144
+ "\n",
145
+ "Processing batch 11 (5 designs)...\n",
146
+ "051: Response status: 200\n",
147
+ "052: Response status: 200\n",
148
+ "053: Response status: 200\n",
149
+ "054: Response status: 200\n",
150
+ "055: Response status: 200\n",
151
+ "Successfully scraped design 051\n",
152
+ "Successfully scraped design 052\n",
153
+ "Successfully scraped design 053\n",
154
+ "Successfully scraped design 054\n",
155
+ "Successfully scraped design 055\n",
156
+ "\n",
157
+ "Processing batch 12 (5 designs)...\n",
158
+ "056: Response status: 200\n",
159
+ "057: Response status: 200\n",
160
+ "058: Response status: 200\n",
161
+ "059: Response status: 200\n",
162
+ "060: Response status: 200\n",
163
+ "Successfully scraped design 056\n",
164
+ "Successfully scraped design 057\n",
165
+ "Successfully scraped design 058\n",
166
+ "Successfully scraped design 059\n",
167
+ "Successfully scraped design 060\n",
168
+ "\n",
169
+ "Processing batch 13 (5 designs)...\n",
170
+ "061: Response status: 200\n",
171
+ "062: Response status: 200\n",
172
+ "063: Response status: 200\n",
173
+ "064: Response status: 200\n",
174
+ "065: Response status: 200\n",
175
+ "Successfully scraped design 061\n",
176
+ "Successfully scraped design 062\n",
177
+ "Successfully scraped design 063\n",
178
+ "Successfully scraped design 064\n",
179
+ "Successfully scraped design 065\n",
180
+ "\n",
181
+ "Processing batch 14 (5 designs)...\n",
182
+ "066: Response status: 200\n",
183
+ "067: Response status: 200\n",
184
+ "068: Response status: 200\n",
185
+ "069: Response status: 200\n",
186
+ "070: Response status: 200\n",
187
+ "Successfully scraped design 066\n",
188
+ "Successfully scraped design 067\n",
189
+ "Successfully scraped design 068\n",
190
+ "Successfully scraped design 069\n",
191
+ "Successfully scraped design 070\n",
192
+ "\n",
193
+ "Processing batch 15 (5 designs)...\n",
194
+ "071: Response status: 200\n",
195
+ "072: Response status: 200\n",
196
+ "073: Response status: 200\n",
197
+ "074: Response status: 200\n",
198
+ "075: Response status: 200\n",
199
+ "Successfully scraped design 071\n",
200
+ "Successfully scraped design 072\n",
201
+ "Successfully scraped design 073\n",
202
+ "Successfully scraped design 074\n",
203
+ "Successfully scraped design 075\n",
204
+ "\n",
205
+ "Processing batch 16 (5 designs)...\n",
206
+ "076: Response status: 200\n",
207
+ "077: Response status: 200\n",
208
+ "078: Response status: 200\n",
209
+ "079: Response status: 200\n",
210
+ "080: Response status: 200\n",
211
+ "Successfully scraped design 076\n",
212
+ "Successfully scraped design 077\n",
213
+ "Successfully scraped design 078\n",
214
+ "Successfully scraped design 079\n",
215
+ "Successfully scraped design 080\n",
216
+ "\n",
217
+ "Processing batch 17 (5 designs)...\n",
218
+ "081: Response status: 200\n",
219
+ "082: Response status: 200\n",
220
+ "083: Response status: 200\n",
221
+ "084: Response status: 200\n",
222
+ "085: Response status: 200\n",
223
+ "Successfully scraped design 081\n",
224
+ "Successfully scraped design 082\n",
225
+ "Successfully scraped design 083\n",
226
+ "Successfully scraped design 084\n",
227
+ "Successfully scraped design 085\n",
228
+ "\n",
229
+ "Processing batch 18 (5 designs)...\n",
230
+ "086: Response status: 200\n",
231
+ "087: Response status: 200\n",
232
+ "088: Response status: 200\n",
233
+ "089: Response status: 200\n",
234
+ "090: Response status: 200\n",
235
+ "Successfully scraped design 086\n",
236
+ "Successfully scraped design 087\n",
237
+ "Successfully scraped design 088\n",
238
+ "Successfully scraped design 089\n",
239
+ "Successfully scraped design 090\n",
240
+ "\n",
241
+ "Processing batch 19 (5 designs)...\n",
242
+ "091: Response status: 200\n",
243
+ "092: Response status: 200\n",
244
+ "093: Response status: 200\n",
245
+ "094: Response status: 200\n",
246
+ "095: Response status: 200\n",
247
+ "Successfully scraped design 091\n",
248
+ "Successfully scraped design 092\n",
249
+ "Successfully scraped design 093\n",
250
+ "Successfully scraped design 094\n",
251
+ "Successfully scraped design 095\n",
252
+ "\n",
253
+ "Processing batch 20 (5 designs)...\n",
254
+ "096: Response status: 200\n",
255
+ "097: Response status: 200\n",
256
+ "098: Response status: 200\n",
257
+ "099: Response status: 200\n",
258
+ "100: Response status: 200\n",
259
+ "Successfully scraped design 096\n",
260
+ "Successfully scraped design 097\n",
261
+ "Successfully scraped design 098\n",
262
+ "Successfully scraped design 099\n",
263
+ "Successfully scraped design 100\n",
264
+ "\n",
265
+ "Processing batch 21 (5 designs)...\n",
266
+ "101: Response status: 200\n",
267
+ "102: Response status: 200\n",
268
+ "103: Response status: 200\n",
269
+ "104: Response status: 200\n",
270
+ "105: Response status: 200\n",
271
+ "Successfully scraped design 101\n",
272
+ "Successfully scraped design 102\n",
273
+ "Successfully scraped design 103\n",
274
+ "Successfully scraped design 104\n",
275
+ "Successfully scraped design 105\n",
276
+ "\n",
277
+ "Processing batch 22 (5 designs)...\n",
278
+ "106: Response status: 200\n",
279
+ "107: Response status: 200\n",
280
+ "108: Response status: 200\n",
281
+ "109: Response status: 200\n",
282
+ "110: Response status: 200\n",
283
+ "Successfully scraped design 106\n",
284
+ "Successfully scraped design 107\n",
285
+ "Successfully scraped design 108\n",
286
+ "Successfully scraped design 109\n",
287
+ "Successfully scraped design 110\n",
288
+ "\n",
289
+ "Processing batch 23 (5 designs)...\n",
290
+ "111: Response status: 200\n",
291
+ "112: Response status: 200\n",
292
+ "113: Response status: 200\n",
293
+ "114: Response status: 200\n",
294
+ "115: Response status: 200\n",
295
+ "Successfully scraped design 111\n",
296
+ "Successfully scraped design 112\n",
297
+ "Successfully scraped design 113\n",
298
+ "Successfully scraped design 114\n",
299
+ "Successfully scraped design 115\n",
300
+ "\n",
301
+ "Processing batch 24 (5 designs)...\n",
302
+ "116: Response status: 200\n",
303
+ "117: Response status: 200\n",
304
+ "118: Response status: 200\n",
305
+ "119: Response status: 200\n",
306
+ "120: Response status: 200\n",
307
+ "Successfully scraped design 116\n",
308
+ "Successfully scraped design 117\n",
309
+ "Successfully scraped design 118\n",
310
+ "Successfully scraped design 119\n",
311
+ "Successfully scraped design 120\n",
312
+ "\n",
313
+ "Processing batch 25 (5 designs)...\n",
314
+ "121: Response status: 200\n",
315
+ "122: Response status: 200\n",
316
+ "123: Response status: 200\n",
317
+ "124: Response status: 200\n",
318
+ "125: Response status: 200\n",
319
+ "Successfully scraped design 121\n",
320
+ "Successfully scraped design 122\n",
321
+ "Successfully scraped design 123\n",
322
+ "Successfully scraped design 124\n",
323
+ "Successfully scraped design 125\n",
324
+ "\n",
325
+ "Processing batch 26 (5 designs)...\n",
326
+ "126: Response status: 200\n",
327
+ "127: Response status: 200\n",
328
+ "128: Response status: 200\n",
329
+ "129: Response status: 200\n",
330
+ "130: Response status: 200\n",
331
+ "Successfully scraped design 126\n",
332
+ "Successfully scraped design 127\n",
333
+ "Successfully scraped design 128\n",
334
+ "Successfully scraped design 129\n",
335
+ "Successfully scraped design 130\n",
336
+ "\n",
337
+ "Processing batch 27 (5 designs)...\n",
338
+ "131: Response status: 200\n",
339
+ "132: Response status: 200\n",
340
+ "133: Response status: 200\n",
341
+ "134: Response status: 200\n",
342
+ "135: Response status: 200\n",
343
+ "Successfully scraped design 131\n",
344
+ "Successfully scraped design 132\n",
345
+ "Successfully scraped design 133\n",
346
+ "Successfully scraped design 134\n",
347
+ "Successfully scraped design 135\n",
348
+ "\n",
349
+ "Processing batch 28 (5 designs)...\n",
350
+ "136: Response status: 200\n",
351
+ "137: Response status: 200\n",
352
+ "138: Response status: 200\n",
353
+ "139: Response status: 200\n",
354
+ "140: Response status: 200\n",
355
+ "Successfully scraped design 136\n",
356
+ "Successfully scraped design 137\n",
357
+ "Successfully scraped design 138\n",
358
+ "Successfully scraped design 139\n",
359
+ "Successfully scraped design 140\n",
360
+ "\n",
361
+ "Processing batch 29 (5 designs)...\n",
362
+ "141: Response status: 200\n",
363
+ "142: Response status: 200\n",
364
+ "143: Response status: 200\n",
365
+ "144: Response status: 200\n",
366
+ "145: Response status: 200\n",
367
+ "Successfully scraped design 141\n",
368
+ "Successfully scraped design 142\n",
369
+ "Successfully scraped design 143\n",
370
+ "Successfully scraped design 144\n",
371
+ "Successfully scraped design 145\n",
372
+ "\n",
373
+ "Processing batch 30 (5 designs)...\n",
374
+ "146: Response status: 200\n",
375
+ "147: Response status: 200\n",
376
+ "148: Response status: 200\n",
377
+ "149: Response status: 200\n",
378
+ "150: Response status: 200\n",
379
+ "Successfully scraped design 146\n",
380
+ "Successfully scraped design 147\n",
381
+ "Successfully scraped design 148\n",
382
+ "Successfully scraped design 149\n",
383
+ "Successfully scraped design 150\n",
384
+ "\n",
385
+ "Processing batch 31 (5 designs)...\n",
386
+ "151: Response status: 200\n",
387
+ "152: Response status: 200\n",
388
+ "153: Response status: 200\n",
389
+ "154: Response status: 200\n",
390
+ "155: Response status: 200\n",
391
+ "Successfully scraped design 151\n",
392
+ "Successfully scraped design 152\n",
393
+ "Successfully scraped design 153\n",
394
+ "Successfully scraped design 154\n",
395
+ "Successfully scraped design 155\n",
396
+ "\n",
397
+ "Processing batch 32 (5 designs)...\n",
398
+ "156: Response status: 200\n",
399
+ "157: Response status: 200\n",
400
+ "158: Response status: 200\n",
401
+ "159: Response status: 200\n",
402
+ "160: Response status: 200\n",
403
+ "Successfully scraped design 156\n",
404
+ "Successfully scraped design 157\n",
405
+ "Successfully scraped design 158\n",
406
+ "Successfully scraped design 159\n",
407
+ "Successfully scraped design 160\n",
408
+ "\n",
409
+ "Processing batch 33 (5 designs)...\n",
410
+ "161: Response status: 200\n",
411
+ "162: Response status: 200\n",
412
+ "163: Response status: 200\n",
413
+ "164: Response status: 200\n",
414
+ "165: Response status: 200\n",
415
+ "Successfully scraped design 161\n",
416
+ "Successfully scraped design 162\n",
417
+ "Successfully scraped design 163\n",
418
+ "Successfully scraped design 164\n",
419
+ "Successfully scraped design 165\n",
420
+ "\n",
421
+ "Processing batch 34 (5 designs)...\n",
422
+ "166: Response status: 200\n",
423
+ "167: Response status: 200\n",
424
+ "168: Response status: 200\n",
425
+ "169: Response status: 200\n",
426
+ "170: Response status: 200\n",
427
+ "Successfully scraped design 166\n",
428
+ "Successfully scraped design 167\n",
429
+ "Successfully scraped design 168\n",
430
+ "Successfully scraped design 169\n",
431
+ "Successfully scraped design 170\n",
432
+ "\n",
433
+ "Processing batch 35 (5 designs)...\n",
434
+ "171: Response status: 200\n",
435
+ "172: Response status: 200\n",
436
+ "173: Response status: 200\n",
437
+ "174: Response status: 200\n",
438
+ "175: Response status: 200\n",
439
+ "Successfully scraped design 171\n",
440
+ "Successfully scraped design 172\n",
441
+ "Successfully scraped design 173\n",
442
+ "Successfully scraped design 174\n",
443
+ "Successfully scraped design 175\n",
444
+ "\n",
445
+ "Processing batch 36 (5 designs)...\n",
446
+ "176: Response status: 200\n",
447
+ "177: Response status: 200\n",
448
+ "178: Response status: 200\n",
449
+ "179: Response status: 200\n",
450
+ "180: Response status: 200\n",
451
+ "Successfully scraped design 176\n",
452
+ "Successfully scraped design 177\n",
453
+ "Successfully scraped design 178\n",
454
+ "Successfully scraped design 179\n",
455
+ "Successfully scraped design 180\n",
456
+ "\n",
457
+ "Processing batch 37 (5 designs)...\n",
458
+ "181: Response status: 200\n",
459
+ "182: Response status: 200\n",
460
+ "183: Response status: 200\n",
461
+ "184: Response status: 200\n",
462
+ "185: Response status: 200\n",
463
+ "Successfully scraped design 181\n",
464
+ "Successfully scraped design 182\n",
465
+ "Successfully scraped design 183\n",
466
+ "Successfully scraped design 184\n",
467
+ "Successfully scraped design 185\n",
468
+ "\n",
469
+ "Processing batch 38 (5 designs)...\n",
470
+ "186: Response status: 200\n",
471
+ "187: Response status: 200\n",
472
+ "188: Response status: 200\n",
473
+ "189: Response status: 200\n",
474
+ "190: Response status: 200\n",
475
+ "Successfully scraped design 186\n",
476
+ "Successfully scraped design 187\n",
477
+ "Successfully scraped design 188\n",
478
+ "Successfully scraped design 189\n",
479
+ "Successfully scraped design 190\n",
480
+ "\n",
481
+ "Processing batch 39 (5 designs)...\n",
482
+ "191: Response status: 200\n",
483
+ "192: Response status: 200\n",
484
+ "193: Response status: 200\n",
485
+ "194: Response status: 200\n",
486
+ "195: Response status: 200\n",
487
+ "Successfully scraped design 191\n",
488
+ "Successfully scraped design 192\n",
489
+ "Successfully scraped design 193\n",
490
+ "Successfully scraped design 194\n",
491
+ "Successfully scraped design 195\n",
492
+ "\n",
493
+ "Processing batch 40 (5 designs)...\n",
494
+ "196: Response status: 200\n",
495
+ "197: Response status: 200\n",
496
+ "198: Response status: 200\n",
497
+ "199: Response status: 200\n",
498
+ "200: Response status: 200\n",
499
+ "Successfully scraped design 196\n",
500
+ "Successfully scraped design 197\n",
501
+ "Successfully scraped design 198\n",
502
+ "Successfully scraped design 199\n",
503
+ "Successfully scraped design 200\n",
504
+ "\n",
505
+ "Processing batch 41 (5 designs)...\n",
506
+ "201: Response status: 200\n",
507
+ "202: Response status: 200\n",
508
+ "203: Response status: 200\n",
509
+ "204: Response status: 200\n",
510
+ "205: Response status: 200\n",
511
+ "Successfully scraped design 201\n",
512
+ "Successfully scraped design 202\n",
513
+ "Successfully scraped design 203\n",
514
+ "Successfully scraped design 204\n",
515
+ "Successfully scraped design 205\n",
516
+ "\n",
517
+ "Processing batch 42 (5 designs)...\n",
518
+ "206: Response status: 200\n",
519
+ "207: Response status: 200\n",
520
+ "208: Response status: 200\n",
521
+ "209: Response status: 200\n",
522
+ "210: Response status: 200\n",
523
+ "Successfully scraped design 206\n",
524
+ "Successfully scraped design 207\n",
525
+ "Successfully scraped design 208\n",
526
+ "Successfully scraped design 209\n",
527
+ "Successfully scraped design 210\n",
528
+ "\n",
529
+ "Processing batch 43 (5 designs)...\n",
530
+ "211: Response status: 200\n",
531
+ "212: Response status: 200\n",
532
+ "213: Response status: 200\n",
533
+ "214: Response status: 200\n",
534
+ "215: Response status: 200\n",
535
+ "Successfully scraped design 211\n",
536
+ "Successfully scraped design 212\n",
537
+ "Successfully scraped design 213\n",
538
+ "Successfully scraped design 214\n",
539
+ "Successfully scraped design 215\n",
540
+ "\n",
541
+ "Processing batch 44 (5 designs)...\n",
542
+ "216: Response status: 200\n",
543
+ "217: Response status: 200\n",
544
+ "218: Response status: 200\n",
545
+ "219: Response status: 200\n",
546
+ "220: Response status: 200\n",
547
+ "Successfully scraped design 216\n",
548
+ "Successfully scraped design 217\n",
549
+ "Successfully scraped design 218\n",
550
+ "Successfully scraped design 219\n",
551
+ "Successfully scraped design 220\n",
552
+ "\n",
553
+ "Processing batch 45 (1 designs)...\n",
554
+ "221: Response status: 200\n",
555
+ "Successfully scraped design 221\n",
556
+ "\n",
557
+ "Scraping complete:\n",
558
+ "Successful: 221\n",
559
+ "Failed: 0\n",
560
+ "Total: 221\n"
561
  ]
562
  }
563
  ],
 
617
  "source": [
618
  "## 2. Analyze\n",
619
  "\n",
620
+ "Now, using the screenshots and styles we downloaded, we analyze the design for characteristics that will be useful for retrieval. Our analyzer can perform a basic analysis and a detailed analysis, which will be used to test and illustrate results on the data set later."
621
  ]
622
  },
623
  {
624
  "cell_type": "code",
625
+ "execution_count": 3,
626
+ "metadata": {},
627
+ "outputs": [],
628
+ "source": [
629
+ "from data_collection.analyze_designs import analyze_screenshot\n",
630
+ "from pathlib import Path\n",
631
+ "import asyncio\n",
632
+ "\n",
633
+ "async def test_analyzer(design_ids, batch_size=5, detailed=True, output_path=None):\n",
634
+ " \"\"\"\n",
635
+ " Asynchronously analyze designs in batches.\n",
636
+ " \n",
637
+ " Args:\n",
638
+ " design_ids (list): List of design IDs to analyze\n",
639
+ " batch_size (int): Number of designs to process concurrently\n",
640
+ " detailed (bool): Whether to use detailed analysis\n",
641
+ " output_path (Path): Where to save analysis results\n",
642
+ " \"\"\"\n",
643
+ " print(f\"Starting analysis of {len(design_ids)} designs...\")\n",
644
+ " \n",
645
+ " successful = 0\n",
646
+ " failed = 0\n",
647
+ " \n",
648
+ " # Process in batches\n",
649
+ " for i in range(0, len(design_ids), batch_size):\n",
650
+ " batch = design_ids[i:i + batch_size]\n",
651
+ " print(f\"\\nProcessing batch {i//batch_size + 1} ({len(batch)} designs)...\")\n",
652
+ " \n",
653
+ " # Create tasks for current batch\n",
654
+ " tasks = [\n",
655
+ " analyze_screenshot(\n",
656
+ " design_id=design_id,\n",
657
+ " design_path=Path(f\"scraped_designs/{design_id}\"),\n",
658
+ " detailed=detailed,\n",
659
+ " output_path=output_path\n",
660
+ " ) for design_id in batch\n",
661
+ " ]\n",
662
+ " \n",
663
+ " # Run batch tasks concurrently\n",
664
+ " results = await asyncio.gather(*tasks, return_exceptions=True)\n",
665
+ " \n",
666
+ " # Process batch results\n",
667
+ " for design_id, result in zip(batch, results):\n",
668
+ " if isinstance(result, Exception):\n",
669
+ " print(f\"Error analyzing design {design_id}: {str(result)}\")\n",
670
+ " failed += 1\n",
671
+ " elif result[1] is not None: # Check if analysis was successful\n",
672
+ " successful += 1\n",
673
+ " print(f\"\\nAnalysis for design {design_id}:\")\n",
674
+ " if detailed:\n",
675
+ " print(f\"Description: {result[1]}\") # summary from description object\n",
676
+ " else:\n",
677
+ " print(f\"Description: {result[1]}\") # direct description string\n",
678
+ " print(f\"Categories: {', '.join(result[2])}\")\n",
679
+ " print(f\"Visual Characteristics: {', '.join(result[3])}\")\n",
680
+ " else:\n",
681
+ " print(f\"Failed to analyze design {design_id}\")\n",
682
+ " failed += 1\n",
683
+ " \n",
684
+ " print(f\"\\nAnalysis complete:\")\n",
685
+ " print(f\"Successful: {successful}\")\n",
686
+ " print(f\"Failed: {failed}\")\n",
687
+ " print(f\"Total: {len(design_ids)}\")\n"
688
+ ]
689
+ },
690
+ {
691
+ "cell_type": "markdown",
692
+ "metadata": {},
693
+ "source": [
694
+ "Now we can run the analysis on a range of our choosing."
695
+ ]
696
+ },
697
+ {
698
+ "cell_type": "code",
699
+ "execution_count": 4,
700
  "metadata": {},
701
  "outputs": [
702
  {
703
  "name": "stdout",
704
  "output_type": "stream",
705
  "text": [
706
+ "Running detailed analysis...\n",
707
+ "Starting analysis of 5 designs...\n",
708
+ "\n",
709
+ "Processing batch 1 (5 designs)...\n",
710
+ "Analyzing design 200...\n",
711
+ "Error processing design 200: Missing required arguments; Expected either ('max_tokens', 'messages' and 'model') or ('max_tokens', 'messages', 'model' and 'stream') arguments to be given\n",
712
+ "Analyzing design 201...\n",
713
+ "Error processing design 201: Missing required arguments; Expected either ('max_tokens', 'messages' and 'model') or ('max_tokens', 'messages', 'model' and 'stream') arguments to be given\n",
714
+ "Analyzing design 202...\n",
715
+ "Error processing design 202: Missing required arguments; Expected either ('max_tokens', 'messages' and 'model') or ('max_tokens', 'messages', 'model' and 'stream') arguments to be given\n",
716
+ "Analyzing design 203...\n",
717
+ "Error processing design 203: Missing required arguments; Expected either ('max_tokens', 'messages' and 'model') or ('max_tokens', 'messages', 'model' and 'stream') arguments to be given\n",
718
+ "Analyzing design 204...\n",
719
+ "Error processing design 204: Missing required arguments; Expected either ('max_tokens', 'messages' and 'model') or ('max_tokens', 'messages', 'model' and 'stream') arguments to be given\n",
720
+ "Failed to analyze design 200\n",
721
+ "Failed to analyze design 201\n",
722
+ "Failed to analyze design 202\n",
723
+ "Failed to analyze design 203\n",
724
+ "Failed to analyze design 204\n",
725
+ "\n",
726
+ "Analysis complete:\n",
727
+ "Successful: 0\n",
728
+ "Failed: 5\n",
729
+ "Total: 5\n",
730
  "\n",
731
+ "Running basic analysis...\n",
732
+ "Starting analysis of 5 designs...\n",
733
+ "\n",
734
+ "Processing batch 1 (5 designs)...\n",
735
+ "Analyzing design 200...\n",
736
+ "Error processing design 200: Missing required arguments; Expected either ('max_tokens', 'messages' and 'model') or ('max_tokens', 'messages', 'model' and 'stream') arguments to be given\n",
737
+ "Analyzing design 201...\n",
738
+ "Error processing design 201: Missing required arguments; Expected either ('max_tokens', 'messages' and 'model') or ('max_tokens', 'messages', 'model' and 'stream') arguments to be given\n",
739
+ "Analyzing design 202...\n",
740
+ "Error processing design 202: Missing required arguments; Expected either ('max_tokens', 'messages' and 'model') or ('max_tokens', 'messages', 'model' and 'stream') arguments to be given\n",
741
+ "Analyzing design 203...\n",
742
+ "Error processing design 203: Missing required arguments; Expected either ('max_tokens', 'messages' and 'model') or ('max_tokens', 'messages', 'model' and 'stream') arguments to be given\n",
743
+ "Analyzing design 204...\n",
744
+ "Error processing design 204: Missing required arguments; Expected either ('max_tokens', 'messages' and 'model') or ('max_tokens', 'messages', 'model' and 'stream') arguments to be given\n",
745
+ "Failed to analyze design 200\n",
746
+ "Failed to analyze design 201\n",
747
+ "Failed to analyze design 202\n",
748
+ "Failed to analyze design 203\n",
749
+ "Failed to analyze design 204\n",
750
+ "\n",
751
+ "Analysis complete:\n",
752
+ "Successful: 0\n",
753
+ "Failed: 5\n",
754
+ "Total: 5\n"
755
  ]
756
  }
757
  ],
758
  "source": [
 
 
 
759
  "\n",
760
+ "# Test with detailed analysis\n",
761
+ "print(\"Running detailed analysis...\")\n",
762
+ "analysis_test_set = [f\"{i:03d}\" for i in range(200, 205)]\n",
763
+ "await test_analyzer(\n",
764
+ " design_ids=analysis_test_set,\n",
765
+ " batch_size=5,\n",
766
+ " detailed=True,\n",
767
+ " output_path=Path(\"analyses/detailed\")\n",
768
+ ")\n",
 
769
  "\n",
770
+ "# Test with basic analysis\n",
771
+ "print(\"\\nRunning basic analysis...\")\n",
772
+ "await test_analyzer(\n",
773
+ " design_ids=analysis_test_set,\n",
774
+ " batch_size=5,\n",
775
+ " detailed=False,\n",
776
+ " output_path=Path(\"analyses/basic\")\n",
777
+ ")"
778
  ]
779
  }
780
  ],