CassianK's picture
Update app.py
455146e verified
# app.py β€” DeepSeek-OCR (HF Space, Gradio only, recursive finder)
import io, os, sys, base64, importlib.util, tempfile, traceback
from typing import Optional, List
from PIL import Image
import numpy as np
import gradio as gr
ROOT = os.path.dirname(__file__)
TARGET_FILENAMES = [
"deepseek_ocr.py", # ν•¨μˆ˜ν˜•/ν΄λž˜μŠ€ν˜•
"run_dpsk_ocr_image.py", # CLI μŠ€νƒ€μΌ
"run_dpsk_ocr.py", # HF μ „μš© 슀크립트
]
def find_candidates(root: str) -> List[str]:
"""ν”„λ‘œμ νŠΈ 전체λ₯Ό μž¬κ·€μ μœΌλ‘œ λ’€μ Έ νƒ€κ²Ÿ 파일 κ²½λ‘œλ“€μ„ λͺ¨λ‘ μˆ˜μ§‘"""
hits = []
for dirpath, dirnames, filenames in os.walk(root):
for fn in filenames:
if fn in TARGET_FILENAMES:
hits.append(os.path.join(dirpath, fn))
return sorted(hits)
def load_module_from_path(path: str):
name = os.path.splitext(os.path.basename(path))[0]
spec = importlib.util.spec_from_file_location(name, path)
if not spec or not spec.loader:
raise ImportError(f"Cannot load module from {path}")
mod = importlib.util.module_from_spec(spec)
sys.modules[name] = mod
spec.loader.exec_module(mod)
return mod
class OCRAdapter:
def __init__(self):
self.mode = "demo"
self.path = None
self.debug = []
self.entry = lambda img, lang="auto": "[DEMO] DeepSeek μ½”λ“œ μ—°κ²° μ „μž…λ‹ˆλ‹€."
hits = find_candidates(ROOT)
self.debug.append(f"ROOT={ROOT}")
self.debug.append("FOUND=" + ("; ".join(hits) if hits else "(none)"))
for path in hits:
try:
mod = load_module_from_path(path)
# 1) ν•¨μˆ˜ν˜•: ocr_image(image, lang="auto")
if hasattr(mod, "ocr_image"):
self.entry = lambda img, lang="auto", _m=mod: _m.ocr_image(img, lang=lang)
self.mode, self.path = "func_ocr_image", path
self.debug.append(f"USE {path} :: ocr_image")
return
# 2) ν΄λž˜μŠ€ν˜•: DeepSeekOCR().recognize(image, lang)
if hasattr(mod, "DeepSeekOCR"):
inst = mod.DeepSeekOCR()
if hasattr(inst, "recognize"):
self.entry = lambda img, lang="auto", _i=inst: _i.recognize(img, lang=lang)
self.mode, self.path = "class_recognize", path
self.debug.append(f"USE {path} :: DeepSeekOCR.recognize")
return
# 3) μŠ€ν¬λ¦½νŠΈν˜•: run / infer / main (파일경둜 μš”κ΅¬ κ°€λŠ₯)
for cand in ("run", "infer", "main", "predict"):
if hasattr(mod, cand):
fn = getattr(mod, cand)
def _call(img, lang="auto", _fn=fn):
with tempfile.NamedTemporaryFile(suffix=".png", delete=True) as tmp:
img.save(tmp.name)
try:
return str(_fn(tmp.name))
except TypeError:
return str(_fn(tmp.name, lang=lang))
self.entry = _call
self.mode, self.path = f"script_{cand}", path
self.debug.append(f"USE {path} :: {cand}(path)")
return
self.debug.append(f"NO ENTRY in {path}")
except Exception as e:
self.debug.append(f"LOAD FAIL {path} :: {e}")
def recognize(self, image: Image.Image, lang="auto") -> str:
return self.entry(image.convert("RGB"), lang)
ADAPTER = OCRAdapter()
def _to_pil(x) -> Image.Image:
if isinstance(x, Image.Image): return x.convert("RGB")
if isinstance(x, (bytes, bytearray)): return Image.open(io.BytesIO(x)).convert("RGB")
if isinstance(x, np.ndarray): return Image.fromarray(x).convert("RGB")
raise TypeError("Unsupported image type")
def _b64_to_image(image_b64: str) -> Image.Image:
return _to_pil(base64.b64decode(image_b64))
def gradio_predict(image, lang):
if image is None: return "No image provided."
try:
return ADAPTER.recognize(_to_pil(image), lang)
except Exception as e:
return f"[ERROR] {e}\n" + traceback.format_exc()
with gr.Blocks(title="DeepSeek-OCR (HF Space, Gradio)") as demo:
gr.Markdown(
"### DeepSeek-OCR (HF Space, Gradio)\n"
f"**ν˜„μž¬ λͺ¨λ“œ:** `{ADAPTER.mode}` \n"
f"**경둜:** `{ADAPTER.path}` \n"
f"**찾은 후보:** \n```\n" + "\n".join(ADAPTER.debug) + "\n```"
)
with gr.Row():
img = gr.Image(type="pil", label="Input Image")
out = gr.Textbox(label="OCR Result", lines=10)
lang = gr.Radio(["auto","en","ko","ja","zh"], value="auto", label="Language")
btn = gr.Button("Run OCR")
btn.click(gradio_predict, inputs=[img, lang], outputs=[out])
demo.launch()