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:
@@ -0,0 +1,3 @@
|
||||
"""svrnty-vision — sovereign vision HTTP gateway."""
|
||||
|
||||
__version__ = "0.1.0"
|
||||
@@ -0,0 +1 @@
|
||||
"""Vision endpoint routers — all 501-stubs in Phase 4a."""
|
||||
@@ -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",
|
||||
)
|
||||
@@ -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",
|
||||
)
|
||||
@@ -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",
|
||||
)
|
||||
@@ -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",
|
||||
)
|
||||
@@ -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()
|
||||
@@ -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()
|
||||
Reference in New Issue
Block a user