100 lines
3.6 KiB
Python
100 lines
3.6 KiB
Python
|
|
"""Authenticated catalog endpoints; writes inherit the application origin guard."""
|
||
|
|
|
||
|
|
from typing import Annotated
|
||
|
|
|
||
|
|
from fastapi import APIRouter, Depends, Query, Request
|
||
|
|
|
||
|
|
from ..schemas import JobOutput
|
||
|
|
from ..security import require_auth
|
||
|
|
from .contracts import (
|
||
|
|
UNIVERSES,
|
||
|
|
CatalogFilters,
|
||
|
|
CatalogJobInput,
|
||
|
|
CatalogPage,
|
||
|
|
CollectionOutput,
|
||
|
|
EntryOutput,
|
||
|
|
InputOutput,
|
||
|
|
InputPreparation,
|
||
|
|
NoteInput,
|
||
|
|
NoteOutput,
|
||
|
|
Scope,
|
||
|
|
)
|
||
|
|
from .service import Catalog
|
||
|
|
|
||
|
|
router = APIRouter(prefix="/api/v1/catalog", tags=["catalog"], dependencies=[Depends(require_auth)])
|
||
|
|
|
||
|
|
|
||
|
|
@router.get("/scopes")
|
||
|
|
async def scopes() -> dict[str, list[str]]:
|
||
|
|
return UNIVERSES
|
||
|
|
|
||
|
|
|
||
|
|
@router.get("/datasets", response_model=CatalogPage)
|
||
|
|
async def datasets(request: Request, filters: Annotated[CatalogFilters, Query()]):
|
||
|
|
async with request.app.state.sessions() as db:
|
||
|
|
return await Catalog(db).search(filters)
|
||
|
|
|
||
|
|
|
||
|
|
@router.get("/datasets/{dataset_id}", response_model=EntryOutput)
|
||
|
|
async def detail(request: Request, dataset_id: str, scope: Annotated[Scope, Query()]):
|
||
|
|
async with request.app.state.sessions() as db:
|
||
|
|
return await Catalog(db).detail(scope, dataset_id)
|
||
|
|
|
||
|
|
|
||
|
|
@router.get("/datasets/{dataset_id}/fields", response_model=CatalogPage)
|
||
|
|
async def fields(request: Request, dataset_id: str, filters: Annotated[CatalogFilters, Query()]):
|
||
|
|
async with request.app.state.sessions() as db:
|
||
|
|
return await Catalog(db).search(filters, dataset_id)
|
||
|
|
|
||
|
|
|
||
|
|
@router.get("/datasets/{dataset_id}/fields/{field_id}", response_model=EntryOutput)
|
||
|
|
async def field(request: Request, dataset_id: str, field_id: str, scope: Annotated[Scope, Query()]):
|
||
|
|
async with request.app.state.sessions() as db:
|
||
|
|
return await Catalog(db).detail(scope, dataset_id, field_id)
|
||
|
|
|
||
|
|
|
||
|
|
@router.patch("/datasets/{dataset_id}/research", response_model=NoteOutput)
|
||
|
|
async def note(request: Request, dataset_id: str, scope: Annotated[Scope, Query()], body: NoteInput):
|
||
|
|
async with request.app.state.sessions.begin() as db:
|
||
|
|
return await Catalog(db).save_note(scope, dataset_id, "", body)
|
||
|
|
|
||
|
|
|
||
|
|
@router.patch("/datasets/{dataset_id}/fields/{field_id}/research", response_model=NoteOutput)
|
||
|
|
async def field_note(
|
||
|
|
request: Request, dataset_id: str, field_id: str, scope: Annotated[Scope, Query()], body: NoteInput
|
||
|
|
):
|
||
|
|
async with request.app.state.sessions.begin() as db:
|
||
|
|
return await Catalog(db).save_note(scope, dataset_id, field_id, body)
|
||
|
|
|
||
|
|
|
||
|
|
@router.post("/sync-jobs", status_code=202, response_model=JobOutput)
|
||
|
|
async def sync(request: Request, body: CatalogJobInput):
|
||
|
|
async with request.app.state.sessions.begin() as db:
|
||
|
|
result = await Catalog(db).create_job(body)
|
||
|
|
request.app.state.runner.wake.set()
|
||
|
|
return result
|
||
|
|
|
||
|
|
|
||
|
|
@router.post("/inputs", status_code=201, response_model=InputOutput)
|
||
|
|
async def prepare(request: Request, body: InputPreparation):
|
||
|
|
async with request.app.state.sessions.begin() as db:
|
||
|
|
return await Catalog(db).prepare(body)
|
||
|
|
|
||
|
|
|
||
|
|
@router.get("/inputs", response_model=list[InputOutput])
|
||
|
|
async def inputs(request: Request, scope: Annotated[Scope, Query()]):
|
||
|
|
async with request.app.state.sessions() as db:
|
||
|
|
return await Catalog(db).inputs(scope)
|
||
|
|
|
||
|
|
|
||
|
|
@router.get("/inputs/{input_id}", response_model=InputOutput)
|
||
|
|
async def get_input(request: Request, input_id: str):
|
||
|
|
async with request.app.state.sessions() as db:
|
||
|
|
return await Catalog(db).input(input_id)
|
||
|
|
|
||
|
|
|
||
|
|
@router.get("/datasets/{dataset_id}/collection", response_model=CollectionOutput)
|
||
|
|
async def collection(request: Request, dataset_id: str, scope: Annotated[Scope, Query()]):
|
||
|
|
async with request.app.state.sessions() as db:
|
||
|
|
return await Catalog(db).collection(scope, dataset_id)
|