palondomus commited on
Commit
5ffb1d1
·
0 Parent(s):

Mostly works trying for huggingface

Browse files
.gitattributes ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ *.7z filter=lfs diff=lfs merge=lfs -text
2
+ *.arrow filter=lfs diff=lfs merge=lfs -text
3
+ *.bin filter=lfs diff=lfs merge=lfs -text
4
+ *.bz2 filter=lfs diff=lfs merge=lfs -text
5
+ *.ckpt filter=lfs diff=lfs merge=lfs -text
6
+ *.ftz filter=lfs diff=lfs merge=lfs -text
7
+ *.gz filter=lfs diff=lfs merge=lfs -text
8
+ *.h5 filter=lfs diff=lfs merge=lfs -text
9
+ *.joblib filter=lfs diff=lfs merge=lfs -text
10
+ *.lfs.* filter=lfs diff=lfs merge=lfs -text
11
+ *.mlmodel filter=lfs diff=lfs merge=lfs -text
12
+ *.model filter=lfs diff=lfs merge=lfs -text
13
+ *.msgpack filter=lfs diff=lfs merge=lfs -text
14
+ *.npy filter=lfs diff=lfs merge=lfs -text
15
+ *.npz filter=lfs diff=lfs merge=lfs -text
16
+ *.onnx filter=lfs diff=lfs merge=lfs -text
17
+ *.ot filter=lfs diff=lfs merge=lfs -text
18
+ *.parquet filter=lfs diff=lfs merge=lfs -text
19
+ *.pb filter=lfs diff=lfs merge=lfs -text
20
+ *.pickle filter=lfs diff=lfs merge=lfs -text
21
+ *.pkl filter=lfs diff=lfs merge=lfs -text
22
+ *.pt filter=lfs diff=lfs merge=lfs -text
23
+ *.pth filter=lfs diff=lfs merge=lfs -text
24
+ *.rar filter=lfs diff=lfs merge=lfs -text
25
+ *.safetensors filter=lfs diff=lfs merge=lfs -text
26
+ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
27
+ *.tar.* filter=lfs diff=lfs merge=lfs -text
28
+ *.tar filter=lfs diff=lfs merge=lfs -text
29
+ *.tflite filter=lfs diff=lfs merge=lfs -text
30
+ *.tgz filter=lfs diff=lfs merge=lfs -text
31
+ *.wasm filter=lfs diff=lfs merge=lfs -text
32
+ *.xz filter=lfs diff=lfs merge=lfs -text
33
+ *.zip filter=lfs diff=lfs merge=lfs -text
34
+ *.zst filter=lfs diff=lfs merge=lfs -text
35
+ *tfevents* filter=lfs diff=lfs merge=lfs -text
CaesarFolderInterface/__pycache__/caesarfolderinterface.cpython-39.pyc ADDED
Binary file (1.41 kB). View file
 
CaesarFolderInterface/caesarfolderinterface.py ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from pydub import AudioSegment
2
+ import io
3
+ import os
4
+ class CaesarFolderInterface:
5
+ def __init__(self) -> None:
6
+ self.audio_input_folder = "CaesarAudioWAVs"
7
+ self.notes_folder = "CaesarNotes"
8
+ self.audio_output_folder = "CaesarAudioTranslations"
9
+ def clean_all(self):
10
+ try:
11
+ for i in os.listdir(self.audio_input_folder):
12
+ os.remove(f"{self.audio_input_folder}/{i}")
13
+ for i in os.listdir(self.notes_folder):
14
+ os.remove(f"{self.notes_folder}/{i}")
15
+ for i in os.listdir(self.audio_output_folder):
16
+ os.remove(f"{self.audio_output_folder}/{i}")
17
+
18
+ except Exception as ex:
19
+ return False
20
+ def store_audio(self,argfilename,contents):
21
+ try:
22
+ recording = AudioSegment.from_file(io.BytesIO(contents), format="mp3")
23
+ recording.export(f'{self.audio_output_folder}/{argfilename}.mp3', format='mp3')
24
+ return True
25
+ except Exception as ex:
26
+ return False
CaesarMobileTTS/__pycache__/caesarmobiletts.cpython-39.pyc ADDED
Binary file (1.86 kB). View file
 
CaesarMobileTTS/caesarmobiletts.py ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ from gtts import gTTS
3
+ from CaesarFolderInterface.caesarfolderinterface import CaesarFolderInterface
4
+ import os
5
+
6
+ class CaesarMobileTTS(CaesarFolderInterface):
7
+ def __init__(self) -> None:
8
+ super().__init__()
9
+ def load_transcription(self,argfilename):
10
+ with open(f"{self.audio_output_folder}/{argfilename}.mp3","rb") as f:
11
+ contents = f.read()
12
+ return contents
13
+
14
+ def check_file_exists(self,argfilename):
15
+ folder = self.audio_output_folder
16
+ if folder in os.listdir():
17
+ if f"{argfilename}.mp3" in os.listdir(folder):
18
+ return True
19
+ else:
20
+ return False
21
+ else:
22
+ return True
23
+ def clean_up_tts(self,argfilename):
24
+ try:
25
+ folder = self.audio_output_folder
26
+ os.remove(f"{folder}/{argfilename}.mp3")
27
+ return True
28
+ except Exception as ex:
29
+ return False
30
+
31
+ def run_tts(self,argfilename,text,language):
32
+ try:
33
+ myobj = gTTS(text=text, lang=language, slow=False)
34
+ # Saving the converted audio in a mp3 file named
35
+ # welcome
36
+ if self.audio_output_folder not in os.listdir():
37
+ os.mkdir(self.audio_output_folder)
38
+ myobj.save(f"{self.audio_output_folder}/{argfilename}.mp3")
39
+ # Playing the converted file
40
+ #os.system("mpg321 welcome.mp3")
41
+ worked = True
42
+ error = None
43
+ except Exception as ex:
44
+ worked = False
45
+ error = f"{type(ex)} - {ex}"
46
+ return worked,error
47
+
48
+
CaesarMobileTranscribe/__pycache__/caesartranscribe.cpython-39.pyc ADDED
Binary file (8.81 kB). View file
 
CaesarMobileTranscribe/caesartranscribe.py ADDED
@@ -0,0 +1,270 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import shutil
3
+ import sys
4
+ import numpy as np
5
+ # importing libraries
6
+ import requests
7
+ import glob
8
+ import soundfile as sf
9
+ import speech_recognition as sr
10
+ from pydub import AudioSegment
11
+ import pydub
12
+ AudioSegment.converter = "/usr/bin/ffmpeg"
13
+ import io
14
+ from CaesarFolderInterface.caesarfolderinterface import CaesarFolderInterface
15
+ from CaesarMobileTranslate.caesarmobiletranslate import CaesarMobileTranslate
16
+ from CaesarMobileTTS.caesarmobiletts import CaesarMobileTTS
17
+ from tqdm import tqdm
18
+
19
+
20
+ def cosine_similarity(doc1,doc2):
21
+ import spacy
22
+ nlp = spacy.load("en_core_web_sm")
23
+ doc1 = nlp(doc1)
24
+ doc2 = nlp(doc2)
25
+ similarity = np.dot(doc1.vector, doc2.vector) / (np.linalg.norm(doc1.vector) * np.linalg.norm(doc2.vector))
26
+ return similarity
27
+ # create a speech recognition object
28
+ r = sr.Recognizer()
29
+
30
+ class CaesarMobileTranscribe(CaesarFolderInterface):
31
+ def __init__(self) -> None:
32
+ super().__init__()
33
+ self.caesartrans = CaesarMobileTranslate()
34
+ self.caesartts = CaesarMobileTTS()
35
+ def create_all_dirs(self):
36
+ if self.audio_input_folder not in os.listdir():
37
+ os.mkdir(self.audio_input_folder)
38
+ if self.notes_folder not in os.listdir():
39
+ os.mkdir(self.notes_folder)
40
+ if self.audio_output_folder not in os.listdir():
41
+ os.mkdir(self.audio_output_folder)
42
+
43
+
44
+
45
+
46
+ def store_audio(self,argfilename,contents,fileformat):
47
+ try:
48
+ recording = AudioSegment.from_file(io.BytesIO(contents)) # , format=fileformat
49
+ recording.export(f'{self.audio_input_folder}/{argfilename}.wav', format='wav')
50
+ return True
51
+ except Exception as ex:
52
+ print(type(ex),ex)
53
+ return False
54
+
55
+
56
+
57
+ def send_revisionbank(self,sentences,txtfilename):
58
+ boole = True
59
+ while boole == True:
60
+ sendrevisionbank = input("Send to RevisionBank: (y) or (n)").lower()
61
+ if sendrevisionbank == "y":
62
+ cardname = f'{txtfilename.split("/")[0]}/{txtfilename.split("/")[-1].replace(".txt","").capitalize()}'
63
+ json = {"revisioncardscheduler":{"sendtoemail":"[email protected]","revisionscheduleinterval":60,"revisioncards":[{"subject":f"A-Level {cardname}","revisioncardtitle":cardname,"revisioncard":sentences}]}}
64
+ loginjson = {"email":"[email protected]","password":"kya63amari"}
65
+ try:
66
+ print("Logging in...")
67
+ access_token = requests.post("https://revisionbank.onrender.com/loginapi",json=loginjson).json()["access_token"]
68
+ headers = {"Authorization": f"Bearer {access_token}"}
69
+ print("Logged in.")
70
+ except Exception as ex:
71
+ print("Login Failed.{}:{}".format(type(ex),ex))
72
+
73
+ try:
74
+ print("Storing CaesarAI text...")
75
+ response = requests.post("https://revisionbank.onrender.com/storerevisioncards",json=json,headers=headers).json()
76
+ print("CaesarAI Stored.")
77
+ except Exception as ex:
78
+ print("CaesarAI Text not stored.".format(type(ex),ex))
79
+ boole = False
80
+ elif sendrevisionbank == "n":
81
+ boole = False
82
+ else:
83
+ boole = True
84
+
85
+ def check_if_wav(self,argfilename):
86
+ folder = self.audio_input_folder
87
+ res = ""
88
+ for i in os.listdir(folder):
89
+ if argfilename in i :
90
+ res += i
91
+ if "wav" in res:
92
+ return True
93
+ else:
94
+ return False
95
+
96
+ def mp3_to_wav(self,src,dst):
97
+ folder = self.audio_input_folder
98
+ src = f"{folder}/{src}"
99
+ dst = f"{folder}/{dst}"
100
+ sound = AudioSegment.from_mp3(src)
101
+ sound.export(dst, format="wav")
102
+ os.remove(src)
103
+ def check_file_exists(self,argfilename):
104
+ folder = self.notes_folder
105
+ if folder in os.listdir():
106
+ if f"{argfilename}.txt" in os.listdir(folder):
107
+ return True
108
+ else:
109
+ return False
110
+ else:
111
+ return True
112
+
113
+ def slice_sections(self,argfilename,largewav="large"):
114
+
115
+ filename = "{}/{}.wav".format(self.audio_input_folder,argfilename)
116
+ sound = AudioSegment.from_wav(filename)
117
+ if self.notes_folder not in os.listdir():
118
+ os.mkdir(self.notes_folder)
119
+
120
+ if largewav == "small":
121
+ sentences =""
122
+ txtfilename = "{}/{}.txt".format(self.notes_folder,argfilename)
123
+ with sr.AudioFile(filename) as source:
124
+ # listen for the data (load audio to memory)
125
+ audio_data = r.record(source)
126
+ # recognize (convert from speech to text)
127
+ text = r.recognize_google(audio_data)
128
+ #print(text)
129
+ with open(txtfilename,"w+") as f:
130
+ f.write(text)
131
+ with open(txtfilename,"r") as f:
132
+ text = f.read()
133
+ textlist = text.split("period")
134
+ #print(textlist)
135
+ with open(txtfilename,"w+") as f:
136
+ for t in textlist:
137
+ sentence = f"{t.rstrip().lstrip()}.\n".capitalize()
138
+ #print(sentence)
139
+ sentences += f"{sentence}\n"
140
+ f.write(sentence)
141
+ #print(textlist[0])
142
+ #self.send_revisionbank(sentences,txtfilename)
143
+ print(sentences)
144
+ if largewav == "large":
145
+ sentences = ""
146
+
147
+ duration = sound.duration_seconds //60
148
+ # 7 seconds - 3 minutes
149
+ #print(duration)
150
+
151
+ minute_intervals = 0.5# 0.15 or 0.50 # TODO Try 1,2 and 3 and see which is the most optimized by seeing themost words/letters collected.
152
+ percentages = [i * (minute_intervals/duration) for i in range(0,int(duration//minute_intervals))]
153
+ #print(percentages)
154
+ #percentages = [i/20 for i in range(0,20)]# 0.8
155
+
156
+
157
+ # TODO Maximum audio time is 3.8 minutes, using percentage may be inconsistent if the audio duration increases.
158
+ slicedsections = [ sound[round(percentages[i] * len(sound)):round(percentages[i+1] * len(sound))] for i in range(len(percentages)-1) ]
159
+ return slicedsections
160
+
161
+
162
+ def run_api(self,argfilename,dest,slicedsections,new_sound,verbose=0):
163
+ filename = "{}/{}.wav".format(self.audio_input_folder,argfilename)
164
+ txtfilename = "{}/{}.txt".format(self.notes_folder,argfilename)
165
+ folder_name = "audio-chunks"
166
+ print("Starting...")
167
+
168
+
169
+ for i, audio_chunk in enumerate(tqdm(slicedsections), start=1):
170
+ # create a drectory to store the audio chunks
171
+ if not os.path.isdir(folder_name):
172
+ os.mkdir(folder_name)
173
+ print("Translating chunk{}.wav...".format(i))
174
+ chunk_filename = os.path.join(folder_name, "chunk{}.wav".format(i))
175
+ audio_chunk.export(chunk_filename, format="wav")
176
+ with sr.AudioFile(chunk_filename) as source:
177
+ audio_listened = r.record(source)
178
+ # try converting it to text
179
+ try:
180
+ text = r.recognize_google(audio_listened)
181
+ except sr.UnknownValueError as e:
182
+ print("Error:", str(e))
183
+ else:
184
+ text = "{}. ".format(text.capitalize())
185
+ try:
186
+ with open(txtfilename,"a+",encoding="utf-8") as f:
187
+ f.write("{}\n".format(text))
188
+ with open(txtfilename,"r",encoding="utf-8") as f:
189
+ caesarnotesduplicate = f.readlines()
190
+ except UnicodeEncodeError as uex:
191
+ pass
192
+ try:
193
+ sim = cosine_similarity(caesarnotesduplicate[-1],caesarnotesduplicate[-2])
194
+ if sim > 0.95:
195
+ caesarnotesduplicate.remove(caesarnotesduplicate[-1])
196
+ try:
197
+ with open(txtfilename,"w+",encoding="utf-8") as f:
198
+ for word in caesarnotesduplicate:
199
+ f.write(word)
200
+ except UnicodeEncodeError as uex:
201
+ pass
202
+ except IndexError as iex:
203
+ pass
204
+ try:
205
+ print(chunk_filename, ":", text)
206
+ translation,dest,origin,src = self.caesartrans.translate(text,dest)
207
+ print(translation)
208
+ self.caesartts.run_tts(argfilename,translation,dest)
209
+ ttsfilename = f"{self.audio_output_folder}/{argfilename}.mp3"
210
+ sound = AudioSegment.from_mp3(ttsfilename)
211
+ new_sound += sound
212
+ yield i,new_sound,src,text,translation
213
+
214
+
215
+ except UnicodeEncodeError as uex:
216
+ pass
217
+ try:
218
+ shutil.rmtree('audio-chunks')
219
+ except FileNotFoundError as fex:
220
+ pass
221
+
222
+
223
+
224
+ def clean_up_wav(self,argfilename):
225
+ try:
226
+ folder = self.audio_input_folder
227
+ os.remove(f"{folder}/{argfilename}.wav")
228
+ return True
229
+ except Exception as ex:
230
+ return False
231
+
232
+ def clean_up_txt(self,argfilename):
233
+ try:
234
+ folder = self.notes_folder
235
+ os.remove(f"{folder}/{argfilename}.txt")
236
+ return True
237
+ except Exception as ex:
238
+ return False
239
+
240
+
241
+ def load_transcription(self,argfilename):
242
+ with open(f"{self.notes_folder}/{argfilename}.txt") as f:
243
+ text = f.read()
244
+ return text
245
+ def load_audio(self,argfilename,fileformat,folder):
246
+ print(f"{folder}/{argfilename}.{fileformat}")
247
+ try:
248
+ with open(f"{folder}/{argfilename}.{fileformat}","rb") as f:
249
+ contents = f.read()
250
+ return contents
251
+ except FileNotFoundError as fex:
252
+ return False
253
+
254
+
255
+ if __name__ == "__main__":
256
+ caesarmbtr = CaesarMobileTranscribe()
257
+ argfilename = "DIALOGUE_de"
258
+ dest = "fr"
259
+ ttsfilename_new = f"{caesarmbtr.audio_output_folder}/{argfilename}_new.mp3"
260
+ new_sound = AudioSegment.empty()
261
+ sliced_sections = caesarmbtr.slice_sections(argfilename)
262
+ for i,new_sound in caesarmbtr.run_api(argfilename,dest,sliced_sections,new_sound):
263
+ print(f"{i}:")
264
+
265
+ new_sound.export(ttsfilename_new, format="mp3")
266
+
267
+
268
+
269
+
270
+
CaesarMobileTranslate/__pycache__/caesarmobiletranslate.cpython-39.pyc ADDED
Binary file (1.1 kB). View file
 
CaesarMobileTranslate/caesarmobiletranslate.py ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #https://thepythoncode.com/article/translate-text-in-python?utm_content=cmp-true
2
+ from googletrans import Translator
3
+ from CaesarFolderInterface.caesarfolderinterface import CaesarFolderInterface
4
+ class CaesarMobileTranslate(CaesarFolderInterface):
5
+ def __init__(self):
6
+ super().__init__()
7
+ self.translator = Translator()
8
+ def translate(self,text,dest,verbose=0):
9
+ # translate a spanish text to english text (by default)
10
+ translation = self.translator.translate(text,dest=dest)
11
+ if verbose == 1:
12
+ print(f"{translation.origin} ({translation.src}) --> {translation.text} ({translation.dest})")
13
+ return translation.text,translation.dest,translation.origin,translation.src
14
+
15
+ if __name__ == "__main__":
16
+ caesarmobtrans = CaesarMobileTranslate()
17
+ caesarmobtrans.translate("Hola Mundo","fr")
CaesarSQLDB ADDED
@@ -0,0 +1 @@
 
 
1
+ Subproject commit 03f2a8eaeb36e2499f577322db716add29d81371
Dockerfile ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Use the official Python 3.9 image
2
+ FROM python:3.8
3
+
4
+ RUN export PYTHONPATH=$PWD
5
+
6
+ RUN apt-get -y update
7
+ RUN apt-get -y upgrade
8
+ RUN apt-get install -y ffmpeg
9
+ RUN pip install --upgrade pip
10
+ RUN pip install uvicorn
11
+ # Set the working directory to /code
12
+ WORKDIR /code
13
+ #VOLUME /home/amari/Desktop/CaesarAI/CaesarFastAPI /code
14
+ # Copy the current directory contents into the container at /code
15
+ COPY ./requirements.txt /code/requirements.txt
16
+
17
+ # Install requirements.txt
18
+ RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt
19
+ RUN python -m spacy download en_core_web_sm
20
+
21
+ # Set up a new user named "user" with user ID 1000
22
+ RUN useradd -m -u 1000 user
23
+ # Switch to the "user" user
24
+ USER user
25
+ # Set home to the user's home directory
26
+ ENV HOME=/home/user \
27
+ PATH=/home/user/.local/bin:$PATH
28
+
29
+ # Set the working directory to the user's home directory
30
+ WORKDIR $HOME/app
31
+
32
+ # Copy the current directory contents into the container at $HOME/app setting the owner to the user
33
+ COPY --chown=user . $HOME/app
34
+
35
+ # Local
36
+ #CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "7860","--reload"]
37
+ # Fly.io
38
+ CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8080","--reload"]
README.md ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ title: CaesarAITranscribeTL
3
+ emoji: 🏆
4
+ colorFrom: red
5
+ colorTo: gray
6
+ sdk: docker
7
+ pinned: false
8
+ ---
__pycache__/main.cpython-39.pyc ADDED
Binary file (5.38 kB). View file
 
caesarmobile.py ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from CaesarMobileTranscribe.caesartranscribe import CaesarMobileTranscribe
2
+ from CaesarMobileTranslate.caesarmobiletranslate import CaesarMobileTranslate
3
+ from CaesarMobileTTS.caesarmobiletts import CaesarMobileTTS
4
+ from CaesarFolderInterface.caesarfolderinterface import CaesarFolderInterface
5
+ from CaesarSQLDB.caesar_create_tables import CaesarCreateTables
6
+ from CaesarSQLDB.caesarcrud import CaesarCRUD
7
+ from CaesarSQLDB.caesarhash import CaesarHash
8
+ from pydub import AudioSegment
9
+ if __name__ == "__main__":
10
+ argfilename = "DIALOGUE" # "audio-sample-1" #
11
+ language = "fr"
12
+ caesarfolders = CaesarFolderInterface()
13
+ caesarmobtrb = CaesarMobileTranscribe()
14
+ caesarmobtrans = CaesarMobileTranslate()
15
+ caesarmobtts = CaesarMobileTTS()
16
+ caesarcrud = CaesarCRUD()
17
+ caesarcreatetables = CaesarCreateTables()
18
+ caesarcreatetables.create(caesarcrud)
19
+
20
+
21
+ fields = ("filename","src","dest","translationhash","original_transcript","translated_transcript","translated_audio_contents")
22
+ table = "translations"
23
+ hash_input = argfilename + language
24
+ translationhash = CaesarHash.hash_text(hash_input)
25
+ condition = f"translationhash = '{translationhash}'"
26
+ translation_exists = caesarcrud.check_exists(("*"),table,condition)
27
+ new = AudioSegment.empty()
28
+ new.export(f"{caesarfolders.audio_output_folder}/{argfilename}_start.mp3", format="mp3")
fly.toml ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # fly.toml app configuration file generated for caesarmobiletranslateapis on 2023-09-09T00:29:27+01:00
2
+ #
3
+ # See https://fly.io/docs/reference/configuration/ for information about how to use this file.
4
+ #
5
+
6
+ app = "caesarmobiletranslateapis"
7
+ primary_region = "ams"
8
+
9
+ [build]
10
+
11
+ [http_service]
12
+ internal_port = 8080
13
+ force_https = true
14
+ auto_stop_machines = true
15
+ auto_start_machines = true
16
+ min_machines_running = 0
17
+ processes = ["app"]
main.py ADDED
@@ -0,0 +1,158 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #https://thepythoncode.com/article/translate-text-in-python?utm_content=cmp-true
2
+ import asyncio
3
+ import uvicorn
4
+ from fastapi import FastAPI,UploadFile,Form,WebSocket,File
5
+ from fastapi.responses import FileResponse
6
+ from fastapi.middleware.cors import CORSMiddleware
7
+ from pydantic import BaseModel
8
+ from typing import Any, Dict, AnyStr, List, Union
9
+ import starlette
10
+ from CaesarMobileTranslate.caesarmobiletranslate import CaesarMobileTranslate
11
+ from CaesarFolderInterface.caesarfolderinterface import CaesarFolderInterface
12
+ from CaesarMobileTranscribe.caesartranscribe import CaesarMobileTranscribe
13
+ from CaesarMobileTTS.caesarmobiletts import CaesarMobileTTS
14
+ from CaesarSQLDB.caesar_create_tables import CaesarCreateTables
15
+ from CaesarSQLDB.caesarhash import CaesarHash
16
+ from pydub import AudioSegment
17
+ import os
18
+ app = FastAPI()
19
+ caesarfolders = CaesarFolderInterface()
20
+ caesarmobtrb = CaesarMobileTranscribe()
21
+
22
+
23
+ caesarcreatetables = CaesarCreateTables()
24
+ caesarmobtrb.create_all_dirs()
25
+
26
+ app.add_middleware(
27
+ CORSMiddleware,
28
+ allow_origins=["*"],
29
+ allow_credentials=True,
30
+ allow_methods=["*"],
31
+ allow_headers=["*"],
32
+ )
33
+ class CaesarMobileTranslateReq(BaseModel):
34
+ text:str
35
+ dest:str
36
+
37
+ JSONObject = Dict[AnyStr, Any]
38
+ JSONArray = List[Any]
39
+ JSONStructure = Union[JSONArray, JSONObject]
40
+ @app.get("/") # POST # allow all origins all methods.
41
+ async def home():
42
+ return "Hello world to Caesar Mobile Translate."
43
+ @app.post("/caesarmobiletranslate") # POST # allow all origins all methods.
44
+ async def caesarmobiletranslate(data : JSONStructure = None):
45
+ try:
46
+ data = dict(data)#request.get_json()
47
+ print(data)
48
+ translation,dest,original,src = caesarmobtrb.caesartrans.translate(data["text"],data["dest"])
49
+
50
+ return {"translation":translation,"dest":dest,"original":original,"src":src}
51
+ except Exception as ex:
52
+ return {"error":f"{type(ex)}-{ex}"}
53
+ @app.post("/caesarmobiletranslatestoreaudio")
54
+ async def caesarmobiletranslatestoreaudio(language: str = Form(...),file: UploadFile = File(...)):
55
+ # Increase Upload filesize: https://stackoverflow.com/questions/73442335/how-to-upload-a-large-file-%E2%89%A53gb-to-fastapi-backend
56
+ filename = file.filename
57
+ fileformat = filename.split(".")[1]
58
+ suffix = f"_{language}"
59
+ argfilename = filename.replace(".mp3","").replace(".wav","") + suffix
60
+ contents = await file.read()
61
+ fields = ("filename","src","dest","translationhash","original_transcript","translated_transcript","translated_audio_contents")
62
+ table = "translations"
63
+ hash_input = argfilename.replace(suffix,'') + language
64
+ translationhash = CaesarHash.hash_text(hash_input)
65
+ condition = f"translationhash = '{translationhash}'"
66
+ caesarfolders.clean_all()
67
+ if f"{argfilename}.wav" not in os.listdir(caesarmobtrb.audio_input_folder):
68
+ store_res = caesarmobtrb.store_audio(argfilename,contents,fileformat)
69
+ if store_res:
70
+ return {"message":"audio stored in active directory."}
71
+ else:
72
+ return {"error":"Error storing."}
73
+ else:
74
+ return {"message":"translation already exists in db."}
75
+
76
+ @app.websocket("/caesarmobiletranslateaudiows")
77
+ async def caesarmobiletranslateaudio(websocket: WebSocket):
78
+ try:
79
+ await websocket.accept()
80
+ while True:
81
+ data = await websocket.receive_json()
82
+ filename = data["filename"]
83
+ language = data["language"]
84
+ fileformat = "wav"
85
+
86
+
87
+ suffix = f"_{language}"
88
+ argfilename = filename + suffix
89
+ print(argfilename)
90
+
91
+ fields = ("filename","src","dest","translationhash","original_transcript","translated_transcript","translated_audio_contents")
92
+ table = "translations"
93
+ hash_input = argfilename.replace(suffix,'') + language
94
+ translationhash = CaesarHash.hash_text(hash_input)
95
+ condition = f"translationhash = '{translationhash}'"
96
+ ttsfilename = f"{caesarmobtrb.audio_output_folder}/{argfilename}.mp3"
97
+ if f"{argfilename}.mp3" not in os.listdir(caesarmobtrb.audio_output_folder):
98
+ contents = caesarmobtrb.load_audio(argfilename,fileformat,caesarmobtrb.audio_input_folder)
99
+ if contents:
100
+ new_sound = AudioSegment.empty()
101
+ original_text = ""
102
+ final_translation = ""
103
+ send_interval = 3
104
+ sliced_sections = caesarmobtrb .slice_sections(argfilename)
105
+ for i,new_sound,dsrc,text,translation in caesarmobtrb.run_api(argfilename,language,sliced_sections,new_sound):
106
+ original_text += f"{text}\n"
107
+ final_translation += f"{translation}\n"
108
+ new_sound.export(ttsfilename, format="mp3")
109
+ current_contents = caesarmobtrb.load_audio(argfilename,"mp3",caesarmobtrb.audio_output_folder)
110
+
111
+ await websocket.send_json({"progress":i,"total":len(sliced_sections),"send_audio_interval":send_interval})
112
+ if i % send_interval == 0:
113
+ await websocket.send_bytes(current_contents)
114
+
115
+ new_sound.export(ttsfilename, format="mp3")
116
+ final_contents = caesarmobtrb.load_audio(argfilename,"mp3",caesarmobtrb.audio_output_folder)
117
+ await websocket.send_bytes(final_contents)
118
+ # .encode('ascii')
119
+ original_text = original_text.replace("\n","<new_line>",100000)
120
+ original_text = original_text.encode('ascii',"ignore").decode()
121
+ original_text = original_text.replace("<new_line>","\n",100000)
122
+
123
+ final_translation = final_translation.replace("\n","<new_line>",100000)
124
+ final_translation = final_translation.encode('ascii',"ignore").decode()
125
+ final_translation = final_translation.replace("<new_line>","\n",100000)
126
+ await websocket.send_json({"original_text":original_text})
127
+ await websocket.send_json({"final_translation":final_translation})
128
+ print({"message":"All translation audio was sent."})
129
+
130
+ await websocket.send_json({"message":"All translation audio was sent."})
131
+
132
+
133
+
134
+ else:
135
+ await websocket.send_json({"error":"error loading file in active directory send request to caesarmobiletranslatestoreaudio."})
136
+ else:
137
+ try:
138
+ result = caesarmobtrb.load_audio(argfilename,"mp3",caesarmobtrb.audio_output_folder)
139
+ await websocket.send_bytes(result)
140
+ except Exception as ex:
141
+ await websocket.send_json({"error":"error getting file from active directory."})
142
+
143
+ except starlette.websockets.WebSocketDisconnect as wed:
144
+ if str(wed) == "1000":
145
+ caesarfolders.clean_all()
146
+ print("connected close handled.")
147
+ else:
148
+ print(type(wed),wed)
149
+
150
+
151
+
152
+ async def main():
153
+ config = uvicorn.Config("main:app", port=7860, log_level="info",host="0.0.0.0",reload=True) # Local
154
+ server = uvicorn.Server(config)
155
+ await server.serve()
156
+
157
+ if __name__ == "__main__":
158
+ asyncio.run(main())
main_db.py ADDED
@@ -0,0 +1,176 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #https://thepythoncode.com/article/translate-text-in-python?utm_content=cmp-true
2
+ import asyncio
3
+ import uvicorn
4
+ from fastapi import FastAPI,UploadFile,Form,WebSocket
5
+ from fastapi.responses import FileResponse
6
+ from fastapi.middleware.cors import CORSMiddleware
7
+ from pydantic import BaseModel
8
+ from typing import Any, Dict, AnyStr, List, Union
9
+ import starlette
10
+ from CaesarMobileTranslate.caesarmobiletranslate import CaesarMobileTranslate
11
+ from CaesarFolderInterface.caesarfolderinterface import CaesarFolderInterface
12
+ from CaesarMobileTranscribe.caesartranscribe import CaesarMobileTranscribe
13
+ from CaesarSQLDB.caesarcrud import CaesarCRUD
14
+ from CaesarMobileTTS.caesarmobiletts import CaesarMobileTTS
15
+ from CaesarSQLDB.caesar_create_tables import CaesarCreateTables
16
+ from CaesarSQLDB.caesarhash import CaesarHash
17
+ from pydub import AudioSegment
18
+ app = FastAPI()
19
+ caesarfolders = CaesarFolderInterface()
20
+ caesarmobtrb = CaesarMobileTranscribe()
21
+
22
+ caesarcrud = CaesarCRUD()
23
+ caesarcreatetables = CaesarCreateTables()
24
+ caesarcreatetables.create(caesarcrud)
25
+ caesarmobtrb.create_all_dirs()
26
+
27
+ app.add_middleware(
28
+ CORSMiddleware,
29
+ allow_origins=["*"],
30
+ allow_credentials=True,
31
+ allow_methods=["*"],
32
+ allow_headers=["*"],
33
+ )
34
+ class CaesarMobileTranslateReq(BaseModel):
35
+ text:str
36
+ dest:str
37
+
38
+ JSONObject = Dict[AnyStr, Any]
39
+ JSONArray = List[Any]
40
+ JSONStructure = Union[JSONArray, JSONObject]
41
+ @app.get("/") # POST # allow all origins all methods.
42
+ async def home():
43
+ return "Hello world to Caesar Mobile Translate."
44
+ @app.post("/caesarmobiletranslate") # POST # allow all origins all methods.
45
+ async def caesarmobiletranslate(data : JSONStructure = None):
46
+ try:
47
+ data = dict(data)#request.get_json()
48
+ print(data)
49
+ translation,dest,original,src = caesarmobtrb.caesartrans.translate(data["text"],data["dest"])
50
+
51
+ return {"translation":translation,"dest":dest,"original":original,"src":src}
52
+ except Exception as ex:
53
+ return {"error":f"{type(ex)}-{ex}"}
54
+ @app.post("/caesarmobiletranslatestoreaudio")
55
+ async def caesarmobiletranslatestoreaudio(file: UploadFile,language: str = Form()):
56
+ # Increase Upload filesize: https://stackoverflow.com/questions/73442335/how-to-upload-a-large-file-%E2%89%A53gb-to-fastapi-backend
57
+ filename = file.filename
58
+ fileformat = filename.split(".")[1]
59
+ suffix = f"_{language}"
60
+ argfilename = filename.replace(".mp3","").replace(".wav","") + suffix
61
+ contents = await file.read()
62
+ fields = ("filename","src","dest","translationhash","original_transcript","translated_transcript","translated_audio_contents")
63
+ table = "translations"
64
+ hash_input = argfilename.replace(suffix,'') + language
65
+ translationhash = CaesarHash.hash_text(hash_input)
66
+ condition = f"translationhash = '{translationhash}'"
67
+ translation_exists = caesarcrud.check_exists(("*"),table,condition)
68
+ caesarfolders.clean_all()
69
+ if not translation_exists:
70
+ store_res = caesarmobtrb.store_audio(argfilename,contents,fileformat)
71
+ if store_res:
72
+ return {"message":"audio stored in active directory."}
73
+ else:
74
+ return {"error":"Error storing."}
75
+ else:
76
+ return {"message":"translation already exists in db."}
77
+
78
+ @app.websocket("/caesarmobiletranslateaudiows")
79
+ async def caesarmobiletranslateaudio(websocket: WebSocket):
80
+ try:
81
+ await websocket.accept()
82
+ while True:
83
+ data = await websocket.receive_json()
84
+ filename = data["filename"]
85
+ language = data["language"]
86
+ fileformat = "wav"
87
+
88
+
89
+ suffix = f"_{language}"
90
+ argfilename = filename + suffix
91
+ print(argfilename)
92
+
93
+ fields = ("filename","src","dest","translationhash","original_transcript","translated_transcript","translated_audio_contents")
94
+ table = "translations"
95
+ hash_input = argfilename.replace(suffix,'') + language
96
+ translationhash = CaesarHash.hash_text(hash_input)
97
+ condition = f"translationhash = '{translationhash}'"
98
+ translation_exists = caesarcrud.check_exists(("*"),table,condition)
99
+ ttsfilename = f"{caesarmobtrb.audio_output_folder}/{argfilename}.mp3"
100
+ if not translation_exists:
101
+ contents = caesarmobtrb.load_audio(argfilename,fileformat,caesarmobtrb.audio_input_folder)
102
+ if contents:
103
+ new_sound = AudioSegment.empty()
104
+ original_text = ""
105
+ final_translation = ""
106
+ send_interval = 3
107
+ sliced_sections = caesarmobtrb .slice_sections(argfilename)
108
+ for i,new_sound,dsrc,text,translation in caesarmobtrb.run_api(argfilename,language,sliced_sections,new_sound):
109
+ original_text += f"{text}\n"
110
+ final_translation += f"{translation}\n"
111
+ new_sound.export(ttsfilename, format="mp3")
112
+ current_contents = caesarmobtrb.load_audio(argfilename,"mp3",caesarmobtrb.audio_output_folder)
113
+
114
+ await websocket.send_json({"progress":i,"total":len(sliced_sections),"send_audio_interval":send_interval})
115
+ if i % send_interval == 0:
116
+ await websocket.send_bytes(current_contents)
117
+
118
+ new_sound.export(ttsfilename, format="mp3")
119
+ final_contents = caesarmobtrb.load_audio(argfilename,"mp3",caesarmobtrb.audio_output_folder)
120
+ await websocket.send_bytes(final_contents)
121
+ # .encode('ascii')
122
+ original_text = original_text.replace("\n","<new_line>",100000)
123
+ original_text = original_text.encode('ascii',"ignore").decode()
124
+ original_text = original_text.replace("<new_line>","\n",100000)
125
+
126
+ final_translation = final_translation.replace("\n","<new_line>",100000)
127
+ final_translation = final_translation.encode('ascii',"ignore").decode()
128
+ final_translation = final_translation.replace("<new_line>","\n",100000)
129
+ await websocket.send_json({"original_text":original_text})
130
+ await websocket.send_json({"final_translation":final_translation})
131
+ print({"message":"All translation audio was sent."})
132
+
133
+ await websocket.send_json({"message":"All translation audio was sent."})
134
+
135
+ # Store db.
136
+ #print("src:",src)
137
+ #res = caesarcrud.post_data(fields,(f"{argfilename.replace(suffix,'')}.mp3",src,languag,translationhash,original_text,final_translation,contents),table)
138
+
139
+ #if res:
140
+ # await websocket.send_json({"message":"translation was stored."})
141
+ #else:
142
+ # await websocket.send_json({"error":"translation was stored."})
143
+
144
+
145
+ else:
146
+ await websocket.send_json({"error":"error loading file in active directory send request to caesarmobiletranslatestoreaudio."})
147
+ else:
148
+ res = caesarcrud.get_data(("filename","translated_audio_contents"),table,condition)
149
+ if res:
150
+ resjson = res[0]
151
+ store_result = caesarfolders.store_audio(argfilename,resjson["translated_audio_contents"])
152
+ if store_result:
153
+ await websocket.send_bytes(store_result)
154
+
155
+ else:
156
+ await websocket.send_json({"error":"error GET storing"})
157
+
158
+ else:
159
+ await websocket.send_json({"error":"error whilst getting data,"})
160
+
161
+ except starlette.websockets.WebSocketDisconnect as wed:
162
+ if str(wed) == "1000":
163
+ caesarfolders.clean_all()
164
+ print("connected close handled.")
165
+ else:
166
+ print(type(wed),wed)
167
+
168
+
169
+
170
+ async def main():
171
+ config = uvicorn.Config("main:app", port=7860, log_level="info",host="0.0.0.0",reload=True) # Local
172
+ server = uvicorn.Server(config)
173
+ await server.serve()
174
+
175
+ if __name__ == "__main__":
176
+ asyncio.run(main())
python_version ADDED
@@ -0,0 +1 @@
 
 
1
+ python=3.9
requirements.txt ADDED
@@ -0,0 +1,58 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ annotated-types==0.5.0
2
+ anyio==3.7.1
3
+ blis==0.7.10
4
+ catalogue==2.0.9
5
+ certifi==2023.7.22
6
+ cffi==1.15.1
7
+ chardet==3.0.4
8
+ charset-normalizer==3.2.0
9
+ click==8.1.7
10
+ confection==0.1.3
11
+ cymem==2.0.7
12
+ en-core-web-sm @ https://github.com/explosion/spacy-models/releases/download/en_core_web_sm-3.6.0/en_core_web_sm-3.6.0-py3-none-any.whl#sha256=83276fc78a70045627144786b52e1f2728ad5e29e5e43916ec37ea9c26a11212
13
+ exceptiongroup==1.1.3
14
+ fastapi==0.103.1
15
+ googletrans==3.1.0a0
16
+ gTTS==2.3.2
17
+ h11==0.9.0
18
+ h2==3.2.0
19
+ hpack==3.0.0
20
+ hstspreload==2023.1.1
21
+ httpcore==0.9.1
22
+ httpx==0.13.3
23
+ hyperframe==5.2.0
24
+ idna==2.10
25
+ Jinja2==3.1.2
26
+ langcodes==3.3.0
27
+ MarkupSafe==2.1.3
28
+ murmurhash==1.0.9
29
+ mysqlclient==2.2.0
30
+ numpy==1.24.4
31
+ packaging==23.1
32
+ pathy==0.10.2
33
+ preshed==3.0.8
34
+ pycparser==2.21
35
+ pydantic==2.3.0
36
+ pydantic_core==2.6.3
37
+ pydub==0.25.1
38
+ python-dotenv==1.0.0
39
+ python-multipart==0.0.6
40
+ requests==2.31.0
41
+ rfc3986==1.5.0
42
+ smart-open==6.4.0
43
+ sniffio==1.3.0
44
+ soundfile==0.12.1
45
+ spacy==3.6.1
46
+ spacy-legacy==3.0.12
47
+ spacy-loggers==1.0.4
48
+ SpeechRecognition==3.10.0
49
+ srsly==2.4.7
50
+ starlette==0.27.0
51
+ thinc==8.1.12
52
+ tqdm==4.66.1
53
+ typer==0.9.0
54
+ typing_extensions==4.7.1
55
+ urllib3==2.0.4
56
+ uvicorn==0.23.2
57
+ wasabi==1.1.2
58
+ websockets==11.0.3
requirements_win.txt ADDED
@@ -0,0 +1,90 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # python:3.9
2
+ fastapi
3
+ uvicorn
4
+ googletrans==3.1.0a0 # This version is IMPORTANT!!!
5
+ pydantic
6
+ altgraph==0.17.3
7
+ asttokens==2.0.8
8
+ backcall==0.2.0
9
+ blis==0.7.8
10
+ catalogue==2.0.8
11
+ certifi==2022.9.24
12
+ cffi==1.15.1
13
+ charset-normalizer==2.1.1
14
+ click==8.1.3
15
+ colorama==0.4.5
16
+ confection==0.0.3
17
+ contourpy==1.0.5
18
+ cycler==0.11.0
19
+ cymem==2.0.6
20
+ Cython==0.29.32
21
+ debugpy==1.6.3
22
+ decorator==5.1.1
23
+ en-core-web-sm @ https://github.com/explosion/spacy-models/releases/download/en_core_web_sm-3.4.0/en_core_web_sm-3.4.0-py3-none-any.whl
24
+ entrypoints==0.4
25
+ executing==1.1.1
26
+ ffmpeg==1.4
27
+ fonttools==4.37.4
28
+ future==0.18.2
29
+ idna # KEEP it like this!!!
30
+ ipykernel==6.16.0
31
+ ipython==8.5.0
32
+ jedi==0.18.1
33
+ Jinja2==3.1.2
34
+ joblib==1.2.0
35
+ jupyter_client==7.4.2
36
+ jupyter_core==4.11.2
37
+ kiwisolver==1.4.4
38
+ langcodes==3.3.0
39
+ MarkupSafe==2.1.1
40
+ matplotlib==3.6.1
41
+ matplotlib-inline==0.1.6
42
+ murmurhash==1.0.8
43
+ nest-asyncio==1.5.6
44
+ nltk==3.7
45
+ numpy==1.23.4
46
+ packaging==21.3
47
+ parso==0.8.3
48
+ pathy==0.6.2
49
+ pefile==2022.5.30
50
+ pickleshare==0.7.5
51
+ Pillow==9.2.0
52
+ preshed==3.0.7
53
+ prompt-toolkit==3.0.31
54
+ psutil==5.9.3
55
+ pure-eval==0.2.2
56
+ PyAudio==0.2.12
57
+ pycparser==2.21
58
+ pydantic==1.9.2
59
+ pydub==0.25.1
60
+ Pygments==2.13.0
61
+ pyinstaller==5.5
62
+ pyinstaller-hooks-contrib==2022.10
63
+ pyparsing==3.0.9
64
+ python-dateutil==2.8.2
65
+ pywin32==304
66
+ pywin32-ctypes==0.2.0
67
+ pyzmq==24.0.1
68
+ regex==2022.9.13
69
+ requests==2.28.1
70
+ scipy==1.9.2
71
+ six==1.16.0
72
+ smart-open==5.2.1
73
+ sounddevice==0.4.5
74
+ soundfile==0.11.0
75
+ spacy==3.4.1
76
+ spacy-legacy==3.0.10
77
+ spacy-loggers==1.0.3
78
+ SpeechRecognition==3.8.1
79
+ srsly==2.4.4
80
+ stack-data==0.5.1
81
+ thinc==8.1.4
82
+ tinyaes==1.0.3
83
+ tornado==6.2
84
+ tqdm==4.64.1
85
+ traitlets==5.5.0
86
+ typer==0.4.2
87
+ typing_extensions==4.4.0
88
+ urllib3==1.26.12
89
+ wasabi==0.10.1
90
+ wcwidth==0.2.5