Spaces:
Runtime error
Runtime error
iamspruce
commited on
Commit
·
869988f
1
Parent(s):
fc43d8e
updated api
Browse files- app/routers/analyze.py +34 -18
app/routers/analyze.py
CHANGED
|
@@ -10,7 +10,16 @@ router = APIRouter()
|
|
| 10 |
|
| 11 |
# Load the spaCy English language model for natural language processing tasks,
|
| 12 |
# such as dependency parsing for active/passive voice detection.
|
| 13 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 14 |
|
| 15 |
# Initialize LanguageTool for grammar, spelling, and style checking.
|
| 16 |
# 'en-US' specifies the English (United States) language.
|
|
@@ -23,18 +32,20 @@ class AnalyzeInput(BaseModel):
|
|
| 23 |
"""
|
| 24 |
text: str
|
| 25 |
|
| 26 |
-
|
| 27 |
-
|
|
|
|
|
|
|
| 28 |
"""
|
| 29 |
Analyzes the provided text for grammar, punctuation, sentence correctness,
|
| 30 |
tone, active/passive voice, and inclusive pronoun suggestions.
|
| 31 |
|
| 32 |
Args:
|
| 33 |
payload (AnalyzeInput): The request body containing the text to be analyzed.
|
| 34 |
-
|
| 35 |
|
| 36 |
Returns:
|
| 37 |
-
dict: A dictionary containing various analysis results.
|
| 38 |
"""
|
| 39 |
text = payload.text
|
| 40 |
|
|
@@ -42,11 +53,11 @@ def analyze_text(payload: AnalyzeInput, request: Request = Depends(verify_api_ke
|
|
| 42 |
# Get the grammatically corrected version of the original text.
|
| 43 |
corrected_grammar = models.run_grammar_correction(text)
|
| 44 |
|
|
|
|
| 45 |
# Use difflib to find differences between the original and corrected text.
|
| 46 |
-
#
|
| 47 |
s = difflib.SequenceMatcher(None, text.split(), corrected_grammar.split())
|
| 48 |
|
| 49 |
-
grammar_changes = []
|
| 50 |
# Iterate through the operations (opcodes) generated by SequenceMatcher.
|
| 51 |
# 'equal', 'replace', 'delete', 'insert' are the types of operations.
|
| 52 |
for opcode, i1, i2, j1, j2 in s.get_opcodes():
|
|
@@ -72,7 +83,7 @@ def analyze_text(payload: AnalyzeInput, request: Request = Depends(verify_api_ke
|
|
| 72 |
sentence_correctness_feedback = []
|
| 73 |
|
| 74 |
for m in matches:
|
| 75 |
-
# Check if the rule ID contains "PUNCTUATION" to categorize it.
|
| 76 |
if 'PUNCTUATION' in m.ruleId.upper():
|
| 77 |
punctuation_issues.append(m.message)
|
| 78 |
else:
|
|
@@ -80,36 +91,41 @@ def analyze_text(payload: AnalyzeInput, request: Request = Depends(verify_api_ke
|
|
| 80 |
sentence_correctness_feedback.append(m.message)
|
| 81 |
|
| 82 |
# --- 4. Tone Detection and Suggestion ---
|
| 83 |
-
# Classify the tone of the original text using the fine-tuned
|
| 84 |
detected_tone = models.classify_tone(text)
|
| 85 |
|
| 86 |
tone_suggestion_text = ""
|
| 87 |
# Provide a simple tone suggestion based on the detected tone.
|
| 88 |
-
# This logic can be expanded for more sophisticated suggestions.
|
| 89 |
-
if detected_tone in ["neutral", "joy"]: # Example
|
| 90 |
# Generate a formal tone version using FLAN-T5.
|
| 91 |
tone_suggestion_text = models.run_flan_prompt(prompts.tone_prompt(text, "formal"))
|
|
|
|
|
|
|
|
|
|
|
|
|
| 92 |
else:
|
|
|
|
| 93 |
tone_suggestion_text = f"The detected tone '{detected_tone}' seems appropriate for general communication."
|
| 94 |
|
| 95 |
|
| 96 |
# --- 5. Active/Passive Voice Detection and Suggestion ---
|
| 97 |
-
doc = nlp(text) # Process the text with spaCy
|
| 98 |
voice_detected = "active"
|
| 99 |
-
voice_suggestion = "None \u2014 active voice is fine here." # Using Unicode em dash
|
| 100 |
|
| 101 |
-
# Iterate through tokens to find passive auxiliary verbs (e.g., "is", "was"
|
| 102 |
-
# A simple heuristic: if any token's dependency is 'auxpass', it's likely passive.
|
| 103 |
for token in doc:
|
| 104 |
if token.dep_ == "auxpass":
|
| 105 |
voice_detected = "passive"
|
| 106 |
-
# If passive, ask FLAN-T5 to rewrite it in active voice.
|
| 107 |
better_voice_prompt = prompts.active_voice_prompt(text)
|
| 108 |
voice_suggestion = models.run_flan_prompt(better_voice_prompt)
|
| 109 |
-
break # Exit loop once passive voice is detected
|
| 110 |
|
| 111 |
# --- 6. Inclusive Pronoun Suggestion ---
|
| 112 |
-
# Use FLAN-T5 with a specific prompt to suggest inclusive language.
|
| 113 |
inclusive_pronouns_suggestion = models.run_flan_prompt(prompts.pronoun_friendly_prompt(text))
|
| 114 |
|
| 115 |
# --- Construct the final response matching the example output structure ---
|
|
|
|
| 10 |
|
| 11 |
# Load the spaCy English language model for natural language processing tasks,
|
| 12 |
# such as dependency parsing for active/passive voice detection.
|
| 13 |
+
# IMPORTANT: If you get an OSError: [E050] Can't find model 'en_core_web_sm',
|
| 14 |
+
# you need to run: python -m spacy download en_core_web_sm in your terminal.
|
| 15 |
+
try:
|
| 16 |
+
nlp = spacy.load("en_core_web_sm")
|
| 17 |
+
except OSError:
|
| 18 |
+
print("SpaCy model 'en_core_web_sm' not found. Please run: python -m spacy download en_core_web_sm")
|
| 19 |
+
# You might want to raise an HTTPException or provide a dummy NLP object
|
| 20 |
+
# if the model is crucial for the application to function.
|
| 21 |
+
# For now, we'll let it fail if not installed, as it's a critical dependency.
|
| 22 |
+
raise
|
| 23 |
|
| 24 |
# Initialize LanguageTool for grammar, spelling, and style checking.
|
| 25 |
# 'en-US' specifies the English (United States) language.
|
|
|
|
| 32 |
"""
|
| 33 |
text: str
|
| 34 |
|
| 35 |
+
# Apply the verify_api_key dependency at the router level for this endpoint.
|
| 36 |
+
# The Request object is now correctly handled without being wrapped by Depends.
|
| 37 |
+
@router.post("/analyze", dependencies=[Depends(verify_api_key)])
|
| 38 |
+
def analyze_text(payload: AnalyzeInput):
|
| 39 |
"""
|
| 40 |
Analyzes the provided text for grammar, punctuation, sentence correctness,
|
| 41 |
tone, active/passive voice, and inclusive pronoun suggestions.
|
| 42 |
|
| 43 |
Args:
|
| 44 |
payload (AnalyzeInput): The request body containing the text to be analyzed.
|
| 45 |
+
(dependencies=[Depends(verify_api_key)]): Ensures the API key is verified before execution.
|
| 46 |
|
| 47 |
Returns:
|
| 48 |
+
dict: A dictionary containing various analysis results structured as per requirements.
|
| 49 |
"""
|
| 50 |
text = payload.text
|
| 51 |
|
|
|
|
| 53 |
# Get the grammatically corrected version of the original text.
|
| 54 |
corrected_grammar = models.run_grammar_correction(text)
|
| 55 |
|
| 56 |
+
grammar_changes = []
|
| 57 |
# Use difflib to find differences between the original and corrected text.
|
| 58 |
+
# We split by words to get word-level diffs, which are easier to interpret.
|
| 59 |
s = difflib.SequenceMatcher(None, text.split(), corrected_grammar.split())
|
| 60 |
|
|
|
|
| 61 |
# Iterate through the operations (opcodes) generated by SequenceMatcher.
|
| 62 |
# 'equal', 'replace', 'delete', 'insert' are the types of operations.
|
| 63 |
for opcode, i1, i2, j1, j2 in s.get_opcodes():
|
|
|
|
| 83 |
sentence_correctness_feedback = []
|
| 84 |
|
| 85 |
for m in matches:
|
| 86 |
+
# Check if the rule ID (from LanguageTool) contains "PUNCTUATION" to categorize it.
|
| 87 |
if 'PUNCTUATION' in m.ruleId.upper():
|
| 88 |
punctuation_issues.append(m.message)
|
| 89 |
else:
|
|
|
|
| 91 |
sentence_correctness_feedback.append(m.message)
|
| 92 |
|
| 93 |
# --- 4. Tone Detection and Suggestion ---
|
| 94 |
+
# Classify the tone of the original text using the fine-tuned emotion classifier.
|
| 95 |
detected_tone = models.classify_tone(text)
|
| 96 |
|
| 97 |
tone_suggestion_text = ""
|
| 98 |
# Provide a simple tone suggestion based on the detected tone.
|
| 99 |
+
# This logic can be expanded for more sophisticated suggestions based on context or user goals.
|
| 100 |
+
if detected_tone in ["neutral", "joy"]: # Example: if text is neutral or joyful, suggest a formal alternative
|
| 101 |
# Generate a formal tone version using FLAN-T5.
|
| 102 |
tone_suggestion_text = models.run_flan_prompt(prompts.tone_prompt(text, "formal"))
|
| 103 |
+
elif detected_tone == "anger":
|
| 104 |
+
tone_suggestion_text = models.run_flan_prompt(prompts.tone_prompt(text, "calm and professional"))
|
| 105 |
+
elif detected_tone == "sadness":
|
| 106 |
+
tone_suggestion_text = models.run_flan_prompt(prompts.tone_prompt(text, "more uplifting"))
|
| 107 |
else:
|
| 108 |
+
# If no specific suggestion, indicate that the detected tone is generally fine.
|
| 109 |
tone_suggestion_text = f"The detected tone '{detected_tone}' seems appropriate for general communication."
|
| 110 |
|
| 111 |
|
| 112 |
# --- 5. Active/Passive Voice Detection and Suggestion ---
|
| 113 |
+
doc = nlp(text) # Process the text with spaCy for linguistic analysis
|
| 114 |
voice_detected = "active"
|
| 115 |
+
voice_suggestion = "None \u2014 active voice is fine here." # Using Unicode em dash for better readability
|
| 116 |
|
| 117 |
+
# Iterate through tokens to find passive auxiliary verbs (e.g., "is", "was", "been" when followed by a past participle).
|
| 118 |
+
# A simple heuristic: if any token's dependency is 'auxpass', it's likely part of a passive construction.
|
| 119 |
for token in doc:
|
| 120 |
if token.dep_ == "auxpass":
|
| 121 |
voice_detected = "passive"
|
| 122 |
+
# If passive voice is detected, ask FLAN-T5 to rewrite it in active voice.
|
| 123 |
better_voice_prompt = prompts.active_voice_prompt(text)
|
| 124 |
voice_suggestion = models.run_flan_prompt(better_voice_prompt)
|
| 125 |
+
break # Exit loop once passive voice is detected, no need to check further
|
| 126 |
|
| 127 |
# --- 6. Inclusive Pronoun Suggestion ---
|
| 128 |
+
# Use FLAN-T5 with a specific prompt to suggest more inclusive language.
|
| 129 |
inclusive_pronouns_suggestion = models.run_flan_prompt(prompts.pronoun_friendly_prompt(text))
|
| 130 |
|
| 131 |
# --- Construct the final response matching the example output structure ---
|