Spaces:
Sleeping
Sleeping
Hakyung Sung
commited on
Commit
·
24a7c39
1
Parent(s):
0bd74cf
Correct app.py
Browse files
app.py
CHANGED
@@ -1,90 +1,140 @@
|
|
1 |
import gradio as gr
|
2 |
import spacy
|
3 |
-
import spacy_transformers
|
4 |
-
from collections import Counter
|
5 |
-
import plotly.graph_objects as go
|
6 |
-
import plotly.io as pio
|
7 |
-
import base64
|
8 |
-
import io
|
9 |
from huggingface_hub import snapshot_download
|
10 |
-
from PIL import Image
|
11 |
import os
|
12 |
|
13 |
-
# Download the model from Hugging Face Hub
|
14 |
model_repo = "hksung/ASC_tagger_v2"
|
15 |
model_path = snapshot_download(model_repo) # Assumes the repo is public; add token if needed
|
16 |
-
|
17 |
-
# Load the spaCy model
|
18 |
nlp = spacy.load(os.path.join(model_path, 'model-best'))
|
19 |
|
20 |
-
#
|
21 |
-
if 'parser' not in nlp.pipe_names and 'senter' not in nlp.pipe_names:
|
22 |
-
nlp.add_pipe('sentencizer')
|
23 |
-
# If the pipeline is missing a sentence splitter, add one
|
24 |
if 'parser' not in nlp.pipe_names and 'senter' not in nlp.pipe_names:
|
25 |
nlp.add_pipe('sentencizer')
|
26 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
27 |
def get_highlighted_text(doc):
|
28 |
"""
|
29 |
-
|
30 |
-
|
31 |
"""
|
32 |
highlighted_sentences = []
|
33 |
for sent in doc.sents:
|
34 |
-
|
35 |
-
#
|
36 |
ents_in_sent = [ent for ent in doc.ents if ent.start_char >= sent.start_char and ent.end_char <= sent.end_char]
|
37 |
if ents_in_sent:
|
38 |
-
# Process entities in reverse order
|
39 |
ents_in_sent = sorted(ents_in_sent, key=lambda x: x.start_char, reverse=True)
|
40 |
-
s = sent_text
|
41 |
for ent in ents_in_sent:
|
42 |
-
# Compute positions relative to the sentence start
|
43 |
ent_start = ent.start_char - sent.start_char
|
44 |
ent_end = ent.end_char - sent.start_char
|
45 |
-
#
|
|
|
46 |
s = (
|
47 |
s[:ent_start]
|
48 |
-
+ f'<span style="background-color:
|
49 |
+ s[ent_start:ent_end]
|
50 |
+ '</span>'
|
51 |
+ s[ent_end:]
|
52 |
)
|
53 |
-
|
54 |
-
|
55 |
-
highlighted_sentences.append(sent_text)
|
56 |
-
# Join sentences with HTML breaks so the output preserves sentence separations.
|
57 |
return "<br><br>".join(highlighted_sentences)
|
58 |
|
59 |
def process_text(input_text):
|
60 |
"""
|
61 |
-
Process
|
62 |
-
Returns an HTML string with
|
63 |
"""
|
64 |
if not input_text.strip():
|
65 |
return "No text provided. Please enter some text."
|
66 |
|
67 |
doc = nlp(input_text)
|
68 |
-
|
69 |
-
if
|
70 |
return "Please enter at least one sentence."
|
71 |
-
|
72 |
if not doc.ents:
|
73 |
return "No ASCs were detected."
|
74 |
|
75 |
-
# Get the HTML with highlighted ASCs.
|
76 |
return get_highlighted_text(doc)
|
77 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
78 |
# Build the Gradio interface.
|
79 |
with gr.Blocks() as demo:
|
80 |
-
gr.Markdown("# ASC
|
81 |
-
gr.Markdown("Enter some text to have ASCs tagged
|
82 |
|
83 |
input_textbox = gr.Textbox(lines=10, label="Input Text", placeholder="Enter text here...")
|
84 |
output_html = gr.HTML(label="Tagged Text")
|
|
|
|
|
|
|
85 |
tag_btn = gr.Button("Tag ASCs")
|
86 |
|
|
|
|
|
|
|
87 |
tag_btn.click(fn=process_text, inputs=input_textbox, outputs=output_html)
|
88 |
|
89 |
if __name__ == "__main__":
|
90 |
-
demo.launch()
|
|
|
1 |
import gradio as gr
|
2 |
import spacy
|
3 |
+
import spacy_transformers # Ensure transformer components register
|
|
|
|
|
|
|
|
|
|
|
4 |
from huggingface_hub import snapshot_download
|
|
|
5 |
import os
|
6 |
|
7 |
+
# Download the model from Hugging Face Hub and load it.
|
8 |
model_repo = "hksung/ASC_tagger_v2"
|
9 |
model_path = snapshot_download(model_repo) # Assumes the repo is public; add token if needed
|
|
|
|
|
10 |
nlp = spacy.load(os.path.join(model_path, 'model-best'))
|
11 |
|
12 |
+
# If sentence segmentation is missing, add a sentencizer.
|
|
|
|
|
|
|
13 |
if 'parser' not in nlp.pipe_names and 'senter' not in nlp.pipe_names:
|
14 |
nlp.add_pipe('sentencizer')
|
15 |
|
16 |
+
# Define the inline color mapping for each ASC tag.
|
17 |
+
color_scheme = {
|
18 |
+
"ATTR": "#f6e9e9", # Light Red
|
19 |
+
"INTRAN_S": "#e7957f", # Light Blue
|
20 |
+
"INTRAN_MOT": "#f6f6aa", # Light Green
|
21 |
+
"INTRAN_RES": "#f0aed6", # Light Yellow
|
22 |
+
"CAUS_MOT": "#cdefb5", # Light Pink
|
23 |
+
"TRAN_S": "#a0d4f7", # Light Blue
|
24 |
+
"TRAN_RES": "#c7aefa", # Light Purple
|
25 |
+
"DITRAN": "#b3f0f7", # Light Teal
|
26 |
+
"PASSIVE": "#c3c0c0" # Light Gray
|
27 |
+
}
|
28 |
+
|
29 |
def get_highlighted_text(doc):
|
30 |
"""
|
31 |
+
Wraps detected ASCs in each sentence with a span tag containing an inline style.
|
32 |
+
The inline style sets a custom background color based on the tag.
|
33 |
"""
|
34 |
highlighted_sentences = []
|
35 |
for sent in doc.sents:
|
36 |
+
s = sent.text
|
37 |
+
# Find all entities fully contained within this sentence.
|
38 |
ents_in_sent = [ent for ent in doc.ents if ent.start_char >= sent.start_char and ent.end_char <= sent.end_char]
|
39 |
if ents_in_sent:
|
40 |
+
# Process entities in reverse order so the character offsets remain valid.
|
41 |
ents_in_sent = sorted(ents_in_sent, key=lambda x: x.start_char, reverse=True)
|
|
|
42 |
for ent in ents_in_sent:
|
|
|
43 |
ent_start = ent.start_char - sent.start_char
|
44 |
ent_end = ent.end_char - sent.start_char
|
45 |
+
# Get the color from our scheme; use default if not defined.
|
46 |
+
color = color_scheme.get(ent.label_, "#cccccc")
|
47 |
s = (
|
48 |
s[:ent_start]
|
49 |
+
+ f'<span style="background-color: {color}; font-weight: bold;" title="{ent.label_}">'
|
50 |
+ s[ent_start:ent_end]
|
51 |
+ '</span>'
|
52 |
+ s[ent_end:]
|
53 |
)
|
54 |
+
highlighted_sentences.append(s)
|
55 |
+
# Combine sentences with HTML breaks.
|
|
|
|
|
56 |
return "<br><br>".join(highlighted_sentences)
|
57 |
|
58 |
def process_text(input_text):
|
59 |
"""
|
60 |
+
Process input text to detect and tag ASCs.
|
61 |
+
Returns an HTML string with inline styles applied to each entity.
|
62 |
"""
|
63 |
if not input_text.strip():
|
64 |
return "No text provided. Please enter some text."
|
65 |
|
66 |
doc = nlp(input_text)
|
67 |
+
|
68 |
+
if not list(doc.sents):
|
69 |
return "Please enter at least one sentence."
|
70 |
+
|
71 |
if not doc.ents:
|
72 |
return "No ASCs were detected."
|
73 |
|
|
|
74 |
return get_highlighted_text(doc)
|
75 |
|
76 |
+
# Define the sample text to be injected.
|
77 |
+
sample_text = (
|
78 |
+
"Once upon a time in a small, enchanted village nestled between towering mountains, there lived a baker named Oliver. "
|
79 |
+
"But this wasn't just any baker—Oliver had a magical secret. Every loaf of bread he baked had the power to grant a wish, "
|
80 |
+
"but only if it was made with true joy in his heart. The villagers adored Oliver’s bread, though they had no idea about its magic. "
|
81 |
+
"They just knew it tasted unlike anything else—warm, soft, and with a hint of something... extraordinary. Only a few people had ever discovered "
|
82 |
+
"its secret, and even fewer had made wishes, because the key was in asking for something truly selfless.\n\n"
|
83 |
+
|
84 |
+
"One crisp autumn morning, a traveling musician named Lyla passed through the village. She had a worn-out lute, tattered clothes, "
|
85 |
+
"and a bright spark of hope in her eyes despite her hardships. Drawn by the smell of freshly baked bread, she wandered into Oliver’s bakery.\n\n"
|
86 |
+
|
87 |
+
"Oliver, busy dusting flour off his hands, smiled warmly. “What can I do for you?” he asked.\n\n"
|
88 |
+
|
89 |
+
"Lyla’s stomach growled in response, and she laughed, a sound as melodic as her lute playing. “Just one loaf of bread, please,” she said, "
|
90 |
+
"placing a single coin on the counter, all she had left.\n\n"
|
91 |
+
|
92 |
+
"Oliver, feeling the joy in the simple act of serving someone in need, baked the loaf with care. As the bread came out of the oven, a golden glow "
|
93 |
+
"shimmered around it for just a moment. Lyla didn’t notice, but Oliver did, and he smiled to himself.\n\n"
|
94 |
+
|
95 |
+
"As Lyla took her first bite outside the shop, she felt warmth spread through her whole being. She thought of how she missed playing her lute to "
|
96 |
+
"cheer others up, but it was broken and beyond repair. Without knowing the magic at work, she whispered under her breath, 'I just wish I could bring "
|
97 |
+
"music to everyone again.'\n\n"
|
98 |
+
|
99 |
+
"That evening, as Lyla set up by the village fountain to play, something miraculous happened. Her old, broken lute began to transform, glowing just "
|
100 |
+
"like the bread had. In her hands now was the most beautiful lute she had ever seen, shimmering with gold and silver strings. When she strummed it, "
|
101 |
+
"the music that flowed out wasn’t just sound—it was pure joy.\n\n"
|
102 |
+
|
103 |
+
"The village gathered around her, drawn by the enchanting melodies that seemed to fill their hearts with warmth and happiness. People laughed, danced, "
|
104 |
+
"and even sang along, forgetting their worries.\n\n"
|
105 |
+
|
106 |
+
"Oliver watched from his bakery window, smiling to himself. He had no idea what Lyla had wished for, but he could see its magic at work. He knew his "
|
107 |
+
"bread had once again brought a little bit of magic to the world.\n\n"
|
108 |
+
|
109 |
+
"And so, every day after that, Lyla would play her magical lute in the village square, bringing joy to everyone who heard her music. People came from "
|
110 |
+
"distant lands just to hear her play, and with every note, the village grew a little brighter, a little happier.\n\n"
|
111 |
+
|
112 |
+
"As for Oliver, he continued to bake with joy in his heart, knowing that sometimes the smallest acts of kindness—like baking a loaf of bread—could "
|
113 |
+
"make the biggest difference in someone’s life.\n\n"
|
114 |
+
|
115 |
+
"And so, the village became known not just for its delicious bread, but for its music, magic, and the happiness that lingered in every corner. The end. "
|
116 |
+
"(Generated by ChatGPT 4o 🤖)"
|
117 |
+
)
|
118 |
+
|
119 |
+
def fill_sample_text():
|
120 |
+
return sample_text
|
121 |
+
|
122 |
# Build the Gradio interface.
|
123 |
with gr.Blocks() as demo:
|
124 |
+
gr.Markdown("# ASC tagger demo")
|
125 |
+
gr.Markdown("Enter some text to have ASCs tagged with a custom inline color scheme. Use the button below to fill in a sample text.")
|
126 |
|
127 |
input_textbox = gr.Textbox(lines=10, label="Input Text", placeholder="Enter text here...")
|
128 |
output_html = gr.HTML(label="Tagged Text")
|
129 |
+
# Button to fill sample text into the input textbox.
|
130 |
+
fill_btn = gr.Button("Fill Sample Text")
|
131 |
+
# Button to analyze the text.
|
132 |
tag_btn = gr.Button("Tag ASCs")
|
133 |
|
134 |
+
# When "Fill Sample Text" is clicked, populate the textbox.
|
135 |
+
fill_btn.click(fn=fill_sample_text, inputs=[], outputs=input_textbox)
|
136 |
+
# When "Tag ASCs" is clicked, process the input text.
|
137 |
tag_btn.click(fn=process_text, inputs=input_textbox, outputs=output_html)
|
138 |
|
139 |
if __name__ == "__main__":
|
140 |
+
demo.launch()
|