This repository has been archived on 2025-11-17. You can view files and clone it, but cannot push or open issues or pull requests.
Files
pypages/routes/api.py
2025-11-16 18:01:30 +01:00

158 lines
4.8 KiB
Python

"""
API routes for the pydoc translation service.
FastAPI-compatible route structure implemented in Flask.
"""
from flask import Blueprint, request, jsonify
from modules.doc_extractor import DocExtractor
from modules.translator import TranslationService
from modules.cache import CacheService
from modules.module_list import ModuleList
from modules.course_scraper import CourseScraper
api_bp = Blueprint('api', __name__, url_prefix='')
# Initialize services (singleton pattern)
doc_extractor = DocExtractor()
translator = TranslationService()
cache = CacheService()
module_list = ModuleList()
@api_bp.route('/docs', methods=['GET'])
def get_docs():
"""
Get documentation for a Python object with optional translation.
Query parameters:
object: Python object name (e.g., 'dict.update', 'os.path')
lang: Target language code (e.g., 'de', 'fr', 'es'). Optional.
Returns:
JSON response with:
- original: Original English documentation
- translated: Translated documentation (if lang provided)
- object_name: Name of the object
- object_type: Type of object
- signature: Function signature if applicable
- error: Error message if any
- cached: Whether the result was served from cache
"""
object_name = request.args.get('object')
target_lang = request.args.get('lang')
if not object_name:
return jsonify({
'error': 'Missing required parameter: object',
'original': None,
'translated': None
}), 400
# Check cache first if language is specified
cached_result = None
if target_lang:
cached_result = cache.get(object_name, target_lang)
if cached_result:
# Verify cached result matches the requested object
if cached_result.get('object_name') == object_name:
cached_result['cached'] = True
return jsonify(cached_result)
else:
# Cache mismatch - clear it and continue
print(f"Cache mismatch for {object_name}: got {cached_result.get('object_name')}")
# Extract documentation
doc_data = doc_extractor.extract_doc(object_name)
if doc_data.get('error'):
return jsonify({
'error': doc_data['error'],
'original': None,
'translated': None,
'object_name': object_name
}), 404
# Always translate if language is specified (auto-translate)
translated = None
if target_lang and doc_data.get('original'):
try:
translated = translator.translate(doc_data['original'], target_lang)
if not translated:
# If translation fails, try to return original with error note
translated = None
except Exception as e:
import traceback
print(f"Translation error: {e}")
print(traceback.format_exc())
translated = None
# Prepare response
response = {
'original': doc_data['original'],
'translated': translated,
'object_name': doc_data['object_name'],
'object_type': doc_data['object_type'],
'signature': doc_data['signature'],
'error': doc_data['error'],
'cached': False
}
# Cache the result if translation was successful
if target_lang and translated:
cache.set(object_name, target_lang, response, ttl=86400) # Cache for 24 hours
return jsonify(response)
@api_bp.route('/modules', methods=['GET'])
def get_modules():
"""
Get list of available Python modules.
Query parameters:
module: Optional module name to get contents of that module
Returns:
List of available modules or module contents
"""
module_name = request.args.get('module')
if module_name:
# Get contents of specific module
contents = module_list.get_module_contents(module_name)
return jsonify({
'module': module_name,
'contents': contents
})
else:
# Get list of standard modules
modules = module_list.get_standard_modules()
builtins = module_list.get_builtin_objects()
return jsonify({
'modules': modules,
'builtins': builtins
})
@api_bp.route('/course', methods=['GET'])
def get_course():
"""
Get Python course content.
Returns:
Course structure and content
"""
scraper = CourseScraper()
course_data = scraper.scrape_course_content()
return jsonify(course_data)
@api_bp.route('/health', methods=['GET'])
def health():
"""Health check endpoint."""
return jsonify({
'status': 'healthy',
'service': 'pydoc-translation-service'
})