Spaces:
Running
on
Zero
Running
on
Zero
Update app.py
Browse files
app.py
CHANGED
@@ -1,19 +1,22 @@
|
|
1 |
"""
|
2 |
-
SMARTok
|
3 |
-
|
4 |
-
|
5 |
-
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
|
|
|
10 |
"""
|
11 |
|
12 |
import gradio as gr
|
13 |
-
import openai, os, io, tempfile, mimetypes
|
14 |
from dotenv import load_dotenv
|
|
|
|
|
15 |
|
16 |
-
#
|
17 |
load_dotenv()
|
18 |
api_key = os.getenv("OPENAI_API_KEY")
|
19 |
if not api_key:
|
@@ -32,234 +35,169 @@ LANG_CODE = {
|
|
32 |
}
|
33 |
VOICE = {l: ("nova" if l in ["Korean","Japanese","Chinese"] else "alloy")
|
34 |
for l in LANGUAGES}
|
|
|
|
|
35 |
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
# โโโโโโโโโโโโโโโโโโโ 1. ์ ํธ ํจ์ โโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
40 |
-
def _safe_path(v):
|
41 |
-
"""Gradio File/Audio ์
๋ ฅ โ ์ค์ ๊ฒฝ๋ก ์ถ์ถ"""
|
42 |
if v is None:
|
43 |
return None
|
44 |
-
return v
|
45 |
|
46 |
-
def
|
47 |
-
"""GPT-3.5-turbo ๋ฒ์ญ (์ค๋ช
์์ด ๊ฒฐ๊ณผ๋ง)"""
|
48 |
rsp = client.chat.completions.create(
|
49 |
model="gpt-3.5-turbo",
|
50 |
messages=[
|
51 |
{"role":"system",
|
52 |
-
"content":f"
|
53 |
-
|
54 |
{"role":"user","content":text}
|
55 |
],
|
56 |
temperature=0.3,max_tokens=4096
|
57 |
)
|
58 |
return rsp.choices[0].message.content.strip()
|
59 |
|
60 |
-
def _tts(text
|
61 |
-
|
62 |
-
out = client.audio.speech.create(
|
63 |
model="tts-1",
|
64 |
voice=VOICE.get(lang,"alloy"),
|
65 |
input=text[:4096]
|
66 |
)
|
67 |
-
tmp = tempfile.NamedTemporaryFile(delete=False,
|
68 |
-
tmp.write(
|
69 |
-
tmp.close()
|
70 |
return tmp.name
|
71 |
|
72 |
-
#
|
73 |
def translate_audio(audio_in, src, tgt):
|
74 |
-
|
75 |
-
if not
|
76 |
-
return "โ ๏ธ ์์ฑ
|
77 |
-
|
78 |
-
with open(path,"rb") as f:
|
79 |
stt = client.audio.transcriptions.create(
|
80 |
-
model="whisper-1",
|
81 |
-
|
82 |
-
|
83 |
-
)
|
84 |
-
original = stt.text.strip()
|
85 |
-
if not original:
|
86 |
return "โ ๏ธ ์์ฑ ์ธ์ ์คํจ", "", None
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
ext = os.path.splitext(path)[1].lower()
|
99 |
-
mime = mimetypes.guess_type(path)[0] or ""
|
100 |
-
text = ""
|
101 |
-
|
102 |
try:
|
103 |
-
|
104 |
-
|
105 |
-
with pdfplumber.open(
|
106 |
-
|
107 |
-
|
108 |
else:
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
|
|
116 |
except Exception as e:
|
117 |
-
return f"โ
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
chunk = mic_stream.recv()
|
161 |
-
if chunk is None:
|
162 |
-
break
|
163 |
-
if header is None:
|
164 |
-
header = chunk[:44]
|
165 |
-
buf.write(chunk)
|
166 |
-
if buf.getbuffer().nbytes > 16000*2*STREAM_SEC:
|
167 |
-
wav = header + buf.getvalue()
|
168 |
-
with tempfile.NamedTemporaryFile(delete=False,suffix=".wav") as tmp:
|
169 |
-
tmp.write(wav); tmp.close()
|
170 |
-
with open(tmp.name,"rb") as f:
|
171 |
-
stt = client.audio.transcriptions.create(
|
172 |
-
model="whisper-1", file=f,
|
173 |
-
language=LANG_CODE.get(src)
|
174 |
-
)
|
175 |
-
orig = stt.text.strip()
|
176 |
-
if orig:
|
177 |
-
acc["orig"] += " " + orig
|
178 |
-
for lang in FOUR_LANGS:
|
179 |
-
acc[lang] += " " + _gpt_translate(orig, src, lang)
|
180 |
-
yield (acc["orig"].strip(),
|
181 |
-
acc["English"].strip(),
|
182 |
-
acc["Chinese"].strip(),
|
183 |
-
acc["Thai"].strip(),
|
184 |
-
acc["Russian"].strip())
|
185 |
-
buf = io.BytesIO()
|
186 |
-
|
187 |
-
if buf.getbuffer().nbytes:
|
188 |
-
wav = header + buf.getvalue()
|
189 |
-
with tempfile.NamedTemporaryFile(delete=False,suffix=".wav") as tmp:
|
190 |
-
tmp.write(wav); tmp.close()
|
191 |
-
with open(tmp.name,"rb") as f:
|
192 |
-
stt = client.audio.transcriptions.create(
|
193 |
-
model="whisper-1", file=f,
|
194 |
-
language=LANG_CODE.get(src)
|
195 |
-
)
|
196 |
-
orig = stt.text.strip()
|
197 |
-
if orig:
|
198 |
-
acc["orig"] += " " + orig
|
199 |
-
for lang in FOUR_LANGS:
|
200 |
-
acc[lang] += " " + _gpt_translate(orig, src, lang)
|
201 |
-
yield (acc["orig"].strip(),
|
202 |
-
acc["English"].strip(),
|
203 |
-
acc["Chinese"].strip(),
|
204 |
-
acc["Thai"].strip(),
|
205 |
-
acc["Russian"].strip())
|
206 |
-
|
207 |
-
# โโโโโโโโโโโโโโโโโโโ 6. Gradio UI โโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
208 |
with gr.Blocks(title="SMARTok Demo", theme=gr.themes.Soft()) as app:
|
209 |
with gr.Tabs():
|
210 |
-
# ํญ 1
|
211 |
with gr.TabItem("๐๏ธ ์ค๋์ค ๋ฒ์ญ"):
|
212 |
-
src1 = gr.Dropdown(LANGUAGES,value="Korean",label="์
๋ ฅ")
|
213 |
-
tgt1 = gr.Dropdown(LANGUAGES,value="English",label="์ถ๋ ฅ")
|
214 |
-
aud1 = gr.Audio(sources=["microphone","upload"],
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
|
233 |
-
|
234 |
-
# ํญ 3 โ ์ค์๊ฐ 1์ธ์ด ๋ฒ์ญ
|
235 |
with gr.TabItem("โฑ๏ธ ์ค์๊ฐ 1์ธ์ด"):
|
236 |
-
src3 = gr.Dropdown(LANGUAGES,value="Korean",label="์
๋ ฅ")
|
237 |
-
tgt3 = gr.Dropdown(LANGUAGES,value="English",label="์ถ๋ ฅ")
|
238 |
-
mic3 = gr.Audio(sources=["microphone"],
|
239 |
-
|
240 |
-
|
241 |
-
|
242 |
-
|
243 |
-
|
244 |
-
|
245 |
-
|
|
|
246 |
with gr.TabItem("๐ ์ค์๊ฐ 4๊ฐ ์ธ์ด"):
|
247 |
-
gr.Markdown("๋ง์ดํฌ ์
๋ ฅ์ 3-4 ์ด ๊ฐ๊ฒฉ์ผ๋ก **English / Chinese(็ฎไฝ) / Thai / Russian** 4๊ฐ ์ธ์ด๋ก ๋์ ๋ฒ์ญํฉ๋๋ค.")
|
248 |
src4 = gr.Dropdown(LANGUAGES,value="Korean",label="์
๋ ฅ ์ธ์ด")
|
249 |
-
mic4 = gr.Audio(sources=["microphone"],
|
250 |
-
|
251 |
-
|
252 |
-
|
253 |
-
|
254 |
-
|
255 |
-
|
256 |
-
|
257 |
-
|
258 |
-
outputs=[o4,e4,
|
259 |
-
|
260 |
-
#
|
261 |
if __name__ == "__main__":
|
262 |
-
app.launch(server_name="0.0.0.0",
|
263 |
-
server_port=7860,
|
264 |
-
share=False,
|
265 |
-
debug=True)
|
|
|
1 |
"""
|
2 |
+
SMARTok ์ค์๊ฐ ๋ค๊ตญ์ด ๋ฐ๋ชจ (์์ ์์ ๋ณธ)
|
3 |
+
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
4 |
+
โข ํญ1 ๐๏ธ ์ค๋์ค ๋ฒ์ญ : ๋ง์ดํฌ/ํ์ผ โ ๋ฒ์ญ + TTS
|
5 |
+
โข ํญ2 ๐ ๋ฌธ์ยท์ด๋ฏธ์ง ๋ฒ์ญ : PDF / ์ด๋ฏธ์ง(OCR) โ ๋ฒ์ญ
|
6 |
+
โข ํญ3 โฑ๏ธ ์ค์๊ฐ 1์ธ์ด ๋ฒ์ญ : ๋ง์ดํฌ โ 1๊ฐ ์ธ์ด ์ค์๊ฐ ์๋ง
|
7 |
+
โข ํญ4 ๐ ์ค์๊ฐ 4๊ฐ ์ธ์ด ๋ฒ์ญ : ๋ง์ดํฌ โ ์ยท์คยทํยท๋ฌ ๋์ ์๋ง
|
8 |
+
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
9 |
+
ํ์ apt : tesseract-ocr libtesseract-dev ocrmypdf ffmpeg
|
10 |
+
ํ์ pip : gradio>=5.33 openai python-dotenv pdfplumber ocrmypdf pillow
|
11 |
"""
|
12 |
|
13 |
import gradio as gr
|
14 |
+
import openai, os, io, tempfile, mimetypes, json, uuid
|
15 |
from dotenv import load_dotenv
|
16 |
+
import pdfplumber, ocrmypdf
|
17 |
+
from PIL import Image
|
18 |
|
19 |
+
# โโโโโโโโโโโโโโ 0. ๊ณตํต ์ด๊ธฐํ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
20 |
load_dotenv()
|
21 |
api_key = os.getenv("OPENAI_API_KEY")
|
22 |
if not api_key:
|
|
|
35 |
}
|
36 |
VOICE = {l: ("nova" if l in ["Korean","Japanese","Chinese"] else "alloy")
|
37 |
for l in LANGUAGES}
|
38 |
+
FOUR = ["English","Chinese","Thai","Russian"]
|
39 |
+
STREAM_SEC = 4 # Whisper ํธ์ถ ์ฃผ๊ธฐ
|
40 |
|
41 |
+
# โโโโโโโโโโโโโโ 1. ์ ํธ ํจ์ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
42 |
+
def _safe(v):
|
|
|
|
|
|
|
|
|
43 |
if v is None:
|
44 |
return None
|
45 |
+
return v["name"] if isinstance(v, dict) else v
|
46 |
|
47 |
+
def _gpt(text, src, tgt):
|
|
|
48 |
rsp = client.chat.completions.create(
|
49 |
model="gpt-3.5-turbo",
|
50 |
messages=[
|
51 |
{"role":"system",
|
52 |
+
"content":f"Translate the following {src} text to {tgt}. "
|
53 |
+
"Return only the translation."},
|
54 |
{"role":"user","content":text}
|
55 |
],
|
56 |
temperature=0.3,max_tokens=4096
|
57 |
)
|
58 |
return rsp.choices[0].message.content.strip()
|
59 |
|
60 |
+
def _tts(text, lang):
|
61 |
+
rsp = client.audio.speech.create(
|
|
|
62 |
model="tts-1",
|
63 |
voice=VOICE.get(lang,"alloy"),
|
64 |
input=text[:4096]
|
65 |
)
|
66 |
+
tmp = tempfile.NamedTemporaryFile(delete=False,suffix=".mp3")
|
67 |
+
tmp.write(rsp.content); tmp.close()
|
|
|
68 |
return tmp.name
|
69 |
|
70 |
+
# โโโโโโโโโโโโโโ 2. ์ค๋์ค(๋จ๊ฑด) ๋ฒ์ญ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
71 |
def translate_audio(audio_in, src, tgt):
|
72 |
+
p = _safe(audio_in)
|
73 |
+
if not p or not os.path.exists(p):
|
74 |
+
return "โ ๏ธ ์์ฑ ํ์ผ ํ์", "", None
|
75 |
+
with open(p,"rb") as f:
|
|
|
76 |
stt = client.audio.transcriptions.create(
|
77 |
+
model="whisper-1", file=f, language=LANG_CODE.get(src))
|
78 |
+
orig = stt.text.strip()
|
79 |
+
if not orig:
|
|
|
|
|
|
|
80 |
return "โ ๏ธ ์์ฑ ์ธ์ ์คํจ", "", None
|
81 |
+
trans = _gpt(orig, src, tgt)
|
82 |
+
return orig, trans, _tts(trans, tgt)
|
83 |
+
|
84 |
+
# โโโโโโโโโโโโโโ 3. ๋ฌธ์ / ์ด๋ฏธ์ง ๋ฒ์ญ โโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
85 |
+
def translate_doc(file_in, src, tgt):
|
86 |
+
p = _safe(file_in)
|
87 |
+
if not p or not os.path.exists(p):
|
88 |
+
return "โ ๏ธ PDF/์ด๋ฏธ์ง ์
๋ก๋", ""
|
89 |
+
ext = os.path.splitext(p)[1].lower()
|
90 |
+
mime = mimetypes.guess_type(p)[0] or ""
|
|
|
|
|
|
|
|
|
|
|
91 |
try:
|
92 |
+
# PDF ๊ทธ๋๋ก
|
93 |
+
if ext==".pdf" or "pdf" in mime:
|
94 |
+
with pdfplumber.open(p) as pdf:
|
95 |
+
txt = "\n".join(pg.extract_text() or "" for pg in pdf.pages[:5])
|
96 |
+
# ์ด๋ฏธ์ง โ OCR PDF
|
97 |
else:
|
98 |
+
img_pdf = tempfile.NamedTemporaryFile(delete=False,suffix=".pdf").name
|
99 |
+
Image.open(p).save(img_pdf,"PDF")
|
100 |
+
ocr_pdf = tempfile.NamedTemporaryFile(delete=False,suffix=".pdf").name
|
101 |
+
ocrmypdf.ocr(img_pdf, ocr_pdf,
|
102 |
+
lang=LANG_CODE.get(src,"eng"),
|
103 |
+
deskew=True,optimize=0,progress_bar=False)
|
104 |
+
with pdfplumber.open(ocr_pdf) as pdf:
|
105 |
+
txt = "\n".join(pg.extract_text() or "" for pg in pdf.pages)
|
106 |
except Exception as e:
|
107 |
+
return f"โ ์ถ์ถ ์ค๋ฅ: {e}", ""
|
108 |
+
txt = txt.strip()
|
109 |
+
if not txt:
|
110 |
+
return "โ ๏ธ ํ
์คํธ ์ถ์ถ ์คํจ", ""
|
111 |
+
return txt, _gpt(txt, src, tgt)
|
112 |
+
|
113 |
+
# โโโโโโโโโโโโโโ 4. ์ค์๊ฐ 1์ธ์ด โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
114 |
+
def stream_single(audio_path, src, tgt, state):
|
115 |
+
state = state or {"orig":"", "trans":""}
|
116 |
+
if not audio_path or not os.path.exists(audio_path):
|
117 |
+
return state["orig"], state["trans"], state
|
118 |
+
with open(audio_path,"rb") as f:
|
119 |
+
stt = client.audio.transcriptions.create(
|
120 |
+
model="whisper-1", file=f, language=LANG_CODE.get(src))
|
121 |
+
full = stt.text.strip()
|
122 |
+
new = full[len(state["orig"]):]
|
123 |
+
if new:
|
124 |
+
state["orig"] = full
|
125 |
+
state["trans"] += " " + _gpt(new, src, tgt)
|
126 |
+
return state["orig"], state["trans"].strip(), state
|
127 |
+
|
128 |
+
# โโโโโโโโโโโโโโ 5. ์ค์๊ฐ 4์ธ์ด โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
129 |
+
def stream_multi(audio_path, src, state):
|
130 |
+
state = state or {k:"" for k in ["orig"]+FOUR}
|
131 |
+
if not audio_path or not os.path.exists(audio_path):
|
132 |
+
return state["orig"],state["English"],state["Chinese"],state["Thai"],state["Russian"],state
|
133 |
+
with open(audio_path,"rb") as f:
|
134 |
+
stt = client.audio.transcriptions.create(
|
135 |
+
model="whisper-1", file=f, language=LANG_CODE.get(src))
|
136 |
+
full = stt.text.strip()
|
137 |
+
new = full[len(state["orig"]):]
|
138 |
+
if new:
|
139 |
+
state["orig"] = full
|
140 |
+
for lang in FOUR:
|
141 |
+
state[lang] += " " + _gpt(new, src, lang)
|
142 |
+
return (state["orig"].strip(),
|
143 |
+
state["English"].strip(),
|
144 |
+
state["Chinese"].strip(),
|
145 |
+
state["Thai"].strip(),
|
146 |
+
state["Russian"].strip(),
|
147 |
+
state)
|
148 |
+
|
149 |
+
# โโโโโโโโโโโโโโ 6. Gradio UI โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
150 |
with gr.Blocks(title="SMARTok Demo", theme=gr.themes.Soft()) as app:
|
151 |
with gr.Tabs():
|
152 |
+
# ํญ 1
|
153 |
with gr.TabItem("๐๏ธ ์ค๋์ค ๋ฒ์ญ"):
|
154 |
+
src1 = gr.Dropdown(LANGUAGES,value="Korean",label="์
๋ ฅ ์ธ์ด")
|
155 |
+
tgt1 = gr.Dropdown(LANGUAGES,value="English",label="์ถ๋ ฅ ์ธ์ด")
|
156 |
+
aud1 = gr.Audio(sources=["microphone","upload"],type="filepath")
|
157 |
+
res1 = gr.Button("๋ฒ์ญ")
|
158 |
+
o1 = gr.Textbox(label="์๋ฌธ",lines=5)
|
159 |
+
t1 = gr.Textbox(label="๋ฒ์ญ",lines=5)
|
160 |
+
a1 = gr.Audio(label="TTS",type="filepath",autoplay=True)
|
161 |
+
res1.click(translate_audio,[aud1,src1,tgt1],[o1,t1,a1])
|
162 |
+
|
163 |
+
# ํญ 2
|
164 |
+
with gr.TabItem("๐ ๋ฌธ์ยท์ด๋ฏธ์ง ๋ฒ์ญ"):
|
165 |
+
src2 = gr.Dropdown(LANGUAGES,value="Korean",label="์
๋ ฅ ์ธ์ด")
|
166 |
+
tgt2 = gr.Dropdown(LANGUAGES,value="English",label="์ถ๋ ฅ ์ธ์ด")
|
167 |
+
file2= gr.File(label="PDF/์ด๋ฏธ์ง ์
๋ก๋",
|
168 |
+
file_types=[".pdf",".png",".jpg",".jpeg",
|
169 |
+
".bmp",".tiff",".gif"])
|
170 |
+
doc2 = gr.Button("๋ฒ์ญ")
|
171 |
+
o2 = gr.Textbox(label="์ถ์ถ ์๋ฌธ",lines=15)
|
172 |
+
t2 = gr.Textbox(label="๋ฒ์ญ ๊ฒฐ๊ณผ",lines=15)
|
173 |
+
doc2.click(translate_doc,[file2,src2,tgt2],[o2,t2])
|
174 |
+
|
175 |
+
# ํญ 3
|
|
|
176 |
with gr.TabItem("โฑ๏ธ ์ค์๊ฐ 1์ธ์ด"):
|
177 |
+
src3 = gr.Dropdown(LANGUAGES,value="Korean",label="์
๋ ฅ ์ธ์ด")
|
178 |
+
tgt3 = gr.Dropdown(LANGUAGES,value="English",label="์ถ๋ ฅ ์ธ์ด")
|
179 |
+
mic3 = gr.Audio(sources=["microphone"],streaming=True)
|
180 |
+
o3 = gr.Textbox(label="์๋ฌธ(์ค์๊ฐ)",lines=8)
|
181 |
+
t3 = gr.Textbox(label="๋ฒ์ญ(์ค์๊ฐ)",lines=8)
|
182 |
+
st3 = gr.State()
|
183 |
+
mic3.stream(stream_single,
|
184 |
+
inputs=[src3,tgt3,st3],
|
185 |
+
outputs=[o3,t3,st3])
|
186 |
+
|
187 |
+
# ํญ 4
|
188 |
with gr.TabItem("๐ ์ค์๊ฐ 4๊ฐ ์ธ์ด"):
|
|
|
189 |
src4 = gr.Dropdown(LANGUAGES,value="Korean",label="์
๋ ฅ ์ธ์ด")
|
190 |
+
mic4 = gr.Audio(sources=["microphone"],streaming=True)
|
191 |
+
o4 = gr.Textbox(label="์๋ฌธ",lines=8)
|
192 |
+
e4 = gr.Textbox(label="English",lines=8)
|
193 |
+
c4 = gr.Textbox(label="Chinese(็ฎไฝ)",lines=8)
|
194 |
+
th4 = gr.Textbox(label="Thai",lines=8)
|
195 |
+
r4 = gr.Textbox(label="Russian",lines=8)
|
196 |
+
st4 = gr.State()
|
197 |
+
mic4.stream(stream_multi,
|
198 |
+
inputs=[src4,st4],
|
199 |
+
outputs=[o4,e4,c4,th4,r4,st4])
|
200 |
+
|
201 |
+
# โโโโโโโโโโโโโโ 7. ์คํ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
202 |
if __name__ == "__main__":
|
203 |
+
app.launch(server_name="0.0.0.0",server_port=7860,share=False,debug=True)
|
|
|
|
|
|