Spaces:
Running
Running
Upload 6 files
Browse files- brochure3-400x400.jpg +0 -0
- logo.svg +20 -0
- price_calc.py +196 -0
- quality-unfolded-brochures_1_.png +0 -0
- requirements.txt +10 -0
- unfolded-glossy-brochures.png +0 -0
brochure3-400x400.jpg
ADDED
![]() |
logo.svg
ADDED
|
price_calc.py
ADDED
@@ -0,0 +1,196 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import base64
|
2 |
+
import gradio as gr
|
3 |
+
from openai import OpenAI
|
4 |
+
import os
|
5 |
+
import dotenv
|
6 |
+
|
7 |
+
dotenv.load_dotenv()
|
8 |
+
|
9 |
+
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
|
10 |
+
|
11 |
+
script_dir = os.path.dirname(os.path.abspath(__file__))
|
12 |
+
|
13 |
+
printer_1 = """
|
14 |
+
printerOne
|
15 |
+
Product: Business Cards
|
16 |
+
Size 2x3.5
|
17 |
+
Quantity,Price per Unit ($)
|
18 |
+
25,2.0
|
19 |
+
50,1.6
|
20 |
+
100,1.0
|
21 |
+
200,0.7
|
22 |
+
500,0.36
|
23 |
+
1000,0.2
|
24 |
+
2000,0.14
|
25 |
+
5000,0.12
|
26 |
+
10000,0.09
|
27 |
+
20000,0.07
|
28 |
+
"""
|
29 |
+
|
30 |
+
printer_2 = """
|
31 |
+
BannerLord
|
32 |
+
Product: Business Cards
|
33 |
+
Size 2x3.5
|
34 |
+
Quantity,Price per Unit ($)
|
35 |
+
25,2.4
|
36 |
+
50,1.8
|
37 |
+
100,1.2
|
38 |
+
200,0.75
|
39 |
+
500,0.4
|
40 |
+
1000,0.22
|
41 |
+
2000,0.15
|
42 |
+
5000,0.14
|
43 |
+
10000,0.1
|
44 |
+
20000,0.075
|
45 |
+
"""
|
46 |
+
|
47 |
+
printer_3 = """
|
48 |
+
PrintMaster
|
49 |
+
Product: Business Cards
|
50 |
+
Size 2x3.5
|
51 |
+
Quantity,Price per Unit ($)
|
52 |
+
50,1.4
|
53 |
+
75,1.2
|
54 |
+
100,1.05
|
55 |
+
150,1
|
56 |
+
200,0.875
|
57 |
+
250,0.72
|
58 |
+
500,0.4
|
59 |
+
750,0.4
|
60 |
+
1000,0.35
|
61 |
+
1500,0.3
|
62 |
+
2000,0.25
|
63 |
+
"""
|
64 |
+
|
65 |
+
|
66 |
+
def find_best_price(request):
|
67 |
+
chat_prompt = (
|
68 |
+
"You are a customer assistant and you have to find the best price for the customer. "
|
69 |
+
"Here are the prices from the printers:\n"
|
70 |
+
f"Printer 1:\n{printer_1}\n"
|
71 |
+
f"Printer 2:\n{printer_2}\n"
|
72 |
+
f"Printer 3:\n{printer_3}\n"
|
73 |
+
"Check if the requested size is available from the printers. If not, provide the nearest size available."
|
74 |
+
"Do not do a linear interpolation. Use the nearest lower quantity pricing and multiply user's amount by nearest price per unit."
|
75 |
+
"Example:\n"
|
76 |
+
"User: I want to print 600 brochures\n"
|
77 |
+
"Answer:\n"
|
78 |
+
"Printer 1: 500 brochures for $0.36 each. 600 * 0.36 = $216\n"
|
79 |
+
"###"
|
80 |
+
"Printer 2: 500 brochures for $0.4 each. 600 * 0.4 = $240\n"
|
81 |
+
"###"
|
82 |
+
"Printer 3: 500 brochures for $0.4 each. 600 * 0.4 = $240\n"
|
83 |
+
"The '###' symbol separates the printer options. It is important to keep it in the response."
|
84 |
+
)
|
85 |
+
|
86 |
+
chat_response = client.chat.completions.create(
|
87 |
+
model="gpt-4o-mini",
|
88 |
+
messages=[
|
89 |
+
{"role": "system", "content": chat_prompt},
|
90 |
+
{"role": "user", "content": request},
|
91 |
+
],
|
92 |
+
)
|
93 |
+
|
94 |
+
chat_text = chat_response.choices[0].message.content
|
95 |
+
|
96 |
+
html_page = render_html_page(chat_text)
|
97 |
+
|
98 |
+
return chat_text, html_page
|
99 |
+
|
100 |
+
|
101 |
+
def render_html_page(chat_text):
|
102 |
+
images = [
|
103 |
+
os.path.join(script_dir, "public/src/brochure3-400x400.jpg"),
|
104 |
+
os.path.join(script_dir, "public/src/quality-unfolded-brochures_1_.png"),
|
105 |
+
os.path.join(script_dir, "public/src/unfolded-glossy-brochures.png"),
|
106 |
+
]
|
107 |
+
product_links = [
|
108 |
+
"https://www.example.com/product_image.jpg",
|
109 |
+
"https://www.example.com/product_image.jpg",
|
110 |
+
"https://www.example.com/product_image.jpg",
|
111 |
+
]
|
112 |
+
|
113 |
+
# Split chat_text into product descriptions
|
114 |
+
product_descriptions = chat_text.split("###")
|
115 |
+
|
116 |
+
# Generate HTML content
|
117 |
+
html_content = """
|
118 |
+
<html>
|
119 |
+
<head>
|
120 |
+
<title>Product Cards</title>
|
121 |
+
<style>
|
122 |
+
.product-card {
|
123 |
+
border: 1px solid #ccc;
|
124 |
+
border-radius: 5px;
|
125 |
+
padding: 16px;
|
126 |
+
margin: 16px;
|
127 |
+
text-align: center;
|
128 |
+
width: 200px;
|
129 |
+
display: inline-block;
|
130 |
+
vertical-align: top;
|
131 |
+
}
|
132 |
+
.product-card img {
|
133 |
+
max-width: 100%;
|
134 |
+
height: auto;
|
135 |
+
}
|
136 |
+
.product-card button {
|
137 |
+
background-color: #4CAF50;
|
138 |
+
color: white;
|
139 |
+
padding: 10px 20px;
|
140 |
+
border: none;
|
141 |
+
border-radius: 5px;
|
142 |
+
cursor: pointer;
|
143 |
+
}
|
144 |
+
.product-card button:hover {
|
145 |
+
background-color: #45a049;
|
146 |
+
}
|
147 |
+
</style>
|
148 |
+
</head>
|
149 |
+
<body>
|
150 |
+
"""
|
151 |
+
|
152 |
+
for i, description in enumerate(product_descriptions):
|
153 |
+
image = images[i % len(images)]
|
154 |
+
with open(image, "rb") as img_file:
|
155 |
+
base64_image = base64.b64encode(img_file.read()).decode("utf-8")
|
156 |
+
|
157 |
+
product_link = product_links[i % len(product_links)]
|
158 |
+
html_content += f"""
|
159 |
+
<div class="product-card">
|
160 |
+
<img src="data:image/jpeg;base64,{base64_image}" alt="Product Image">
|
161 |
+
<p>{description}</p>
|
162 |
+
<a href="{product_link}" target="_blank"><button>Buy Now</button></a>
|
163 |
+
</div>
|
164 |
+
"""
|
165 |
+
|
166 |
+
html_content += """
|
167 |
+
</body>
|
168 |
+
</html>
|
169 |
+
"""
|
170 |
+
return html_content
|
171 |
+
|
172 |
+
|
173 |
+
logo = os.path.join(script_dir, "public/src/logo.svg")
|
174 |
+
with open(logo, "rb") as logo_file:
|
175 |
+
base64_logo = base64.b64encode(logo_file.read()).decode("utf-8")
|
176 |
+
|
177 |
+
|
178 |
+
iface = gr.Interface(
|
179 |
+
fn=find_best_price,
|
180 |
+
inputs=gr.Textbox(lines=3, placeholder="Enter what are you looking for"),
|
181 |
+
outputs=[
|
182 |
+
gr.Textbox(label="Result"),
|
183 |
+
gr.HTML(label="Product Image"),
|
184 |
+
],
|
185 |
+
title="Get Instant Quote",
|
186 |
+
description=f"""
|
187 |
+
<div style="display: flex; justify-content: center; align-items: center; text-align: center; margin-bottom: 20px;">
|
188 |
+
<img src="data:image/svg+xml;base64,{base64_logo}" alt="Logo" style="width: 150px; height: auto;">
|
189 |
+
</div>
|
190 |
+
""",
|
191 |
+
submit_btn="Get quote",
|
192 |
+
)
|
193 |
+
|
194 |
+
valid_users = [("admin", "password123"), ("user1", "pass456")]
|
195 |
+
|
196 |
+
iface.launch(auth=valid_users)
|
quality-unfolded-brochures_1_.png
ADDED
![]() |
requirements.txt
ADDED
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
gradio==4.44.1
|
2 |
+
openai==1.55.3
|
3 |
+
pillow==10.4.0
|
4 |
+
python-dotenv
|
5 |
+
pymupdf
|
6 |
+
pytesseract
|
7 |
+
pillow
|
8 |
+
pdfplumber
|
9 |
+
pdf2image
|
10 |
+
poppler-utils
|
unfolded-glossy-brochures.png
ADDED
![]() |