diff --git a/app/__init__.py b/app/__init__.py new file mode 100644 index 0000000..06d7405 Binary files /dev/null and b/app/__init__.py differ diff --git a/app/config.py b/app/config.py new file mode 100644 index 0000000..5452a90 --- /dev/null +++ b/app/config.py @@ -0,0 +1,20 @@ + +from __future__ import annotations +import os +from functools import lru_cache + +class Settings: + # Qdrant + QDRANT_URL: str = os.getenv("QDRANT_URL", "http://127.0.0.1:6333") + QDRANT_API_KEY: str | None = os.getenv("QDRANT_API_KEY") + COLLECTION_PREFIX: str = os.getenv("MINDNET_PREFIX", "mindnet") + VECTOR_SIZE: int = int(os.getenv("MINDNET_VECTOR_SIZE", "384")) + DISTANCE: str = os.getenv("MINDNET_DISTANCE", "Cosine") + # Embeddings + MODEL_NAME: str = os.getenv("MINDNET_MODEL", "sentence-transformers/all-MiniLM-L6-v2") + # API + DEBUG: bool = os.getenv("DEBUG", "false").lower() == "true" + +@lru_cache +def get_settings() -> Settings: + return Settings() diff --git a/app/embeddings.py b/app/embeddings.py new file mode 100644 index 0000000..2f23562 --- /dev/null +++ b/app/embeddings.py @@ -0,0 +1,22 @@ + +from __future__ import annotations +from typing import List +from functools import lru_cache + +from .config import get_settings + +# Lazy import so startup stays fast +@lru_cache +def _load_model(): + from sentence_transformers import SentenceTransformer + settings = get_settings() + model = SentenceTransformer(settings.MODEL_NAME, device="cpu") + return model + +def embed_texts(texts: List[str]) -> list[list[float]]: + model = _load_model() + # Normalize to list of str + texts = [t if isinstance(t, str) else str(t) for t in texts] + vecs = model.encode(texts, normalize_embeddings=True, convert_to_numpy=False) + # Ensure pure-python list of floats + return [list(map(float, v)) for v in vecs] diff --git a/app/main.py b/app/main.py new file mode 100644 index 0000000..0098913 --- /dev/null +++ b/app/main.py @@ -0,0 +1,18 @@ + +from __future__ import annotations +from fastapi import FastAPI +from .config import get_settings +from .routers.embed_router import router as embed_router +from .routers.qdrant_router import router as qdrant_router + +def create_app() -> FastAPI: + app = FastAPI(title="mindnet API", version="0.1.0") + s = get_settings() + @app.get("/healthz") + def healthz(): + return {"status": "ok", "qdrant": s.QDRANT_URL, "prefix": s.COLLECTION_PREFIX} + app.include_router(embed_router) + app.include_router(qdrant_router) + return app + +app = create_app()