TextLens API for Python
Add text analysis to your Python app in 5 lines. Readability grades (8 formulas), sentiment scoring, keyword extraction, and SEO analysis — no textstat, VADER, or spaCy to install and configure.
import requests
result = requests.post(
'https://api.ckmtools.dev/v1/analyze',
headers={'X-API-Key': 'your_key'},
json={'text': 'Your content here...'}
).json()
print(result['readability']['consensus_grade']) # Grade 8
print(result['sentiment']['label']) # positive
print(result['keywords']['top_5']) # [content, quality, ...]
Join the Waitlist
What you get
8 Readability Formulas
Flesch-Kincaid, Gunning Fog, SMOG, Coleman-Liau, ARI, Dale-Chall, Linsear Write, plus a consensus grade. No single Python library covers all eight.
Sentiment + Keywords
AFINN sentiment scoring for long-form content — label, score, and confidence. TF-IDF keyword extraction with relevance scores. SEO quality scoring.
Zero Library Dependencies
No NLTK corpus downloads (150MB+), no spaCy model files (12MB–560MB), no pip deps beyond requests. Works in serverless, CI/CD, and containers.
The response
One endpoint returns everything you need:
{
"readability": {
"fleschKincaidGrade": 8.2,
"gunningFog": 10.1,
"smog": 9.4,
"colemanLiau": 11.3,
"ari": 9.7,
"daleChall": 7.8,
"linsearWrite": 8.5,
"consensusGrade": "Grade 9",
"fleschReadingEase": { "score": 62.3, "interpretation": "Standard" }
},
"sentiment": {
"label": "positive",
"score": 4.2,
"confidence": 0.71
},
"keywords": [
{ "word": "content", "score": 5.1, "count": 4, "density": 1.87 },
{ "word": "readability", "score": 4.8, "count": 3, "density": 1.40 }
],
"seo": { "score": 74, "grade": "B" },
"statistics": { "words": 342, "sentences": 18, "paragraphs": 5 },
"meta": { "processing_time_ms": 14 }
}
Python patterns
import requests
import os
class TextLensClient:
BASE_URL = 'https://api.ckmtools.dev/v1/analyze'
def __init__(self, api_key: str):
self.session = requests.Session()
self.session.headers.update({'X-API-Key': api_key})
def analyze(self, text: str) -> dict:
response = self.session.post(self.BASE_URL, json={'text': text})
response.raise_for_status()
return response.json()
client = TextLensClient(os.environ['TEXTLENS_KEY'])
result = client.analyze(article.body)
print(f"Grade: {result['readability']['consensusGrade']}")
print(f"Sentiment: {result['sentiment']['label']}")
print(f"SEO score: {result['seo']['score']}/100")
import httpx
import asyncio
import os
async def analyze_text(text: str) -> dict:
async with httpx.AsyncClient() as client:
response = await client.post(
'https://api.ckmtools.dev/v1/analyze',
headers={'X-API-Key': os.environ['TEXTLENS_KEY']},
json={'text': text}
)
response.raise_for_status()
return response.json()
# Analyze multiple documents concurrently
async def batch_analyze(texts: list[str]) -> list[dict]:
tasks = [analyze_text(t) for t in texts]
return await asyncio.gather(*tasks)
results = asyncio.run(batch_analyze(articles))
import urllib.request
import json
import os
def analyze(text: str, api_key: str) -> dict:
data = json.dumps({'text': text}).encode('utf-8')
req = urllib.request.Request(
'https://api.ckmtools.dev/v1/analyze',
data=data,
headers={
'Content-Type': 'application/json',
'X-API-Key': api_key,
},
method='POST'
)
with urllib.request.urlopen(req) as resp:
return json.loads(resp.read())
result = analyze(document, os.environ['TEXTLENS_KEY'])
print(result['readability']['consensusGrade'])
Why not textstat + VADER + spaCy?
Three packages, three APIs, three version conflicts. textstat covers readability but skips sentiment. vaderSentiment covers sentiment but not readability. spaCy requires a model download (12MB to 560MB) before you can do anything. And none of them give you SEO scoring. TextLens API covers all of it in a single HTTP call — no corpus downloads, no model files, no dependency resolver headaches. The same endpoint works from Python, Ruby, Go, or any language with an HTTP client.
Join the Waitlist
TextLens API is in development. Join the waitlist to get notified at launch.
Backed by the textlens npm package — 96 downloads/week.
Get Early Access$0 — no credit card required
Pricing
Using Ruby? See Ruby-specific examples →
Using Go? See Go-specific examples →