wellsaid / app /services /readability.py
iamspruce
fixed the api
73a6a7e
# app/services/readability.py
import textstat
import logging
from app.core.config import APP_NAME
from app.core.exceptions import ServiceError
logger = logging.getLogger(f"{APP_NAME}.services.readability")
class ReadabilityScorer:
async def compute(self, text: str) -> dict:
try:
text = text.strip()
if not text:
raise ServiceError(status_code=400, detail="Input text is empty for readability scoring.")
scores = {
"flesch_reading_ease": textstat.flesch_reading_ease(text),
"flesch_kincaid_grade": textstat.flesch_kincaid_grade(text),
"gunning_fog_index": textstat.gunning_fog(text),
"smog_index": textstat.smog_index(text),
"coleman_liau_index": textstat.coleman_liau_index(text),
"automated_readability_index": textstat.automated_readability_index(text),
}
friendly_scores = {
"flesch_reading_ease": {
"score": round(scores["flesch_reading_ease"], 2),
"label": "Flesch Reading Ease",
"description": "Higher is easier. 60–70 is plain English; 90+ is very easy."
},
"flesch_kincaid_grade": {
"score": round(scores["flesch_kincaid_grade"], 2),
"label": "Flesch-Kincaid Grade Level",
"description": "U.S. school grade. 8.0 means an 8th grader can understand it."
},
"gunning_fog_index": {
"score": round(scores["gunning_fog_index"], 2),
"label": "Gunning Fog Index",
"description": "Estimates years of formal education needed to understand."
},
"smog_index": {
"score": round(scores["smog_index"], 2),
"label": "SMOG Index",
"description": "Also estimates required years of education."
},
"coleman_liau_index": {
"score": round(scores["coleman_liau_index"], 2),
"label": "Coleman-Liau Index",
"description": "Grade level based on characters, not syllables."
},
"automated_readability_index": {
"score": round(scores["automated_readability_index"], 2),
"label": "Automated Readability Index",
"description": "Grade level using word and sentence lengths."
}
}
ease_score = scores["flesch_reading_ease"]
if ease_score >= 90:
summary = "Very easy to read. Easily understood by 11-year-olds."
elif ease_score >= 70:
summary = "Fairly easy. Conversational English for most people."
elif ease_score >= 60:
summary = "Plain English. Easily understood by 13–15-year-olds."
elif ease_score >= 30:
summary = "Fairly difficult. College-level reading."
else:
summary = "Very difficult. Best understood by university graduates."
return {
"readability_summary": summary,
"scores": friendly_scores
}
except Exception as e:
logger.error(f"Readability scoring error for text: '{text[:50]}...'", exc_info=True)
raise ServiceError(status_code=500, detail="An internal error occurred during readability scoring.") from e
# You can continue pasting the rest of your services here for production hardening