feat: initial scaffold — FastAPI shell + stub vision routers

Phase 4a of the BTE refactor (audit 2026-05-24 §3 V). svrnty-vision is a
sovereign HTTP gateway in front of four vision capabilities — VLM (Spark 2
Qwen3-VL), FLUX image gen (Spark 1 ComfyUI), palette extraction, and
background removal. This commit lays only the scaffold: FastAPI app,
/healthz, four 501-stub routers, pydantic-settings config, pytest smoke.

Real implementations land in Phase 4b. BTE code is untouched in 4a.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Svrnty
2026-05-24 13:25:57 -04:00
commit 2a90c3f884
15 changed files with 416 additions and 0 deletions
+3
View File
@@ -0,0 +1,3 @@
"""svrnty-vision — sovereign vision HTTP gateway."""
__version__ = "0.1.0"
+1
View File
@@ -0,0 +1 @@
"""Vision endpoint routers — all 501-stubs in Phase 4a."""
+17
View File
@@ -0,0 +1,17 @@
"""FLUX image generation — stub until Phase 4b wires the ComfyUI HTTP client."""
from fastapi import APIRouter, HTTPException, status
router = APIRouter(prefix="/flux", tags=["flux"])
@router.post("/render")
async def render() -> None:
"""Render an image via Spark 1 (FLUX on ComfyUI).
Phase 4a: stub. Phase 4b: proxies to Spark 1 ComfyUI workflow.
"""
raise HTTPException(
status_code=status.HTTP_501_NOT_IMPLEMENTED,
detail="flux.render not implemented in Phase 4a — see BTE-REFACTOR-EXECUTION-PLAN Phase 4b",
)
+17
View File
@@ -0,0 +1,17 @@
"""Palette extraction (ColorThief-equivalent) — stub until Phase 4b."""
from fastapi import APIRouter, HTTPException, status
router = APIRouter(prefix="/palette", tags=["palette"])
@router.post("/extract")
async def extract() -> None:
"""Extract a dominant-color palette from an image.
Phase 4a: stub. Phase 4b: runs in-process (Pillow + colorthief).
"""
raise HTTPException(
status_code=status.HTTP_501_NOT_IMPLEMENTED,
detail="palette.extract not implemented in Phase 4a — see BTE-REFACTOR-EXECUTION-PLAN Phase 4b",
)
+17
View File
@@ -0,0 +1,17 @@
"""Background removal — stub until Phase 4b."""
from fastapi import APIRouter, HTTPException, status
router = APIRouter(prefix="/rembg", tags=["rembg"])
@router.post("/cutout")
async def cutout() -> None:
"""Remove the background of an image (alpha cutout).
Phase 4a: stub. Phase 4b: runs in-process (rembg) or proxies to a Spark service.
"""
raise HTTPException(
status_code=status.HTTP_501_NOT_IMPLEMENTED,
detail="rembg.cutout not implemented in Phase 4a — see BTE-REFACTOR-EXECUTION-PLAN Phase 4b",
)
+17
View File
@@ -0,0 +1,17 @@
"""VLM (vision-language model) analysis — stub until Phase 4b moves Qwen3-VL code."""
from fastapi import APIRouter, HTTPException, status
router = APIRouter(prefix="/vlm", tags=["vlm"])
@router.post("/analyze")
async def analyze() -> None:
"""Analyze an image with a vision-language model.
Phase 4a: stub. Phase 4b: proxies to Spark 2 (Qwen3-VL via vLLM).
"""
raise HTTPException(
status_code=status.HTTP_501_NOT_IMPLEMENTED,
detail="vlm.analyze not implemented in Phase 4a — see BTE-REFACTOR-EXECUTION-PLAN Phase 4b",
)
+40
View File
@@ -0,0 +1,40 @@
"""FastAPI application entry point."""
from fastapi import FastAPI
from svrnty_vision import __version__
from svrnty_vision.routers import flux, palette, rembg, vlm
app = FastAPI(
title="svrnty-vision",
version=__version__,
description="Sovereign vision HTTP gateway — VLM, FLUX, palette, rembg.",
)
app.include_router(vlm.router)
app.include_router(flux.router)
app.include_router(palette.router)
app.include_router(rembg.router)
@app.get("/healthz")
async def healthz() -> dict[str, str]:
"""Liveness probe."""
return {"status": "ok", "version": __version__}
def main() -> None:
"""Run with `python -m svrnty_vision.server`."""
import uvicorn
from svrnty_vision.settings import settings
uvicorn.run(
"svrnty_vision.server:app",
host=settings.svrnty_vision_host,
port=settings.svrnty_vision_port,
)
if __name__ == "__main__":
main()
+30
View File
@@ -0,0 +1,30 @@
"""Settings loaded from environment / .env."""
from pydantic_settings import BaseSettings, SettingsConfigDict
class Settings(BaseSettings):
"""Runtime configuration for svrnty-vision."""
model_config = SettingsConfigDict(
env_file=".env",
env_file_encoding="utf-8",
extra="ignore",
)
# Server
svrnty_vision_host: str = "0.0.0.0"
svrnty_vision_port: int = 8090
# Spark 1 — FLUX (ComfyUI)
spark1_flux_url: str = "http://spark1.lan:8188"
# Spark 2 — Qwen3-VL (vLLM, OpenAI-compatible)
spark2_vlm_url: str = "http://spark2.lan:8000"
spark2_vlm_model: str = "Qwen/Qwen3-VL-7B-Instruct"
# Common
vision_request_timeout_seconds: int = 120
settings = Settings()