ehaemmma commited on
Commit
73f6946
·
verified ·
1 Parent(s): 0ccf92e

Beta version

Browse files
Files changed (1) hide show
  1. app.py +207 -0
app.py ADDED
@@ -0,0 +1,207 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import requests
3
+ from PIL import Image
4
+ from pdf2image import convert_from_path
5
+ from typing import List, Union, Dict, Optional, Tuple
6
+ from io import BytesIO
7
+ import base64
8
+ import numpy as np
9
+ import json
10
+
11
+ prompt = """You are an advanced document parsing bot. Given the fixture schedule I provided, you need to parse out
12
+
13
+ 1. the name of the fixture
14
+ 2. the company that produces this fixture
15
+ 3. the part number of this fixture. It is a series of specification codes connected with - , and you can get the info by reading the texts marked in a different color or reading the top bar. Include every specification code in a correct order in your answer.
16
+ 4. the input wattage of this fixture, short answer. Please answer the wattage according to the part number you found in question 3
17
+
18
+ Please format your response in json format
19
+ {
20
+ "fixture_name": <fixture name>,
21
+ "manufacture_name": <company name>,
22
+ "mfr": <part number>,
23
+ "input wattage": <numerical input wattage>
24
+ }
25
+
26
+ ---
27
+ For example
28
+ {
29
+ "fixture_name": "SW24/1.5 Led Strips - Static White",
30
+ "manufacture_name": "Q-Tran Inc.",
31
+ "mfr": "SW24-1.5-DRY-30-BW-BW-WH-CL2-535",
32
+ "input wattage": "1.5W"
33
+ }"""
34
+
35
+ def query_openai_api(messages, model, temperature=0, api_key=None, organization_key=None, json_mode=False):
36
+ try:
37
+ url = "https://api.openai.com/v1/chat/completions"
38
+ if organization_key is not None:
39
+ headers = {
40
+ "Content-Type": "application/json",
41
+ "Authorization": f"Bearer {api_key}",
42
+ "OpenAI-Organization": f"{organization_key}",
43
+ }
44
+ else:
45
+ headers = {
46
+ "Content-Type": "application/json",
47
+ "Authorization": f"Bearer {api_key}",
48
+ }
49
+ data = {"model": model, "messages": messages, "temperature": temperature}
50
+ if json_mode:
51
+ data["response_format"] = {"type": "json_object"}
52
+
53
+ # Make the POST request and return the response
54
+ response = requests.post(url, headers=headers, data=json.dumps(data)).json()
55
+ print(response)
56
+ return response["choices"][0]["message"]["content"].lstrip(), response
57
+ except Exception as e:
58
+ print(f"An error occurred: {e}")
59
+ return f"API_ERROR: {e}", None
60
+
61
+ class GPT4V_Client:
62
+ def __init__(self, api_key, organization_key, model_name="gpt-4-vision-preview", max_tokens=512):
63
+ self.api_key = api_key
64
+ self.organization_key = organization_key
65
+ # self.client = OpenAI(api_key=api_key)
66
+ self.model_name = model_name
67
+ self.max_tokens = max_tokens
68
+
69
+ def chat(self, messages, json_mode):
70
+ return query_openai_api(messages, self.model_name, api_key=self.api_key, organization_key=self.organization_key, json_mode=json_mode)
71
+
72
+ def one_step_chat(
73
+ self,
74
+ text,
75
+ image: Union[Image.Image, np.ndarray],
76
+ system_msg: Optional[str] = None,
77
+ json_mode=False,
78
+ ):
79
+ jpeg_buffer = BytesIO()
80
+
81
+ # Save the image as JPEG to the buffer
82
+ if isinstance(image, np.ndarray):
83
+ image = Image.fromarray(image)
84
+ image = image.convert("RGB")
85
+ image.save(jpeg_buffer, format="JPEG")
86
+
87
+ # Get the byte data from the buffer
88
+ jpeg_data = jpeg_buffer.getvalue()
89
+
90
+ # Encode the JPEG image data in base64
91
+ jpg_base64 = base64.b64encode(jpeg_data)
92
+
93
+ # If you need it in string format
94
+ jpg_base64_str = jpg_base64.decode("utf-8")
95
+ messages = []
96
+ if system_msg is not None:
97
+ messages.append({"role": "system", "content": system_msg})
98
+ messages += [
99
+ {
100
+ "role": "user",
101
+ "content": [
102
+ {"type": "text", "text": text},
103
+ {
104
+ "type": "image_url",
105
+ "image_url": {
106
+ "url": f"data:image/jpeg;base64,{jpg_base64_str}"
107
+ },
108
+ },
109
+ ],
110
+ }
111
+ ]
112
+ return self.chat(messages, json_mode=json_mode)
113
+
114
+ def one_step_multi_image_chat(
115
+ self,
116
+ text,
117
+ images: list[Union[Image.Image, np.ndarray]],
118
+ system_msg: Optional[str] = None,
119
+ json_mode=False,
120
+ ):
121
+ """
122
+ images: [{"image": PIL.image, "detail": "high" or "low }]
123
+
124
+ For low res mode, we expect a 512px x 512px image. For high res mode, the short side of the image should be less than 768px and the long side should be less than 2,000px.
125
+ """
126
+ details = [i["detail"] for i in images]
127
+ img_strs = []
128
+ for img_info in images:
129
+ image = img_info["image"]
130
+ jpeg_buffer = BytesIO()
131
+
132
+ # Save the image as JPEG to the buffer
133
+ if isinstance(image, np.ndarray):
134
+ image = Image.fromarray(image)
135
+ image = image.convert("RGB")
136
+ image.save(jpeg_buffer, format="JPEG")
137
+
138
+ # Get the byte data from the buffer
139
+ jpeg_data = jpeg_buffer.getvalue()
140
+
141
+ # Encode the JPEG image data in base64
142
+ jpg_base64 = base64.b64encode(jpeg_data)
143
+
144
+ # If you need it in string format
145
+ jpg_base64_str = jpg_base64.decode("utf-8")
146
+ img_strs.append(f"data:image/jpeg;base64,{jpg_base64_str}")
147
+ messages = []
148
+ if system_msg is not None:
149
+ messages.append({"role": "system", "content": system_msg})
150
+
151
+ img_sub_msg = [
152
+ {
153
+ "type": "image_url",
154
+ "image_url": {"url": img_str, "detail": detail},
155
+ }
156
+ for img_str, detail in zip(img_strs, details)
157
+ ]
158
+ messages += [
159
+ {
160
+ "role": "user",
161
+ "content": [
162
+ {"type": "text", "text": text},
163
+ ]
164
+ + img_sub_msg,
165
+ }
166
+ ]
167
+ return self.chat(messages, json_mode=json_mode)
168
+
169
+ def markdown_json_to_table(markdown_json_string, iteration):
170
+ if markdown_json_string[0] == '`':
171
+ json_string = markdown_json_string.strip("```json\n").rstrip("```")
172
+ json_object = json.loads(json_string)
173
+ values = json_object.values()
174
+ if iteration == 0:
175
+ headers = json_object.keys()
176
+ markdown_table = "| " + " | ".join(headers) + " |\n" + \
177
+ "|---" * len(json_object) + "|\n" + \
178
+ "| " + " | ".join(map(str, values)) + " |"
179
+ else:
180
+ markdown_table = "|---" * len(json_object) + "|\n" + \
181
+ "| " + " | ".join(map(str, values)) + " |"
182
+ else:
183
+ markdown_table = ""
184
+ return markdown_table
185
+
186
+ def gptRead(cutsheets, api_key, organization_key):
187
+ fixtureInfo = ""
188
+ iteration = 0
189
+ for cutsheet in cutsheets:
190
+ source = (convert_from_path(cutsheet.name))[0]
191
+ client = GPT4V_Client(api_key=api_key, organization_key=organization_key)
192
+ fixtureInfo += markdown_json_to_table(client.one_step_chat(prompt, source)[0], iteration)
193
+ iteration += 1
194
+ return fixtureInfo
195
+
196
+ if __name__ == "__main__":
197
+ with gr.Blocks() as demo:
198
+ gr.Markdown("# Lighting Manufacture Cutsheet GPT Tool")
199
+ api_key = gr.Textbox(label = "Input your ChatGPT4 API Key: ")
200
+ organization_key = gr.Textbox(label = "Input your ChatGPT4 API Organization Key: ", info = "(optional)")
201
+ # image = gr.Image()
202
+ file_uploader = gr.UploadButton("Upload cutsheets", type="filepath", file_count="multiple")
203
+ form = gr.Markdown()
204
+ file_uploader.upload(gptRead, [file_uploader, api_key, organization_key], form)
205
+
206
+ demo.launch(share=True)
207
+