idea198-civicswarm-privacy-.../civicswarm/api.py

82 lines
2.6 KiB
Python

from __future__ import annotations
from pathlib import Path
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel, Field
from .service import CivicSwarmService
class ProposalCreate(BaseModel):
city: str
title: str
body: str
geography: str = ""
tags: list[str] = Field(default_factory=list)
class ResidentCreate(BaseModel):
resident_key: str
geography: str = ""
interests: list[str] = Field(default_factory=list)
lived_experience: list[str] = Field(default_factory=list)
languages: list[str] = Field(default_factory=list)
class CommentCreate(BaseModel):
text: str
channel: str = "mobile"
resident_key: str | None = None
geography: str = ""
metadata: dict = Field(default_factory=dict)
class PreferenceCreate(BaseModel):
resident_key: str
score: float
channel: str = "mobile"
def create_app(db_path: str | Path = ":memory:") -> FastAPI:
service = CivicSwarmService.from_path(db_path)
app = FastAPI(title="CivicSwarm", version="0.1.0")
app.state.service = service
@app.post("/proposals")
def create_proposal(payload: ProposalCreate):
return service.create_proposal(payload.city, payload.title, payload.body, payload.geography, payload.tags)
@app.post("/residents")
def create_resident(payload: ResidentCreate):
return service.register_resident(payload.resident_key, payload.geography, payload.interests, payload.lived_experience, payload.languages)
@app.post("/proposals/{proposal_id}/comments")
def create_comment(proposal_id: int, payload: CommentCreate):
try:
return service.add_comment(proposal_id, payload.text, payload.channel, payload.resident_key, payload.geography, payload.metadata)
except KeyError as exc:
raise HTTPException(status_code=404, detail=str(exc)) from exc
@app.post("/proposals/{proposal_id}/preferences")
def create_preference(proposal_id: int, payload: PreferenceCreate):
return service.submit_preference(proposal_id, payload.resident_key, payload.score, payload.channel)
@app.get("/proposals/{proposal_id}/route")
def route_proposal(proposal_id: int, top_n: int = 3):
return service.route_proposal(proposal_id, top_n=top_n)
@app.get("/proposals/{proposal_id}/dashboard")
def dashboard(proposal_id: int):
return service.build_dashboard(proposal_id)
@app.get("/proposals/{proposal_id}/brief")
def brief(proposal_id: int):
return service.export_brief(proposal_id)
@app.get("/proposals/{proposal_id}/ledger")
def ledger(proposal_id: int):
return service.list_ledger(proposal_id)
return app