userIdc2024 commited on
Commit
53e2f35
·
verified ·
1 Parent(s): 105f97a

Update main.py

Browse files
Files changed (1) hide show
  1. main.py +162 -0
main.py CHANGED
@@ -0,0 +1,162 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from openai import OpenAI
2
+ from pydantic import BaseModel
3
+ import replicate
4
+ from dotenv import load_dotenv
5
+ import os
6
+ from uuid import uuid4
7
+ import requests
8
+ import boto3
9
+ import base64
10
+ from concurrent.futures import ThreadPoolExecutor, as_completed
11
+
12
+ load_dotenv()
13
+
14
+ gpt_client = OpenAI(api_key=os.getenv("GEMENI_KEY"),
15
+ base_url="https://generativelanguage.googleapis.com/v1beta/openai/")
16
+
17
+ class GeneratedPrompt(BaseModel):
18
+ prompt: str
19
+
20
+ def image_url_to_base64(url):
21
+ response = requests.get(url, stream=True)
22
+ response.raise_for_status()
23
+
24
+ content_type = response.headers['Content-Type']
25
+
26
+ encoded_string = base64.b64encode(response.content).decode('utf-8')
27
+
28
+ return f"data:{content_type};base64,{encoded_string}"
29
+
30
+
31
+ def generate_prompt(url):
32
+
33
+ system_prompt = """You are a top-tier performance digital marketer and creative strategist with 15+ years of expertise in affiliate marketing.
34
+ Your objective is to analyze the provided winning ad image, deconstruct its concept, visual composition, and color scheme, and generate a fresh, conversion-focused ad visual tailored.
35
+ The new design should convey a same as original image sentiment. Create a visually compelling ad optimized for Facebook Ads that is scroll-stopping, pattern-interrupting, and designed to drive high CTR and Conversion Rate.
36
+ Utilize striking color combinations, dynamic contrast levels, and strategic layout compositions to command attention while aligning with the target audience avatar.
37
+ Make sure the images should be realistic, not be stocky at all and raw which should look like they are shot from an iPhone."""
38
+
39
+ messages = [
40
+ {
41
+ "role": "system",
42
+ "content": [
43
+ {
44
+ "type": "text",
45
+ "text": system_prompt
46
+ }
47
+ ]
48
+ },
49
+ {
50
+ "role": "user",
51
+ "content": [
52
+ {
53
+ "type": "text",
54
+ "text": "Generate the prompt for the given ad image."
55
+ },
56
+ {
57
+ "type": "image_url",
58
+ "image_url": {
59
+ "url": url
60
+ }
61
+ }
62
+ ]
63
+ }
64
+ ]
65
+
66
+ response = gpt_client.beta.chat.completions.parse(
67
+ model="gemini-2.0-flash",
68
+ messages=messages,
69
+ response_format=GeneratedPrompt,
70
+
71
+ )
72
+
73
+ final_prompt = response.choices[0].message.parsed
74
+ final_prompt = final_prompt.prompt
75
+
76
+ return final_prompt
77
+
78
+ def generate_images(prompt):
79
+ replicate_client = replicate.Client(api_token=os.getenv("REPLICATE_API_TOKEN"))
80
+ output = replicate_client.run(
81
+ "google/imagen-4-ultra",
82
+ input={
83
+ "prompt": prompt,
84
+ "aspect_ratio": "1:1"
85
+ }
86
+ )
87
+
88
+ print(output)
89
+ urls = []
90
+ if isinstance(output, list) and output:
91
+ first = output[0]
92
+ url = getattr(first, "url", str(first))
93
+ urls = [url]
94
+ elif isinstance(output, str):
95
+ urls = [output]
96
+ elif hasattr(output, "url"):
97
+ urls = [getattr(output, "url")]
98
+
99
+ return urls[0]
100
+
101
+ def fetch_image_bytes(url):
102
+ r = requests.get(url, timeout=60)
103
+ r.raise_for_status()
104
+ return r.content
105
+
106
+ def init_s3():
107
+
108
+ return boto3.client(
109
+ "s3",
110
+ endpoint_url=os.getenv("R2_ENDPOINT"),
111
+ aws_access_key_id=os.getenv("R2_ACCESS_KEY"),
112
+ aws_secret_access_key=os.getenv("R2_SECRET_KEY"),
113
+ region_name="auto",
114
+ )
115
+
116
+ def upload_to_r2(image_bytes):
117
+ s3_client = init_s3()
118
+
119
+ filename = f"{uuid4().hex}.png"
120
+ file_key = f"infinityverse/{filename}"
121
+ s3_client.put_object(
122
+ Bucket=os.getenv("R2_BUCKET_NAME"),
123
+ Key=file_key,
124
+ Body=image_bytes,
125
+ ContentType="image/png",
126
+ )
127
+ r2_url = f'{os.getenv("NEW_BASE").rstrip("/")}/{file_key}'
128
+ return r2_url
129
+
130
+ def get_images(reference_images):
131
+ items = reference_images.get("items", [])
132
+ results = []
133
+ max_workers = min(32, (os.cpu_count() or 1) * 2)
134
+
135
+ for image in items:
136
+ num = int(image["num"])
137
+ ref_url = image["ref_url"]
138
+ base = image_url_to_base64(ref_url)
139
+ urls = []
140
+
141
+ with ThreadPoolExecutor(max_workers=min(max_workers, max(1, num))) as ex:
142
+ futures = [
143
+ ex.submit(
144
+ lambda b=base: upload_to_r2(
145
+ fetch_image_bytes(
146
+ generate_images(
147
+ generate_prompt(b)
148
+ )
149
+ )
150
+ )
151
+ )
152
+ for _ in range(num)
153
+ ]
154
+ for f in as_completed(futures):
155
+ try:
156
+ urls.append(f.result())
157
+ except Exception:
158
+ pass
159
+
160
+ results.append({"ref_url": ref_url, "urls": urls})
161
+
162
+ return results