Files
platform/gateway/responses.py
Yusuf Suleman 8275f3a71b feat: brain service — self-contained second brain knowledge manager
Full backend service with:
- FastAPI REST API with CRUD, search, reprocess endpoints
- PostgreSQL + pgvector for items and semantic search
- Redis + RQ for background job processing
- Meilisearch for fast keyword/filter search
- Browserless/Chrome for JS rendering and screenshots
- OpenAI structured output for AI classification
- Local file storage with S3-ready abstraction
- Gateway auth via X-Gateway-User-Id header
- Own docker-compose stack (6 containers)

Classification: fixed folders (Home/Family/Work/Travel/Knowledge/Faith/Projects)
and fixed tags (28 predefined). AI assigns exactly 1 folder, 2-3 tags, title,
summary, and confidence score per item.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 11:48:29 -05:00

52 lines
1.7 KiB
Python

"""
Platform Gateway — Response helpers mixed into GatewayHandler.
"""
import json
from http.cookies import SimpleCookie
from config import SESSION_MAX_AGE, DEV_AUTO_LOGIN
from sessions import get_session_user, get_or_create_dev_user
class ResponseMixin:
"""Mixin providing response helpers for GatewayHandler."""
def _send_json(self, data, status=200):
body = json.dumps(data).encode()
self.send_response(status)
self.send_header("Content-Type", "application/json")
self.send_header("Content-Length", len(body))
self.end_headers()
self.wfile.write(body)
def _get_session_token(self):
cookie = SimpleCookie(self.headers.get("Cookie", ""))
if "platform_session" in cookie:
return cookie["platform_session"].value
auth = self.headers.get("Authorization", "")
if auth.startswith("Bearer "):
return auth[7:]
return None
def _get_user(self):
if DEV_AUTO_LOGIN and self.headers.get("X-Dev-Auto-Login") == "1":
return get_or_create_dev_user()
token = self._get_session_token()
return get_session_user(token)
def _require_auth(self):
user = self._get_user()
if not user:
self._send_json({"error": "Unauthorized"}, 401)
return None
return user
def _set_session_cookie(self, token):
self.send_header("Set-Cookie",
f"platform_session={token}; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age={SESSION_MAX_AGE}")
def _read_body(self):
length = int(self.headers.get("Content-Length", 0))
return self.rfile.read(length) if length > 0 else b""