Update app.py
Browse files
app.py
CHANGED
@@ -24,19 +24,6 @@ def init_api_keys():
|
|
24 |
if 'OPENAI_API_KEY' not in os.environ:
|
25 |
os.environ['OPENAI_API_KEY'] = getpass.getpass('OpenAI API key:')
|
26 |
|
27 |
-
# Embedding Functions
|
28 |
-
@pxt.expr_udf
|
29 |
-
def e5_embed(text: str) -> np.ndarray:
|
30 |
-
return sentence_transformer(text, model_id='intfloat/e5-large-v2')
|
31 |
-
|
32 |
-
@pxt.expr_udf
|
33 |
-
def embed_image(img: PIL.Image.Image):
|
34 |
-
return clip_image(img, model_id='openai/clip-vit-base-patch32')
|
35 |
-
|
36 |
-
@pxt.expr_udf
|
37 |
-
def str_embed(s: str):
|
38 |
-
return clip_text(s, model_id='openai/clip-vit-base-patch32')
|
39 |
-
|
40 |
# Common Utilities
|
41 |
def initialize_pixeltable(dir_name='unified_app'):
|
42 |
"""Initialize Pixeltable directory"""
|
@@ -53,7 +40,7 @@ def create_prompt(top_k_list: list[dict], question: str) -> str:
|
|
53 |
QUESTION:
|
54 |
{question}'''
|
55 |
|
56 |
-
@pxt.udf(return_type=pxt.
|
57 |
def generate_audio(script: str, voice: str, api_key: str):
|
58 |
"""Generate audio from text using OpenAI's API"""
|
59 |
if not script or not voice:
|
@@ -87,7 +74,7 @@ class DocumentProcessor:
|
|
87 |
|
88 |
docs = pxt.create_table(
|
89 |
'unified_app.documents',
|
90 |
-
{'document': pxt.
|
91 |
)
|
92 |
|
93 |
docs.insert({'document': file.name} for file in pdf_files if file.name.endswith('.pdf'))
|
@@ -102,7 +89,7 @@ class DocumentProcessor:
|
|
102 |
)
|
103 |
)
|
104 |
|
105 |
-
chunks.add_embedding_index('text', string_embed=
|
106 |
return "Documents processed successfully. You can start asking questions."
|
107 |
|
108 |
@staticmethod
|
@@ -117,14 +104,14 @@ class DocumentProcessor:
|
|
117 |
temp_table = pxt.create_table(
|
118 |
'unified_app.temp_response',
|
119 |
{
|
120 |
-
'question': pxt.
|
121 |
-
'context': pxt.
|
122 |
}
|
123 |
)
|
124 |
|
125 |
temp_table.insert([{'question': question, 'context': context}])
|
126 |
|
127 |
-
temp_table
|
128 |
messages=[
|
129 |
{
|
130 |
'role': 'system',
|
@@ -136,7 +123,7 @@ class DocumentProcessor:
|
|
136 |
}
|
137 |
],
|
138 |
model='gpt-4o-mini-2024-07-18'
|
139 |
-
)
|
140 |
|
141 |
answer = temp_table.select(
|
142 |
answer=temp_table.response.choices[0].message.content
|
@@ -157,12 +144,12 @@ class CallAnalyzer:
|
|
157 |
initialize_pixeltable()
|
158 |
calls = pxt.create_table(
|
159 |
'unified_app.calls',
|
160 |
-
{"video": pxt.
|
161 |
)
|
162 |
|
163 |
-
calls
|
164 |
-
calls
|
165 |
-
calls
|
166 |
|
167 |
sentences = pxt.create_view(
|
168 |
'unified_app.sentences',
|
@@ -170,7 +157,7 @@ class CallAnalyzer:
|
|
170 |
iterator=StringSplitter.create(text=calls.text, separators='sentence')
|
171 |
)
|
172 |
|
173 |
-
sentences.add_embedding_index('text', string_embed=
|
174 |
|
175 |
@pxt.udf
|
176 |
def generate_insights(text: str) -> list[dict]:
|
@@ -179,11 +166,11 @@ class CallAnalyzer:
|
|
179 |
{'role': 'user', 'content': text}
|
180 |
]
|
181 |
|
182 |
-
calls
|
183 |
-
calls
|
184 |
messages=calls.insights_prompt,
|
185 |
model='gpt-4o-mini-2024-07-18'
|
186 |
-
).choices[0].message.content
|
187 |
|
188 |
calls.insert([{"video": video_file}])
|
189 |
|
@@ -200,15 +187,21 @@ class VideoSearcher:
|
|
200 |
"""Process video for searching"""
|
201 |
try:
|
202 |
initialize_pixeltable()
|
203 |
-
videos = pxt.create_table('unified_app.videos', {'video': pxt.
|
204 |
|
205 |
frames = pxt.create_view(
|
206 |
'unified_app.frames',
|
207 |
videos,
|
208 |
iterator=FrameIterator.create(video=videos.video, fps=1)
|
209 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
210 |
|
211 |
-
frames.add_embedding_index('frame', string_embed=str_embed, image_embed=embed_image)
|
212 |
videos.insert([{'video': video_file.name}])
|
213 |
|
214 |
return "Video processed and indexed for search."
|
|
|
24 |
if 'OPENAI_API_KEY' not in os.environ:
|
25 |
os.environ['OPENAI_API_KEY'] = getpass.getpass('OpenAI API key:')
|
26 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
27 |
# Common Utilities
|
28 |
def initialize_pixeltable(dir_name='unified_app'):
|
29 |
"""Initialize Pixeltable directory"""
|
|
|
40 |
QUESTION:
|
41 |
{question}'''
|
42 |
|
43 |
+
@pxt.udf(return_type=pxt.Audio)
|
44 |
def generate_audio(script: str, voice: str, api_key: str):
|
45 |
"""Generate audio from text using OpenAI's API"""
|
46 |
if not script or not voice:
|
|
|
74 |
|
75 |
docs = pxt.create_table(
|
76 |
'unified_app.documents',
|
77 |
+
{'document': pxt.Document}
|
78 |
)
|
79 |
|
80 |
docs.insert({'document': file.name} for file in pdf_files if file.name.endswith('.pdf'))
|
|
|
89 |
)
|
90 |
)
|
91 |
|
92 |
+
chunks.add_embedding_index('text', string_embed=sentence_transformer.using(model_id='intfloat/e5-large-v2'))
|
93 |
return "Documents processed successfully. You can start asking questions."
|
94 |
|
95 |
@staticmethod
|
|
|
104 |
temp_table = pxt.create_table(
|
105 |
'unified_app.temp_response',
|
106 |
{
|
107 |
+
'question': pxt.String,
|
108 |
+
'context': pxt.String
|
109 |
}
|
110 |
)
|
111 |
|
112 |
temp_table.insert([{'question': question, 'context': context}])
|
113 |
|
114 |
+
temp_table.add_computed_column(response=openai.chat_completions(
|
115 |
messages=[
|
116 |
{
|
117 |
'role': 'system',
|
|
|
123 |
}
|
124 |
],
|
125 |
model='gpt-4o-mini-2024-07-18'
|
126 |
+
))
|
127 |
|
128 |
answer = temp_table.select(
|
129 |
answer=temp_table.response.choices[0].message.content
|
|
|
144 |
initialize_pixeltable()
|
145 |
calls = pxt.create_table(
|
146 |
'unified_app.calls',
|
147 |
+
{"video": pxt.Video}
|
148 |
)
|
149 |
|
150 |
+
calls.add_computed_column(audio=extract_audio(calls.video, format='mp3'))
|
151 |
+
calls.add_computed_column(transcription=openai.transcriptions(audio=calls.audio, model='whisper-1'))
|
152 |
+
calls.add_computed_column(text=calls.transcription.text)
|
153 |
|
154 |
sentences = pxt.create_view(
|
155 |
'unified_app.sentences',
|
|
|
157 |
iterator=StringSplitter.create(text=calls.text, separators='sentence')
|
158 |
)
|
159 |
|
160 |
+
sentences.add_embedding_index('text', string_embed=sentence_transformer.using(model_id='intfloat/e5-large-v2'))
|
161 |
|
162 |
@pxt.udf
|
163 |
def generate_insights(text: str) -> list[dict]:
|
|
|
166 |
{'role': 'user', 'content': text}
|
167 |
]
|
168 |
|
169 |
+
calls.add_computed_column(insights_prompt=generate_insights(calls.text))
|
170 |
+
calls.add_computed_column(insights=openai.chat_completions(
|
171 |
messages=calls.insights_prompt,
|
172 |
model='gpt-4o-mini-2024-07-18'
|
173 |
+
).choices[0].message.content)
|
174 |
|
175 |
calls.insert([{"video": video_file}])
|
176 |
|
|
|
187 |
"""Process video for searching"""
|
188 |
try:
|
189 |
initialize_pixeltable()
|
190 |
+
videos = pxt.create_table('unified_app.videos', {'video': pxt.Video})
|
191 |
|
192 |
frames = pxt.create_view(
|
193 |
'unified_app.frames',
|
194 |
videos,
|
195 |
iterator=FrameIterator.create(video=videos.video, fps=1)
|
196 |
)
|
197 |
+
|
198 |
+
|
199 |
+
# Embedding Functions
|
200 |
+
frames.add_embedding_index('frame',
|
201 |
+
string_embed=clip_text.using(model_id='openai/clip-vit-base-patch32'),
|
202 |
+
image_embed=clip_image.using(model_id='openai/clip-vit-base-patch32')
|
203 |
+
)
|
204 |
|
|
|
205 |
videos.insert([{'video': video_file.name}])
|
206 |
|
207 |
return "Video processed and indexed for search."
|