Files
kjvstudy.org/kjvstudy_org/routes/timeline.py
kennethreitz bab27364fc Integrate turboAPI as FastAPI replacement for Zig-powered HTTP performance
Replace FastAPI with turboAPI across the entire codebase:
- Swap all imports from fastapi to turboapi (TurboAPI, APIRouter, HTTPException, etc.)
- Keep starlette imports for Jinja2Templates and StaticFiles (not yet in turboapi)
- Remove unsupported `example=` params from Query/Path declarations
- Update entry point to use turboapi's native server (app.run())
- Update test clients to use turboapi.testclient.TestClient

The app loads successfully with all 200+ routes registered. turboAPI's
Zig HTTP core provides significant throughput improvements over uvicorn.

Note: turboAPI's TestClient has limited support for Request injection
and Query defaults, causing some test failures. The actual server
runtime handles these correctly.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 00:38:03 -04:00

116 lines
3.9 KiB
Python

"""Biblical timeline routes."""
import json
from pathlib import Path
from turboapi import APIRouter, HTTPException, Request
from turboapi import HTMLResponse, StreamingResponse
from starlette.templating import Jinja2Templates
from ..kjv import bible
from ..utils.pdf import WEASYPRINT_AVAILABLE, render_html_to_pdf_async
router = APIRouter()
templates = None
def init_templates(t: Jinja2Templates):
"""Initialize templates for timeline routes."""
global templates
templates = t
# =============================================================================
# Helper Functions
# =============================================================================
# Cache timeline data at module level
_TIMELINE_CACHE: dict | None = None
def _load_timeline_data() -> dict:
"""Load timeline data from JSON file (internal, uncached)."""
data_dir = Path(__file__).parent.parent / "data"
timeline_path = data_dir / "biblical_timeline.json"
with open(timeline_path, 'r', encoding='utf-8') as f:
return json.load(f)
def get_biblical_timeline_context():
"""
Load comprehensive biblical timeline data from JSON file (cached).
Returns tuple of (timeline_events, introduction, chronology_note, chronology_comparison, conclusion)
"""
global _TIMELINE_CACHE
if _TIMELINE_CACHE is None:
_TIMELINE_CACHE = _load_timeline_data()
timeline_events = _TIMELINE_CACHE.get("timeline_events", {})
introduction = _TIMELINE_CACHE.get("introduction", "")
chronology_note = _TIMELINE_CACHE.get("chronology_note", "")
chronology_comparison = _TIMELINE_CACHE.get("chronology_comparison", [])
conclusion = _TIMELINE_CACHE.get("conclusion", "")
return timeline_events, introduction, chronology_note, chronology_comparison, conclusion
# =============================================================================
# Routes
# =============================================================================
@router.get("/biblical-timeline", response_class=HTMLResponse)
async def biblical_timeline_page(request: Request):
"""Biblical timeline page showing major biblical events chronologically"""
books = bible.get_books()
timeline_events, introduction, chronology_note, chronology_comparison, conclusion = get_biblical_timeline_context()
breadcrumbs = [
{"text": "Home", "url": "/"},
{"text": "Resources", "url": "/resources"},
{"text": "Biblical Timeline", "url": None}
]
return templates.TemplateResponse(
request,
"biblical_timeline.html",
{
"books": books,
"timeline_events": timeline_events,
"introduction": introduction,
"chronology_note": chronology_note,
"chronology_comparison": chronology_comparison,
"conclusion": conclusion,
"breadcrumbs": breadcrumbs,
"pdf_available": WEASYPRINT_AVAILABLE
}
)
@router.get("/biblical-timeline/pdf")
async def biblical_timeline_pdf():
"""Generate PDF export for the biblical timeline."""
if not WEASYPRINT_AVAILABLE:
raise HTTPException(
status_code=503,
detail="PDF generation is not available. WeasyPrint system libraries are not installed."
)
timeline_events, introduction, chronology_note, chronology_comparison, conclusion = get_biblical_timeline_context()
html_content = templates.get_template("biblical_timeline_pdf.html").render(
timeline_events=timeline_events,
introduction=introduction,
chronology_note=chronology_note,
chronology_comparison=chronology_comparison,
conclusion=conclusion
)
pdf_buffer = await render_html_to_pdf_async(html_content)
return StreamingResponse(
pdf_buffer,
media_type="application/pdf",
headers={"Content-Disposition": "attachment; filename=biblical-timeline.pdf"}
)