Update app.py
Browse files
app.py
CHANGED
@@ -72,11 +72,8 @@ class TextHumanizer:
|
|
72 |
}
|
73 |
|
74 |
def detect_ai_text(self, text: str) -> float:
|
75 |
-
"""
|
76 |
-
Detect if text is AI-generated and return confidence score
|
77 |
-
"""
|
78 |
try:
|
79 |
-
# Split long text into sentences and analyze each chunk
|
80 |
sentences = sent_tokenize(text)
|
81 |
chunks = [' '.join(sentences[i:i+5]) for i in range(0, len(sentences), 5)]
|
82 |
|
@@ -93,10 +90,7 @@ class TextHumanizer:
|
|
93 |
return 0.0
|
94 |
|
95 |
def add_human_variations(self, text: str) -> str:
|
96 |
-
"""
|
97 |
-
Add human-like variations to text
|
98 |
-
"""
|
99 |
-
# Add occasional filler words
|
100 |
fillers = ["well", "you know", "actually", "basically", "I mean"]
|
101 |
|
102 |
try:
|
@@ -106,11 +100,10 @@ class TextHumanizer:
|
|
106 |
sentences = text.split('.')
|
107 |
|
108 |
for i in range(len(sentences)):
|
109 |
-
if random.random() < 0.3:
|
110 |
filler = random.choice(fillers)
|
111 |
sentences[i] = f"{filler}, {sentences[i].lower()}"
|
112 |
|
113 |
-
# Add minor grammatical variations
|
114 |
text = ' '.join(sentences)
|
115 |
text = text.replace(" can not ", " can't ")
|
116 |
text = text.replace(" do not ", " don't ")
|
@@ -124,25 +117,19 @@ class TextHumanizer:
|
|
124 |
translate_to: Optional[str] = None,
|
125 |
max_retries: int = 3
|
126 |
) -> str:
|
127 |
-
"""
|
128 |
-
Main function to humanize text with error handling and retries
|
129 |
-
"""
|
130 |
try:
|
131 |
-
# Verify NLTK is properly initialized
|
132 |
nltk.data.find('tokenizers/punkt')
|
133 |
|
134 |
-
# Check if text is likely AI-generated
|
135 |
ai_score = self.detect_ai_text(text)
|
136 |
logger.info(f"AI detection score: {ai_score}")
|
137 |
|
138 |
-
if ai_score < 0.7:
|
139 |
logger.info("Text appears human-written, making minor adjustments")
|
140 |
output = self.add_human_variations(text)
|
141 |
else:
|
142 |
-
# Select random prompt variation for the chosen tone
|
143 |
prompt = random.choice(self.tone_prompts[tone]).format(text=text)
|
144 |
|
145 |
-
# Try generation with retries
|
146 |
for attempt in range(max_retries):
|
147 |
try:
|
148 |
output = self.humanizer(
|
@@ -153,15 +140,13 @@ class TextHumanizer:
|
|
153 |
top_p=0.9
|
154 |
)[0]['generated_text']
|
155 |
|
156 |
-
# Add human variations
|
157 |
output = self.add_human_variations(output)
|
158 |
-
|
159 |
-
# Verify the output is more human-like
|
160 |
new_ai_score = self.detect_ai_text(output)
|
|
|
161 |
if new_ai_score < ai_score:
|
162 |
break
|
163 |
elif attempt < max_retries - 1:
|
164 |
-
logger.warning(f"Attempt {attempt + 1}:
|
165 |
time.sleep(1)
|
166 |
except Exception as e:
|
167 |
if attempt < max_retries - 1:
|
@@ -170,7 +155,6 @@ class TextHumanizer:
|
|
170 |
else:
|
171 |
raise
|
172 |
|
173 |
-
# Handle translation if requested
|
174 |
if translate_to and translate_to != "None":
|
175 |
lang_code = translate_to.split(" ")[0]
|
176 |
output = self.translator.translate(output, destination_language=lang_code).result
|
@@ -184,8 +168,20 @@ class TextHumanizer:
|
|
184 |
def create_interface():
|
185 |
humanizer = TextHumanizer()
|
186 |
|
187 |
-
def process_text(text: str, tone: str, translate_to: str) ->
|
188 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
189 |
|
190 |
iface = gr.Interface(
|
191 |
fn=process_text,
|
@@ -196,7 +192,7 @@ def create_interface():
|
|
196 |
lines=5
|
197 |
),
|
198 |
gr.Dropdown(
|
199 |
-
choices=list(humanizer.tone_prompts.keys()),
|
200 |
label="Writing Style",
|
201 |
value="Casual",
|
202 |
info="Select the desired writing style for the output"
|
@@ -216,7 +212,7 @@ def create_interface():
|
|
216 |
info="Optional: translate the output to another language"
|
217 |
)
|
218 |
],
|
219 |
-
outputs=gr.
|
220 |
title="AI Text Humanizer",
|
221 |
description="Convert AI-generated text into more natural, human-like writing",
|
222 |
examples=[
|
@@ -227,16 +223,16 @@ def create_interface():
|
|
227 |
"Business",
|
228 |
"es (Spanish)"]
|
229 |
],
|
230 |
-
|
231 |
)
|
232 |
-
|
233 |
-
|
234 |
-
if __name__ == "__main__":
|
235 |
-
# Set up thread pool for handling multiple requests
|
236 |
-
interface = create_interface()
|
237 |
-
interface.queue()
|
238 |
-
interface.launch(
|
239 |
server_name="0.0.0.0",
|
240 |
server_port=7860,
|
241 |
-
share=True
|
242 |
-
|
|
|
|
|
|
|
|
|
|
|
|
72 |
}
|
73 |
|
74 |
def detect_ai_text(self, text: str) -> float:
|
75 |
+
"""Detect if text is AI-generated and return confidence score"""
|
|
|
|
|
76 |
try:
|
|
|
77 |
sentences = sent_tokenize(text)
|
78 |
chunks = [' '.join(sentences[i:i+5]) for i in range(0, len(sentences), 5)]
|
79 |
|
|
|
90 |
return 0.0
|
91 |
|
92 |
def add_human_variations(self, text: str) -> str:
|
93 |
+
"""Add human-like variations to text"""
|
|
|
|
|
|
|
94 |
fillers = ["well", "you know", "actually", "basically", "I mean"]
|
95 |
|
96 |
try:
|
|
|
100 |
sentences = text.split('.')
|
101 |
|
102 |
for i in range(len(sentences)):
|
103 |
+
if random.random() < 0.3:
|
104 |
filler = random.choice(fillers)
|
105 |
sentences[i] = f"{filler}, {sentences[i].lower()}"
|
106 |
|
|
|
107 |
text = ' '.join(sentences)
|
108 |
text = text.replace(" can not ", " can't ")
|
109 |
text = text.replace(" do not ", " don't ")
|
|
|
117 |
translate_to: Optional[str] = None,
|
118 |
max_retries: int = 3
|
119 |
) -> str:
|
120 |
+
"""Main humanization function with error handling"""
|
|
|
|
|
121 |
try:
|
|
|
122 |
nltk.data.find('tokenizers/punkt')
|
123 |
|
|
|
124 |
ai_score = self.detect_ai_text(text)
|
125 |
logger.info(f"AI detection score: {ai_score}")
|
126 |
|
127 |
+
if ai_score < 0.7:
|
128 |
logger.info("Text appears human-written, making minor adjustments")
|
129 |
output = self.add_human_variations(text)
|
130 |
else:
|
|
|
131 |
prompt = random.choice(self.tone_prompts[tone]).format(text=text)
|
132 |
|
|
|
133 |
for attempt in range(max_retries):
|
134 |
try:
|
135 |
output = self.humanizer(
|
|
|
140 |
top_p=0.9
|
141 |
)[0]['generated_text']
|
142 |
|
|
|
143 |
output = self.add_human_variations(output)
|
|
|
|
|
144 |
new_ai_score = self.detect_ai_text(output)
|
145 |
+
|
146 |
if new_ai_score < ai_score:
|
147 |
break
|
148 |
elif attempt < max_retries - 1:
|
149 |
+
logger.warning(f"Attempt {attempt + 1}: Retrying...")
|
150 |
time.sleep(1)
|
151 |
except Exception as e:
|
152 |
if attempt < max_retries - 1:
|
|
|
155 |
else:
|
156 |
raise
|
157 |
|
|
|
158 |
if translate_to and translate_to != "None":
|
159 |
lang_code = translate_to.split(" ")[0]
|
160 |
output = self.translator.translate(output, destination_language=lang_code).result
|
|
|
168 |
def create_interface():
|
169 |
humanizer = TextHumanizer()
|
170 |
|
171 |
+
def process_text(text: str, tone: str, translate_to: str) -> Dict:
|
172 |
+
try:
|
173 |
+
processed = humanizer.humanize_text(text, tone, translate_to)
|
174 |
+
return {
|
175 |
+
"data": [processed],
|
176 |
+
"success": True,
|
177 |
+
"error": None
|
178 |
+
}
|
179 |
+
except Exception as e:
|
180 |
+
return {
|
181 |
+
"data": [],
|
182 |
+
"success": False,
|
183 |
+
"error": str(e)
|
184 |
+
}
|
185 |
|
186 |
iface = gr.Interface(
|
187 |
fn=process_text,
|
|
|
192 |
lines=5
|
193 |
),
|
194 |
gr.Dropdown(
|
195 |
+
choices=list(humanizer.tone_prompts.keys()), # Restored dynamic tones
|
196 |
label="Writing Style",
|
197 |
value="Casual",
|
198 |
info="Select the desired writing style for the output"
|
|
|
212 |
info="Optional: translate the output to another language"
|
213 |
)
|
214 |
],
|
215 |
+
outputs=gr.JSON(label="API Response"),
|
216 |
title="AI Text Humanizer",
|
217 |
description="Convert AI-generated text into more natural, human-like writing",
|
218 |
examples=[
|
|
|
223 |
"Business",
|
224 |
"es (Spanish)"]
|
225 |
],
|
226 |
+
allow_flagging="never"
|
227 |
)
|
228 |
+
|
229 |
+
iface.launch(
|
|
|
|
|
|
|
|
|
|
|
230 |
server_name="0.0.0.0",
|
231 |
server_port=7860,
|
232 |
+
share=True,
|
233 |
+
cors_allowed_origins=["*"],
|
234 |
+
allowed_paths=["*"]
|
235 |
+
)
|
236 |
+
|
237 |
+
if __name__ == "__main__":
|
238 |
+
create_interface()
|