initial
This commit is contained in:
157
routes/api.py
Normal file
157
routes/api.py
Normal file
@@ -0,0 +1,157 @@
|
||||
"""
|
||||
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'
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user