feat: OCR independent chunks + TMDb seed with file_uuid
- Rule 1 now creates OCR-only chunks instead of merging into ASRX - generate_seed_embeddings.py supports --file-uuid parameter - get_seeds() filters by file_uuid - identity_matcher.py uses file_uuid for seed matching - Push QDRANT_API_KEY to Python subprocesses - Face clustering uses frame+bbox matching instead of face_id - Portal uses JWT authentication - FilesView filter logic fixed
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
# Portal Development Environment
|
# Portal Development Environment
|
||||||
VITE_APP_TITLE=Momentry Portal (Development)
|
VITE_APP_TITLE=Momentry Portal (Development)
|
||||||
VITE_API_BASE_URL=http://127.0.0.1:3003
|
VITE_API_BASE_URL=http://127.0.0.1:3002
|
||||||
VITE_API_KEY=muser_68600856036340bcafc01930eb4bd839_1774418104_97221b69
|
VITE_API_KEY=muser_68600856036340bcafc01930eb4bd839_1774418104_97221b69
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ export interface UnregisterResponse {
|
|||||||
// ── Config (browser-only, stored in localStorage) ───────────────────────
|
// ── Config (browser-only, stored in localStorage) ───────────────────────
|
||||||
|
|
||||||
const DEFAULT_CONFIG: PortalConfig = {
|
const DEFAULT_CONFIG: PortalConfig = {
|
||||||
api_base_url: import.meta.env.VITE_API_BASE_URL || 'http://127.0.0.1:3003',
|
api_base_url: import.meta.env.VITE_API_BASE_URL || 'http://127.0.0.1:3002',
|
||||||
api_key: import.meta.env.VITE_API_KEY || '',
|
api_key: import.meta.env.VITE_API_KEY || '',
|
||||||
timeout_secs: 30,
|
timeout_secs: 30,
|
||||||
}
|
}
|
||||||
@@ -99,13 +99,20 @@ export function saveConfig(config: PortalConfig): void {
|
|||||||
export async function logout(): Promise<void> {
|
export async function logout(): Promise<void> {
|
||||||
try {
|
try {
|
||||||
const config = getConfig();
|
const config = getConfig();
|
||||||
|
const jwtToken = localStorage.getItem('momentry_jwt');
|
||||||
const apiKey = config.api_key || localStorage.getItem('momentry_api_key');
|
const apiKey = config.api_key || localStorage.getItem('momentry_api_key');
|
||||||
if (apiKey) {
|
if (jwtToken || apiKey) {
|
||||||
|
const headers: Record<string, string> = { 'Content-Type': 'application/json' };
|
||||||
|
if (jwtToken) {
|
||||||
|
headers['Authorization'] = `Bearer ${jwtToken}`;
|
||||||
|
} else if (apiKey) {
|
||||||
|
headers['X-API-Key'] = apiKey;
|
||||||
|
}
|
||||||
// Call logout API to invalidate session on server side (if implemented)
|
// Call logout API to invalidate session on server side (if implemented)
|
||||||
// For now, just best effort
|
// For now, just best effort
|
||||||
await fetch(`${config.api_base_url}/api/v1/auth/logout`, {
|
await fetch(`${config.api_base_url}/api/v1/auth/logout`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { 'X-API-Key': apiKey }
|
headers
|
||||||
}).catch(() => {}); // Ignore network errors
|
}).catch(() => {}); // Ignore network errors
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@@ -129,6 +136,7 @@ function handleSessionExpired() {
|
|||||||
localStorage.removeItem('momentry_user');
|
localStorage.removeItem('momentry_user');
|
||||||
localStorage.removeItem('portal_config');
|
localStorage.removeItem('portal_config');
|
||||||
localStorage.removeItem('momentry_api_key');
|
localStorage.removeItem('momentry_api_key');
|
||||||
|
localStorage.removeItem('momentry_jwt');
|
||||||
if (window.location.pathname !== '/login') {
|
if (window.location.pathname !== '/login') {
|
||||||
window.location.href = '/login';
|
window.location.href = '/login';
|
||||||
}
|
}
|
||||||
@@ -139,12 +147,15 @@ export async function httpFetch<T>(url: string, options?: RequestInit, retries =
|
|||||||
// Re-read config to ensure we have the latest key if it changed
|
// Re-read config to ensure we have the latest key if it changed
|
||||||
const config = getConfig();
|
const config = getConfig();
|
||||||
|
|
||||||
// Fallback key check
|
// Use JWT token if available, fallback to API key
|
||||||
|
const jwtToken = localStorage.getItem('momentry_jwt');
|
||||||
const apiKey = config.api_key || localStorage.getItem('momentry_api_key') || '';
|
const apiKey = config.api_key || localStorage.getItem('momentry_api_key') || '';
|
||||||
|
|
||||||
const headers = new Headers(options?.headers);
|
const headers = new Headers(options?.headers);
|
||||||
headers.set('Content-Type', 'application/json');
|
headers.set('Content-Type', 'application/json');
|
||||||
if (apiKey) {
|
if (jwtToken) {
|
||||||
|
headers.set('Authorization', `Bearer ${jwtToken}`);
|
||||||
|
} else if (apiKey) {
|
||||||
headers.set('X-API-Key', apiKey);
|
headers.set('X-API-Key', apiKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -156,7 +167,7 @@ export async function httpFetch<T>(url: string, options?: RequestInit, retries =
|
|||||||
type: 'HTTP',
|
type: 'HTTP',
|
||||||
method,
|
method,
|
||||||
url,
|
url,
|
||||||
headers: { ...headers, 'X-API-Key': apiKey ? apiKey.substring(0, 10) + '...' : 'none' },
|
headers: { ...headers, 'Authorization': jwtToken ? 'Bearer ***' : 'none', 'X-API-Key': apiKey ? apiKey.substring(0, 10) + '...' : 'none' },
|
||||||
body: options?.body ? JSON.parse(options.body as string) : null,
|
body: options?.body ? JSON.parse(options.body as string) : null,
|
||||||
status: 'loading',
|
status: 'loading',
|
||||||
data: null,
|
data: null,
|
||||||
|
|||||||
@@ -116,6 +116,9 @@ const handleLogin = async () => {
|
|||||||
if (data.success) {
|
if (data.success) {
|
||||||
localStorage.setItem('momentry_user', JSON.stringify(data.user))
|
localStorage.setItem('momentry_user', JSON.stringify(data.user))
|
||||||
localStorage.setItem('momentry_api_key', data.api_key)
|
localStorage.setItem('momentry_api_key', data.api_key)
|
||||||
|
if (data.jwt) {
|
||||||
|
localStorage.setItem('momentry_jwt', data.jwt)
|
||||||
|
}
|
||||||
saveConfig({ ...config, api_key: data.api_key })
|
saveConfig({ ...config, api_key: data.api_key })
|
||||||
const redirect = (route.query.redirect as string) || '/home'
|
const redirect = (route.query.redirect as string) || '/home'
|
||||||
router.push(redirect)
|
router.push(redirect)
|
||||||
|
|||||||
@@ -12,6 +12,9 @@ export MOMENTRY_OUTPUT_DIR=/Users/accusys/momentry/output
|
|||||||
export DATABASE_SCHEMA=public
|
export DATABASE_SCHEMA=public
|
||||||
export MOMENTRY_REDIS_PREFIX=momentry:
|
export MOMENTRY_REDIS_PREFIX=momentry:
|
||||||
export MOMENTRY_SERVER_PORT=3002
|
export MOMENTRY_SERVER_PORT=3002
|
||||||
|
# Qdrant credentials for Python subprocesses
|
||||||
|
export QDRANT_URL=http://127.0.0.1:6333
|
||||||
|
export QDRANT_API_KEY=Test3200Test3200Test3200
|
||||||
|
|
||||||
# Kill existing server on port 3002
|
# Kill existing server on port 3002
|
||||||
PID=$(lsof -ti :3002 2>/dev/null || true)
|
PID=$(lsof -ti :3002 2>/dev/null || true)
|
||||||
|
|||||||
@@ -13,6 +13,9 @@ mkdir -p logs
|
|||||||
export MOMENTRY_OUTPUT_DIR=/Users/accusys/momentry/output
|
export MOMENTRY_OUTPUT_DIR=/Users/accusys/momentry/output
|
||||||
export DATABASE_SCHEMA=public
|
export DATABASE_SCHEMA=public
|
||||||
export MOMENTRY_REDIS_PREFIX=momentry:
|
export MOMENTRY_REDIS_PREFIX=momentry:
|
||||||
|
# Qdrant credentials for Python subprocesses
|
||||||
|
export QDRANT_URL=http://127.0.0.1:6333
|
||||||
|
export QDRANT_API_KEY=Test3200Test3200Test3200
|
||||||
|
|
||||||
# Kill existing worker via PID file
|
# Kill existing worker via PID file
|
||||||
if [ -f logs/worker_3002.pid ]; then
|
if [ -f logs/worker_3002.pid ]; then
|
||||||
|
|||||||
@@ -104,9 +104,14 @@ def main():
|
|||||||
print(f"[FACE_CLUSTER] Loading embeddings from Qdrant for {UUID}...")
|
print(f"[FACE_CLUSTER] Loading embeddings from Qdrant for {UUID}...")
|
||||||
try:
|
try:
|
||||||
import requests
|
import requests
|
||||||
qdrant_url = "http://localhost:6333"
|
qdrant_url = os.environ.get("QDRANT_URL", "http://localhost:6333")
|
||||||
|
qdrant_api_key = os.environ.get("QDRANT_API_KEY", "")
|
||||||
collection = "_faces"
|
collection = "_faces"
|
||||||
|
|
||||||
|
headers = {}
|
||||||
|
if qdrant_api_key:
|
||||||
|
headers["api-key"] = qdrant_api_key
|
||||||
|
|
||||||
# Query all embeddings for this file_uuid
|
# Query all embeddings for this file_uuid
|
||||||
response = requests.post(
|
response = requests.post(
|
||||||
f"{qdrant_url}/collections/{collection}/points/scroll",
|
f"{qdrant_url}/collections/{collection}/points/scroll",
|
||||||
@@ -118,7 +123,8 @@ def main():
|
|||||||
},
|
},
|
||||||
"limit": 10000,
|
"limit": 10000,
|
||||||
"with_vector": True
|
"with_vector": True
|
||||||
}
|
},
|
||||||
|
headers=headers
|
||||||
)
|
)
|
||||||
|
|
||||||
if response.status_code == 200:
|
if response.status_code == 200:
|
||||||
@@ -140,22 +146,57 @@ def main():
|
|||||||
print(f"[FACE_CLUSTER] Failed to load embeddings from Qdrant: {e}")
|
print(f"[FACE_CLUSTER] Failed to load embeddings from Qdrant: {e}")
|
||||||
embedding_map = {}
|
embedding_map = {}
|
||||||
|
|
||||||
# Use embeddings from Qdrant or face.json
|
# Use embeddings from Qdrant - match by frame + bbox
|
||||||
embeddings = []
|
embeddings = []
|
||||||
face_refs = []
|
face_refs = []
|
||||||
|
|
||||||
print(f"🔍 Collecting face embeddings for {UUID}...")
|
print(f"🔍 Collecting face embeddings for {UUID}...")
|
||||||
|
|
||||||
|
# Build a lookup: (frame, bbox_center) -> embedding
|
||||||
|
# Use frame number and approximate bbox center for matching
|
||||||
|
qdrant_by_frame = {}
|
||||||
|
for point in points:
|
||||||
|
payload = point.get("payload", {})
|
||||||
|
frame = payload.get("frame")
|
||||||
|
bbox = payload.get("bbox", {})
|
||||||
|
vector = point.get("vector")
|
||||||
|
if frame is not None and vector:
|
||||||
|
# Use frame + bbox center as key
|
||||||
|
cx = bbox.get("x", 0) + bbox.get("width", 0) // 2
|
||||||
|
cy = bbox.get("y", 0) + bbox.get("height", 0) // 2
|
||||||
|
key = (frame, cx, cy)
|
||||||
|
if key not in qdrant_by_frame:
|
||||||
|
qdrant_by_frame[key] = vector
|
||||||
|
|
||||||
|
print(f"[FACE_CLUSTER] Built Qdrant lookup with {len(qdrant_by_frame)} entries")
|
||||||
|
|
||||||
for frame_idx, frame_obj in enumerate(frames_list):
|
for frame_idx, frame_obj in enumerate(frames_list):
|
||||||
|
frame_num = frame_obj.get("frame", frame_idx)
|
||||||
faces = frame_obj.get("faces", [])
|
faces = frame_obj.get("faces", [])
|
||||||
if not faces:
|
if not faces:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
for face_idx, face in enumerate(faces):
|
for face_idx, face in enumerate(faces):
|
||||||
face_id = face.get("face_id")
|
x = face.get("x", 0)
|
||||||
if face_id and face_id in embedding_map:
|
y = face.get("y", 0)
|
||||||
embeddings.append(embedding_map[face_id])
|
w = face.get("width", 0)
|
||||||
face_refs.append({"frame_idx": frame_idx, "face_idx": face_idx, "face_id": face_id})
|
h = face.get("height", 0)
|
||||||
|
cx = x + w // 2
|
||||||
|
cy = y + h // 2
|
||||||
|
|
||||||
|
# Try exact match first
|
||||||
|
key = (frame_num, cx, cy)
|
||||||
|
if key in qdrant_by_frame:
|
||||||
|
embeddings.append(qdrant_by_frame[key])
|
||||||
|
face_refs.append({"frame_idx": frame_idx, "face_idx": face_idx})
|
||||||
|
continue
|
||||||
|
|
||||||
|
# Try approximate match (within 50 pixels)
|
||||||
|
for (qf, qx, qy), vec in qdrant_by_frame.items():
|
||||||
|
if qf == frame_num and abs(qx - cx) < 50 and abs(qy - cy) < 50:
|
||||||
|
embeddings.append(vec)
|
||||||
|
face_refs.append({"frame_idx": frame_idx, "face_idx": face_idx})
|
||||||
|
break
|
||||||
|
|
||||||
if not embeddings:
|
if not embeddings:
|
||||||
print("❌ No embeddings found in Qdrant.")
|
print("❌ No embeddings found in Qdrant.")
|
||||||
|
|||||||
@@ -46,11 +46,12 @@ SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
|
|||||||
FACENET_PATH = os.path.join(SCRIPT_DIR, "..", "models", "facenet512.mlpackage")
|
FACENET_PATH = os.path.join(SCRIPT_DIR, "..", "models", "facenet512.mlpackage")
|
||||||
|
|
||||||
|
|
||||||
def get_tmdb_identities(limit: int = None) -> List[Dict]:
|
def get_tmdb_identities(limit: int = None, file_uuid: str = None) -> List[Dict]:
|
||||||
"""Query PG for TMDb identities with profile photos
|
"""Query PG for TMDb identities with profile photos
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
limit: Max identities to process
|
limit: Max identities to process
|
||||||
|
file_uuid: Filter by file_uuid via file_identities table
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
List of {id, uuid, name, tmdb_id, tmdb_profile}
|
List of {id, uuid, name, tmdb_id, tmdb_profile}
|
||||||
@@ -63,20 +64,34 @@ def get_tmdb_identities(limit: int = None) -> List[Dict]:
|
|||||||
|
|
||||||
if SCHEMA == "public":
|
if SCHEMA == "public":
|
||||||
table = "identities"
|
table = "identities"
|
||||||
|
file_table = "file_identities"
|
||||||
else:
|
else:
|
||||||
table = f"{SCHEMA}.identities"
|
table = f"{SCHEMA}.identities"
|
||||||
|
file_table = f"{SCHEMA}.file_identities"
|
||||||
|
|
||||||
query = f"""
|
if file_uuid:
|
||||||
SELECT id, uuid, name, tmdb_id, tmdb_profile
|
query = f"""
|
||||||
FROM {table}
|
SELECT DISTINCT i.id, i.uuid, i.name, i.tmdb_id, i.tmdb_profile
|
||||||
WHERE source = 'tmdb' AND tmdb_profile IS NOT NULL
|
FROM {table} i
|
||||||
ORDER BY id
|
JOIN {file_table} fi ON fi.identity_id = i.id
|
||||||
"""
|
WHERE i.source = 'tmdb' AND i.tmdb_profile IS NOT NULL
|
||||||
|
AND fi.file_uuid = %s
|
||||||
|
ORDER BY i.id
|
||||||
|
"""
|
||||||
|
if limit:
|
||||||
|
query += f" LIMIT {limit}"
|
||||||
|
cur.execute(query, (file_uuid,))
|
||||||
|
else:
|
||||||
|
query = f"""
|
||||||
|
SELECT id, uuid, name, tmdb_id, tmdb_profile
|
||||||
|
FROM {table}
|
||||||
|
WHERE source = 'tmdb' AND tmdb_profile IS NOT NULL
|
||||||
|
ORDER BY id
|
||||||
|
"""
|
||||||
|
if limit:
|
||||||
|
query += f" LIMIT {limit}"
|
||||||
|
cur.execute(query)
|
||||||
|
|
||||||
if limit:
|
|
||||||
query += f" LIMIT {limit}"
|
|
||||||
|
|
||||||
cur.execute(query)
|
|
||||||
rows = cur.fetchall()
|
rows = cur.fetchall()
|
||||||
cur.close()
|
cur.close()
|
||||||
conn.close()
|
conn.close()
|
||||||
@@ -180,7 +195,7 @@ def extract_face_embedding(image_path: str) -> Optional[List[float]]:
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
def generate_seed_embeddings(limit: int = None, dry_run: bool = False) -> Dict:
|
def generate_seed_embeddings(limit: int = None, dry_run: bool = False, file_uuid: str = None) -> Dict:
|
||||||
"""Generate embeddings for all TMDb identities
|
"""Generate embeddings for all TMDb identities
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@@ -198,14 +213,14 @@ def generate_seed_embeddings(limit: int = None, dry_run: bool = False) -> Dict:
|
|||||||
"errors": [],
|
"errors": [],
|
||||||
}
|
}
|
||||||
|
|
||||||
identities = get_tmdb_identities(limit)
|
identities = get_tmdb_identities(limit, file_uuid)
|
||||||
result["total"] = len(identities)
|
result["total"] = len(identities)
|
||||||
|
|
||||||
if not identities:
|
if not identities:
|
||||||
print("[SEED] No TMDb identities with profile photos")
|
print(f"[SEED] No TMDb identities with profile photos{' for ' + file_uuid if file_uuid else ''}")
|
||||||
return result
|
return result
|
||||||
|
|
||||||
print(f"[SEED] Found {len(identities)} TMDb identities")
|
print(f"[SEED] Found {len(identities)} TMDb identities{' for ' + file_uuid if file_uuid else ''}")
|
||||||
|
|
||||||
if not dry_run:
|
if not dry_run:
|
||||||
ensure_seeds_collection()
|
ensure_seeds_collection()
|
||||||
@@ -259,6 +274,7 @@ def generate_seed_embeddings(limit: int = None, dry_run: bool = False) -> Dict:
|
|||||||
name=name,
|
name=name,
|
||||||
embedding=embedding,
|
embedding=embedding,
|
||||||
source="tmdb",
|
source="tmdb",
|
||||||
|
file_uuid=file_uuid,
|
||||||
tmdb_id=tmdb_id,
|
tmdb_id=tmdb_id,
|
||||||
)
|
)
|
||||||
result["success"] += 1
|
result["success"] += 1
|
||||||
@@ -280,12 +296,13 @@ def main():
|
|||||||
parser.add_argument("--dry-run", action="store_true", help="Don't push to Qdrant")
|
parser.add_argument("--dry-run", action="store_true", help="Don't push to Qdrant")
|
||||||
parser.add_argument("--tmdb-api-key", help="TMDb API key (optional, for rate limiting)")
|
parser.add_argument("--tmdb-api-key", help="TMDb API key (optional, for rate limiting)")
|
||||||
parser.add_argument("--output", help="Output JSON file path")
|
parser.add_argument("--output", help="Output JSON file path")
|
||||||
|
parser.add_argument("--file-uuid", help="File UUID to generate seeds for")
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
if args.tmdb_api_key:
|
if args.tmdb_api_key:
|
||||||
TMDB_API_KEY = args.tmdb_api_key
|
TMDB_API_KEY = args.tmdb_api_key
|
||||||
|
|
||||||
result = generate_seed_embeddings(args.limit, args.dry_run)
|
result = generate_seed_embeddings(args.limit, args.dry_run, args.file_uuid)
|
||||||
|
|
||||||
output_json = json.dumps(result, indent=2, ensure_ascii=False)
|
output_json = json.dumps(result, indent=2, ensure_ascii=False)
|
||||||
|
|
||||||
|
|||||||
@@ -79,10 +79,10 @@ def match_faces_round_1(file_uuid: str) -> dict:
|
|||||||
{trace_id: {identity_id, identity_uuid, name, score, suggested_by: 'tmdb'}}
|
{trace_id: {identity_id, identity_uuid, name, score, suggested_by: 'tmdb'}}
|
||||||
"""
|
"""
|
||||||
traces = get_trace_representatives(file_uuid)
|
traces = get_trace_representatives(file_uuid)
|
||||||
seeds = get_seeds(source="tmdb")
|
seeds = get_seeds(source="tmdb", file_uuid=file_uuid)
|
||||||
|
|
||||||
if not seeds:
|
if not seeds:
|
||||||
print("[MATCH] No TMDb seeds available")
|
print(f"[MATCH] No TMDb seeds available for {file_uuid}")
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
suggestions = {}
|
suggestions = {}
|
||||||
|
|||||||
@@ -493,11 +493,12 @@ def push_seed_embedding(
|
|||||||
raise RuntimeError(f"Qdrant seed push failed: HTTP {e.code} - {error_body}")
|
raise RuntimeError(f"Qdrant seed push failed: HTTP {e.code} - {error_body}")
|
||||||
|
|
||||||
|
|
||||||
def get_seeds(source: str = None) -> list:
|
def get_seeds(source: str = None, file_uuid: str = None) -> list:
|
||||||
"""Get all seed points
|
"""Get all seed points
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
source: Filter by source ('tmdb', 'manual', 'propagation'), or None for all
|
source: Filter by source ('tmdb', 'manual', 'propagation'), or None for all
|
||||||
|
file_uuid: Filter by file_uuid, or None for all
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
List of seed points with payload and vector
|
List of seed points with payload and vector
|
||||||
@@ -514,12 +515,14 @@ def get_seeds(source: str = None) -> list:
|
|||||||
"with_vector": True,
|
"with_vector": True,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
filters = []
|
||||||
if source:
|
if source:
|
||||||
body["filter"] = {
|
filters.append({"key": "source", "match": {"value": source}})
|
||||||
"must": [
|
if file_uuid:
|
||||||
{"key": "source", "match": {"value": source}}
|
filters.append({"key": "file_uuid", "match": {"value": file_uuid}})
|
||||||
]
|
|
||||||
}
|
if filters:
|
||||||
|
body["filter"] = {"must": filters}
|
||||||
|
|
||||||
if offset:
|
if offset:
|
||||||
body["offset"] = offset
|
body["offset"] = offset
|
||||||
|
|||||||
@@ -309,6 +309,13 @@ impl PythonExecutor {
|
|||||||
cmd.env("DATABASE_SCHEMA", &*DATABASE_SCHEMA);
|
cmd.env("DATABASE_SCHEMA", &*DATABASE_SCHEMA);
|
||||||
cmd.env("MOMENTRY_DB_SCHEMA", &*DATABASE_SCHEMA);
|
cmd.env("MOMENTRY_DB_SCHEMA", &*DATABASE_SCHEMA);
|
||||||
cmd.env("MOMENTRY_REDIS_PREFIX", &*REDIS_KEY_PREFIX);
|
cmd.env("MOMENTRY_REDIS_PREFIX", &*REDIS_KEY_PREFIX);
|
||||||
|
// Pass Qdrant credentials to Python subprocesses
|
||||||
|
if let Ok(qdrant_url) = std::env::var("QDRANT_URL") {
|
||||||
|
cmd.env("QDRANT_URL", qdrant_url);
|
||||||
|
}
|
||||||
|
if let Ok(qdrant_api_key) = std::env::var("QDRANT_API_KEY") {
|
||||||
|
cmd.env("QDRANT_API_KEY", qdrant_api_key);
|
||||||
|
}
|
||||||
if let Some(u) = uuid {
|
if let Some(u) = uuid {
|
||||||
cmd.env("UUID", u);
|
cmd.env("UUID", u);
|
||||||
}
|
}
|
||||||
@@ -450,6 +457,13 @@ impl PythonExecutor {
|
|||||||
cmd.env("DATABASE_SCHEMA", &*DATABASE_SCHEMA);
|
cmd.env("DATABASE_SCHEMA", &*DATABASE_SCHEMA);
|
||||||
cmd.env("MOMENTRY_DB_SCHEMA", &*DATABASE_SCHEMA);
|
cmd.env("MOMENTRY_DB_SCHEMA", &*DATABASE_SCHEMA);
|
||||||
cmd.env("MOMENTRY_REDIS_PREFIX", &*REDIS_KEY_PREFIX);
|
cmd.env("MOMENTRY_REDIS_PREFIX", &*REDIS_KEY_PREFIX);
|
||||||
|
// Pass Qdrant credentials to Python subprocesses
|
||||||
|
if let Ok(qdrant_url) = std::env::var("QDRANT_URL") {
|
||||||
|
cmd.env("QDRANT_URL", qdrant_url);
|
||||||
|
}
|
||||||
|
if let Ok(qdrant_api_key) = std::env::var("QDRANT_API_KEY") {
|
||||||
|
cmd.env("QDRANT_API_KEY", qdrant_api_key);
|
||||||
|
}
|
||||||
if let Some(u) = uuid {
|
if let Some(u) = uuid {
|
||||||
cmd.env("UUID", u);
|
cmd.env("UUID", u);
|
||||||
}
|
}
|
||||||
@@ -631,6 +645,13 @@ impl PythonExecutor {
|
|||||||
cmd.env("DATABASE_SCHEMA", &*DATABASE_SCHEMA);
|
cmd.env("DATABASE_SCHEMA", &*DATABASE_SCHEMA);
|
||||||
cmd.env("MOMENTRY_DB_SCHEMA", &*DATABASE_SCHEMA);
|
cmd.env("MOMENTRY_DB_SCHEMA", &*DATABASE_SCHEMA);
|
||||||
cmd.env("MOMENTRY_REDIS_PREFIX", &*REDIS_KEY_PREFIX);
|
cmd.env("MOMENTRY_REDIS_PREFIX", &*REDIS_KEY_PREFIX);
|
||||||
|
// Pass Qdrant credentials to Python subprocesses
|
||||||
|
if let Ok(qdrant_url) = std::env::var("QDRANT_URL") {
|
||||||
|
cmd.env("QDRANT_URL", qdrant_url);
|
||||||
|
}
|
||||||
|
if let Ok(qdrant_api_key) = std::env::var("QDRANT_API_KEY") {
|
||||||
|
cmd.env("QDRANT_API_KEY", qdrant_api_key);
|
||||||
|
}
|
||||||
cmd.arg(&script_path);
|
cmd.arg(&script_path);
|
||||||
|
|
||||||
for arg in args {
|
for arg in args {
|
||||||
@@ -882,6 +903,13 @@ mod tests {
|
|||||||
cmd.env("DATABASE_SCHEMA", &*DATABASE_SCHEMA);
|
cmd.env("DATABASE_SCHEMA", &*DATABASE_SCHEMA);
|
||||||
cmd.env("MOMENTRY_DB_SCHEMA", &*DATABASE_SCHEMA);
|
cmd.env("MOMENTRY_DB_SCHEMA", &*DATABASE_SCHEMA);
|
||||||
cmd.env("MOMENTRY_REDIS_PREFIX", &*REDIS_KEY_PREFIX);
|
cmd.env("MOMENTRY_REDIS_PREFIX", &*REDIS_KEY_PREFIX);
|
||||||
|
// Pass Qdrant credentials to Python subprocesses
|
||||||
|
if let Ok(qdrant_url) = std::env::var("QDRANT_URL") {
|
||||||
|
cmd.env("QDRANT_URL", qdrant_url);
|
||||||
|
}
|
||||||
|
if let Ok(qdrant_api_key) = std::env::var("QDRANT_API_KEY") {
|
||||||
|
cmd.env("QDRANT_API_KEY", qdrant_api_key);
|
||||||
|
}
|
||||||
cmd.args([
|
cmd.args([
|
||||||
"-c",
|
"-c",
|
||||||
"import os; print(f'ENV_DATABASE_SCHEMA={os.environ.get(\"DATABASE_SCHEMA\",\"\")}'); print(f'ENV_MOMENTRY_DB_SCHEMA={os.environ.get(\"MOMENTRY_DB_SCHEMA\",\"\")}'); print(f'ENV_MOMENTRY_OUTPUT_DIR={os.environ.get(\"MOMENTRY_OUTPUT_DIR\",\"\")}'); print(f'ENV_MOMENTRY_REDIS_PREFIX={os.environ.get(\"MOMENTRY_REDIS_PREFIX\",\"\")}');",
|
"import os; print(f'ENV_DATABASE_SCHEMA={os.environ.get(\"DATABASE_SCHEMA\",\"\")}'); print(f'ENV_MOMENTRY_DB_SCHEMA={os.environ.get(\"MOMENTRY_DB_SCHEMA\",\"\")}'); print(f'ENV_MOMENTRY_OUTPUT_DIR={os.environ.get(\"MOMENTRY_OUTPUT_DIR\",\"\")}'); print(f'ENV_MOMENTRY_REDIS_PREFIX={os.environ.get(\"MOMENTRY_REDIS_PREFIX\",\"\")}');",
|
||||||
|
|||||||
Reference in New Issue
Block a user