mirror of
https://github.com/migatu/astrololo.git
synced 2026-07-14 21:38:37 +00:00
16d35c16dc
Trzy niezależne usługi FastAPI komunikujące się przez HTTP/JSON, każda zna tylko adres warstwy bezpośrednio pod nią: - presentation (:8000) — strona WWW + formularz - logic (:8001) — reguły biznesowe, pośrednik - data (:8002) — wyszukiwanie danych za interfejsem DataProvider Warstwa danych: czytanie setek plików .xlsx z wykrywaniem nagłówka i mapowaniem układu kolumn na schemat kanoniczny, z 4-poziomowym cache (schemat L1, Parquet L2, wyniki zapytań L3, odwrócony indeks L4) i unieważnianiem po odcisku pliku. Gotowa ścieżka migracji do SQL (ingest/to_sql.py + SqlDataProvider, przełączane przez DATA_PROVIDER). Zawiera docker-compose, Makefile, generator danych przykładowych. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
47 lines
1.5 KiB
Python
47 lines
1.5 KiB
Python
"""Warstwa PREZENTACJI — usługa HTTP serwująca stronę WWW.
|
|
|
|
W dół: przekazuje dane z formularza do warstwy logicznej i odbiera opracowane
|
|
wyniki. Nie zawiera logiki biznesowej ani dostępu do danych — tylko UI.
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
import httpx
|
|
from fastapi import FastAPI, Form, Request
|
|
from fastapi.responses import HTMLResponse
|
|
from fastapi.staticfiles import StaticFiles
|
|
from fastapi.templating import Jinja2Templates
|
|
|
|
from app.clients.logic_client import LogicClient
|
|
|
|
app = FastAPI(title="astrololo · warstwa prezentacji")
|
|
app.mount("/static", StaticFiles(directory="app/static"), name="static")
|
|
templates = Jinja2Templates(directory="app/templates")
|
|
logic = LogicClient()
|
|
|
|
|
|
@app.get("/", response_class=HTMLResponse)
|
|
def index(request: Request):
|
|
return templates.TemplateResponse(request, "index.html", {"result": None, "form": {}})
|
|
|
|
|
|
@app.post("/", response_class=HTMLResponse)
|
|
def search(
|
|
request: Request,
|
|
query: str = Form(...),
|
|
field: str = Form("name"),
|
|
exact: bool = Form(False),
|
|
limit: int = Form(25),
|
|
):
|
|
form = {"query": query, "field": field, "exact": exact, "limit": limit}
|
|
ctx: dict = {"form": form, "result": None, "error": None}
|
|
try:
|
|
ctx["result"] = logic.query(query=query, field=field, exact=exact, limit=limit)
|
|
except httpx.HTTPError as e:
|
|
ctx["error"] = f"Warstwa logiczna niedostępna: {e}"
|
|
return templates.TemplateResponse(request, "index.html", ctx)
|
|
|
|
|
|
@app.get("/health")
|
|
def health() -> dict:
|
|
return {"status": "ok", "layer": "presentation"}
|