Spaces:
Runtime error
Runtime error
| # 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 | |