Ryan Malloy 33787e03da Fix ruff lint, Pyright type ambiguity, and MCP tool SQL queries
- Fix 28 ruff errors: E501 line length, B904 raise-from, F401 unused import
- Fix SQLAlchemy Row.count() ambiguity with tuple indexing (Pyright)
- Replace composite column notation with accessor functions in MCP tools
  (topocentric/equatorial/pass_event are C-level base types, not composites)
- Fix satellite_pass: use time window (start + end) not count parameter
  to match predict_passes(tle, observer, start_ts, end_ts, min_el) signature
2026-03-01 16:41:07 -07:00

77 lines
2.2 KiB
Python

from fastapi import APIRouter, Depends, Query
from sqlalchemy import func, select
from sqlalchemy.ext.asyncio import AsyncSession
from orrery_search.db import get_db
from orrery_search.models.document import Document
from orrery_search.schemas.search import (
SearchResponse,
SearchResult,
SectionCount,
SectionsResponse,
)
from orrery_search.services.search import search_documents
router = APIRouter()
@router.get("", response_model=SearchResponse)
async def search(
q: str = Query(..., min_length=1, max_length=500),
content_type: str | None = Query(None, description="Filter by content type"),
section: str | None = Query(
None, max_length=200, description="Section prefix filter"
),
limit: int = Query(10, ge=1, le=50),
mode: str = Query("hybrid", pattern="^(hybrid|semantic|text)$"),
db: AsyncSession = Depends(get_db),
):
"""Search pg_orrery documentation using semantic and/or text matching."""
output = await search_documents(
q=q,
db=db,
mode=mode,
content_type=content_type,
section=section,
limit=limit,
)
return SearchResponse(
query=output.query,
results=[
SearchResult(
title=r.title,
slug=r.slug,
section=r.section,
content_type=r.content_type,
description=r.description,
snippet=r.snippet,
url=r.url,
score=r.score,
source=r.source,
)
for r in output.results
],
count=output.count,
mode=output.mode,
)
@router.get("/sections", response_model=SectionsResponse)
async def list_sections(
db: AsyncSession = Depends(get_db),
):
"""List all sections with document counts for the filter UI."""
stmt = (
select(Document.section, func.count(Document.id).label("count"))
.group_by(Document.section)
.order_by(Document.section)
)
result = await db.execute(stmt)
sections = [
SectionCount(section=row[0], count=row[1])
for row in result
if row[0]
]
return SectionsResponse(sections=sections)