Spaces:
Runtime error
Runtime error
Update app.py
Browse files
app.py
CHANGED
|
@@ -20,15 +20,15 @@ from pipelines.utils import detect_filetype, load_doc_text
|
|
| 20 |
APP_TITLE = "候補者インテーク & レジュメ標準化(OpenAI版)"
|
| 21 |
|
| 22 |
|
| 23 |
-
def process_resumes(
|
| 24 |
-
if not
|
| 25 |
raise gr.Error("少なくとも1ファイルをアップロードしてください。")
|
| 26 |
|
| 27 |
partial_records = []
|
| 28 |
raw_texts = []
|
| 29 |
|
| 30 |
-
# gr.Files(type="filepath")
|
| 31 |
-
for path in
|
| 32 |
filepath = str(path)
|
| 33 |
filename = os.path.basename(filepath)
|
| 34 |
with open(filepath, "rb") as fp:
|
|
@@ -72,7 +72,7 @@ def process_resumes(files, candidate_id: str, additional_notes: str = ""):
|
|
| 72 |
"skills": ", ".join(merged.get("skills", [])),
|
| 73 |
})
|
| 74 |
|
| 75 |
-
# 5) 匿名化
|
| 76 |
anonymized_text, anon_map = anonymize_text(merged_text)
|
| 77 |
anon_pdf_bytes = render_anonymized_pdf(anonymized_text)
|
| 78 |
|
|
@@ -85,7 +85,7 @@ def process_resumes(files, candidate_id: str, additional_notes: str = ""):
|
|
| 85 |
# 8) 構造化出力
|
| 86 |
result_json = {
|
| 87 |
"candidate_id": candidate_id or hashlib.sha256(merged_text.encode("utf-8")).hexdigest()[:16],
|
| 88 |
-
"files": [os.path.basename(p) for p in
|
| 89 |
"merged": merged,
|
| 90 |
"skills": skills,
|
| 91 |
"quality_score": score,
|
|
@@ -110,7 +110,7 @@ def process_resumes(files, candidate_id: str, additional_notes: str = ""):
|
|
| 110 |
|
| 111 |
anon_pdf = (result_json["candidate_id"] + ".anon.pdf", anon_pdf_bytes)
|
| 112 |
|
| 113 |
-
# gr.Code
|
| 114 |
return (
|
| 115 |
json.dumps(result_json, ensure_ascii=False, indent=2),
|
| 116 |
json.dumps(skills, ensure_ascii=False, indent=2),
|
|
@@ -131,7 +131,7 @@ with gr.Blocks(title=APP_TITLE) as demo:
|
|
| 131 |
label="レジュメ類 (PDF/画像/Word/テキスト) 複数可",
|
| 132 |
file_count="multiple",
|
| 133 |
file_types=[".pdf", ".png", ".jpg", ".jpeg", ".tiff", ".bmp", ".docx", ".txt"],
|
| 134 |
-
type="filepath",
|
| 135 |
)
|
| 136 |
candidate_id = gr.Textbox(label="候補者ID(任意。未入力なら自動生成)")
|
| 137 |
notes = gr.Textbox(label="補足メモ(任意)", lines=3)
|
|
@@ -142,7 +142,7 @@ with gr.Blocks(title=APP_TITLE) as demo:
|
|
| 142 |
out_json = gr.Code(label="統合出力 (JSON)")
|
| 143 |
|
| 144 |
with gr.Tab("抽出スキル"):
|
| 145 |
-
out_skills = gr.Code(label="スキル一覧 (JSON)") #
|
| 146 |
|
| 147 |
with gr.Tab("品質スコア"):
|
| 148 |
out_score = gr.Code(label="品質評価")
|
|
@@ -166,5 +166,5 @@ with gr.Blocks(title=APP_TITLE) as demo:
|
|
| 166 |
|
| 167 |
|
| 168 |
if __name__ == "__main__":
|
| 169 |
-
# HF Spaces
|
| 170 |
-
demo.launch()
|
|
|
|
| 20 |
APP_TITLE = "候補者インテーク & レジュメ標準化(OpenAI版)"
|
| 21 |
|
| 22 |
|
| 23 |
+
def process_resumes(filepaths, candidate_id: str, additional_notes: str = ""):
|
| 24 |
+
if not filepaths:
|
| 25 |
raise gr.Error("少なくとも1ファイルをアップロードしてください。")
|
| 26 |
|
| 27 |
partial_records = []
|
| 28 |
raw_texts = []
|
| 29 |
|
| 30 |
+
# ⚠️ gr.Files(type="filepath") のため、ここは「パス文字列」の配列
|
| 31 |
+
for path in filepaths:
|
| 32 |
filepath = str(path)
|
| 33 |
filename = os.path.basename(filepath)
|
| 34 |
with open(filepath, "rb") as fp:
|
|
|
|
| 72 |
"skills": ", ".join(merged.get("skills", [])),
|
| 73 |
})
|
| 74 |
|
| 75 |
+
# 5) 匿名化 → PDF化
|
| 76 |
anonymized_text, anon_map = anonymize_text(merged_text)
|
| 77 |
anon_pdf_bytes = render_anonymized_pdf(anonymized_text)
|
| 78 |
|
|
|
|
| 85 |
# 8) 構造化出力
|
| 86 |
result_json = {
|
| 87 |
"candidate_id": candidate_id or hashlib.sha256(merged_text.encode("utf-8")).hexdigest()[:16],
|
| 88 |
+
"files": [os.path.basename(p) for p in filepaths],
|
| 89 |
"merged": merged,
|
| 90 |
"skills": skills,
|
| 91 |
"quality_score": score,
|
|
|
|
| 110 |
|
| 111 |
anon_pdf = (result_json["candidate_id"] + ".anon.pdf", anon_pdf_bytes)
|
| 112 |
|
| 113 |
+
# ← GradioのAPIスキーマ生成バグ回避のため、JSONは文字列で返す(gr.Codeに表示)
|
| 114 |
return (
|
| 115 |
json.dumps(result_json, ensure_ascii=False, indent=2),
|
| 116 |
json.dumps(skills, ensure_ascii=False, indent=2),
|
|
|
|
| 131 |
label="レジュメ類 (PDF/画像/Word/テキスト) 複数可",
|
| 132 |
file_count="multiple",
|
| 133 |
file_types=[".pdf", ".png", ".jpg", ".jpeg", ".tiff", ".bmp", ".docx", ".txt"],
|
| 134 |
+
type="filepath", # ★ 重要: 'file' ではなく 'filepath'
|
| 135 |
)
|
| 136 |
candidate_id = gr.Textbox(label="候補者ID(任意。未入力なら自動生成)")
|
| 137 |
notes = gr.Textbox(label="補足メモ(任意)", lines=3)
|
|
|
|
| 142 |
out_json = gr.Code(label="統合出力 (JSON)")
|
| 143 |
|
| 144 |
with gr.Tab("抽出スキル"):
|
| 145 |
+
out_skills = gr.Code(label="スキル一覧 (JSON)") # ★ gr.JSON は使わない
|
| 146 |
|
| 147 |
with gr.Tab("品質スコア"):
|
| 148 |
out_score = gr.Code(label="品質評価")
|
|
|
|
| 166 |
|
| 167 |
|
| 168 |
if __name__ == "__main__":
|
| 169 |
+
# HF Spaces で share=True は未対応。明示的に 0.0.0.0 を指定。
|
| 170 |
+
demo.launch(server_name="0.0.0.0", server_port=7860)
|