SpellChecker instance once at startup, then reuse it across requests. Use check_async() for async frameworks and check() for sync ones.
FastAPI
Basic Endpoint
Copy
Ask AI
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel, Field
from myspellchecker import SpellChecker
from myspellchecker.core.constants import ValidationLevel
app = FastAPI(title="Myanmar Spell Checker API")
checker = SpellChecker() # Create once, reuse
class CheckRequest(BaseModel):
text: str = Field(..., min_length=1, max_length=10000)
level: str = Field(default="syllable")
class ErrorInfo(BaseModel):
text: str
position: int
error_type: str
suggestions: list[str]
confidence: float
class CheckResponse(BaseModel):
text: str
has_errors: bool
corrected_text: str
errors: list[ErrorInfo]
@app.post("/check", response_model=CheckResponse)
async def check_spelling(request: CheckRequest):
level = ValidationLevel(request.level)
result = await checker.check_async(request.text, level=level)
return CheckResponse(
text=result.text,
has_errors=result.has_errors,
corrected_text=result.corrected_text,
errors=[
ErrorInfo(
text=e.text,
position=e.position,
error_type=e.error_type,
suggestions=e.suggestions[:5],
confidence=e.confidence,
)
for e in result.errors
],
)
Testing with curl
Copy
Ask AI
# Check single text
curl -X POST http://localhost:8000/check \
-H "Content-Type: application/json" \
-d '{"text": "မြန်မာနိုင်ငံသည်", "level": "syllable"}'
# Batch check
curl -X POST http://localhost:8000/check/batch \
-H "Content-Type: application/json" \
-d '{"texts": ["မြန်မာ", "နိုင်ငံ"], "level": "syllable"}'
# Health check
curl http://localhost:8000/health
Batch Endpoint
Copy
Ask AI
class BatchRequest(BaseModel):
texts: list[str]
@app.post("/check/batch")
async def check_batch(request: BatchRequest):
results = await checker.check_batch_async(request.texts)
return {
"results": [
{"text": r.text, "has_errors": r.has_errors, "error_count": len(r.errors)}
for r in results
],
"summary": {
"total_texts": len(results),
"texts_with_errors": sum(1 for r in results if r.has_errors),
},
}
With Lifespan Management
Copy
Ask AI
from contextlib import asynccontextmanager
from fastapi import FastAPI, Request
@asynccontextmanager
async def lifespan(app: FastAPI):
app.state.checker = SpellChecker()
yield
app = FastAPI(lifespan=lifespan)
@app.post("/check")
async def check_spelling(request: Request, body: CheckRequest):
checker = request.app.state.checker
result = await checker.check_async(body.text)
return {"has_errors": result.has_errors, "errors": [...]}
CORS Configuration
Copy
Ask AI
from fastapi.middleware.cors import CORSMiddleware
import os
allowed_origins_env = os.getenv("ALLOWED_ORIGINS")
if allowed_origins_env:
origins = [o.strip() for o in allowed_origins_env.split(",")]
allow_credentials = True
else:
origins = ["*"]
allow_credentials = False
app.add_middleware(
CORSMiddleware,
allow_origins=origins,
allow_credentials=allow_credentials,
allow_methods=["*"],
allow_headers=["*"],
)
Production Deployment
Copy
Ask AI
# Development with auto-reload
uvicorn app:app --reload --port 8000
# Production with Gunicorn
gunicorn app:app \
-w 4 \
-k uvicorn.workers.UvicornWorker \
--bind 0.0.0.0:8000
Flask
Basic Setup
Copy
Ask AI
from flask import Flask, request, jsonify
from myspellchecker import SpellChecker
app = Flask(__name__)
checker = SpellChecker()
@app.route("/check", methods=["POST"])
def check_spelling():
data = request.get_json()
text = data.get("text", "")
result = checker.check(text)
return jsonify({
"has_errors": result.has_errors,
"errors": [
{
"text": e.text,
"position": e.position,
"suggestions": e.suggestions[:5],
}
for e in result.errors
],
})
if __name__ == "__main__":
app.run()
With Application Factory
Copy
Ask AI
from flask import Flask
def create_app():
app = Flask(__name__)
checker = SpellChecker()
app.extensions["spellchecker"] = checker
from . import routes
app.register_blueprint(routes.bp)
return app
# routes.py
from flask import Blueprint, current_app, request, jsonify
bp = Blueprint("spell", __name__)
@bp.route("/check", methods=["POST"])
def check():
checker = current_app.extensions["spellchecker"]
result = checker.check(request.json["text"])
return jsonify({"has_errors": result.has_errors})
Django
As a Service
Copy
Ask AI
# services/spellcheck.py
from myspellchecker import SpellChecker
class SpellCheckService:
_instance = None
@classmethod
def get_instance(cls):
if cls._instance is None:
cls._instance = SpellChecker()
return cls._instance
@classmethod
def check(cls, text: str):
return cls.get_instance().check(text)
View Example
Copy
Ask AI
# views.py
from django.http import JsonResponse
from django.views.decorators.http import require_POST
from django.views.decorators.csrf import csrf_exempt
import json
from .services.spellcheck import SpellCheckService
@csrf_exempt
@require_POST
def check_spelling(request):
data = json.loads(request.body)
result = SpellCheckService.check(data.get("text", ""))
return JsonResponse({
"has_errors": result.has_errors,
"errors": [
{"text": e.text, "suggestions": e.suggestions[:5]}
for e in result.errors
],
})
Django REST Framework
Copy
Ask AI
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import serializers
class SpellCheckRequestSerializer(serializers.Serializer):
text = serializers.CharField()
class SpellCheckView(APIView):
def post(self, request):
serializer = SpellCheckRequestSerializer(data=request.data)
serializer.is_valid(raise_exception=True)
result = SpellCheckService.check(serializer.validated_data["text"])
return Response({
"has_errors": result.has_errors,
"errors": [
{"text": e.text, "position": e.position, "suggestions": e.suggestions[:5]}
for e in result.errors
],
})
WebSocket
FastAPI WebSocket
Copy
Ask AI
from fastapi import FastAPI, WebSocket
import json
app = FastAPI()
checker = SpellChecker()
@app.websocket("/ws/check")
async def websocket_check(websocket: WebSocket):
await websocket.accept()
try:
while True:
data = await websocket.receive_text()
message = json.loads(data)
result = await checker.check_async(message["text"])
await websocket.send_json({
"has_errors": result.has_errors,
"errors": [
{"text": e.text, "suggestions": e.suggestions[:3]}
for e in result.errors
],
})
except Exception:
pass
Celery
Task Definition
Copy
Ask AI
# tasks.py
from celery import Celery
from myspellchecker import SpellChecker
app = Celery("spellcheck")
checker = None
@app.task
def check_text(text: str) -> dict:
global checker
if checker is None:
checker = SpellChecker()
result = checker.check(text)
return {
"has_errors": result.has_errors,
"error_count": len(result.errors),
"errors": [
{"text": e.text, "suggestions": e.suggestions[:5]}
for e in result.errors
],
}
# Usage
result = check_text.delay("မြန်မာနိုင်ငံ")
output = result.get()
Common Patterns
Error Handling
Copy
Ask AI
from myspellchecker.core.exceptions import MyanmarSpellcheckError
@app.post("/check")
async def check_spelling(request: CheckRequest):
try:
result = await checker.check_async(request.text)
return {"status": "success", "result": {...}}
except MyanmarSpellcheckError as e:
return {"status": "error", "message": str(e)}, 500
except Exception:
return {
"status": "degraded",
"message": "Spell check unavailable",
"original_text": request.text,
}
Health Check
Copy
Ask AI
@app.get("/health")
async def health_check():
try:
result = checker.check("မြန်မာ")
return {"status": "healthy", "checker": "ok"}
except Exception as e:
return {"status": "unhealthy", "error": str(e)}, 500
Redis Caching
Copy
Ask AI
import redis
import hashlib
import json
redis_client = redis.Redis()
def cached_check(text: str, ttl: int = 3600) -> dict:
key = f"spell:{hashlib.md5(text.encode()).hexdigest()}"
cached = redis_client.get(key)
if cached:
return json.loads(cached)
result = checker.check(text)
output = {
"has_errors": result.has_errors,
"errors": [{"text": e.text} for e in result.errors],
}
redis_client.setex(key, ttl, json.dumps(output))
return output
See Also
- Async API -
check_async()andcheck_batch_async()details - Batch Processing - Efficient batch checking
- Docker Guide - Containerized deployment
- Performance Tuning - Optimization strategies