Spaces:
Runtime error
Runtime error
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."
|