mirror of
https://github.com/semantica-agi/semantica.git
synced 2026-08-29 04:26:20 +00:00
Remove unreachable dead code (#1176)
* Remove unreachable dead code Delete symbols with no callers anywhere in the codebase, tests, or docs, confirmed by a repo-wide search. These are internal/private or app-layer (explorer) symbols, not part of the importable library's public API (no __all__ / package re-export), so there is no user-facing change. Removed: - poc_runner.py: parse_import_csv_row (unused nested helper) - change_management/version_storage.py: create_graph_snapshot_record - context/graph_schema.py: drop_decision_schema - explorer/dependencies.py: get_ws_manager (+ now-unused ConnectionManager import) - explorer/routes/graph.py: _extract_node_embeddings (+ stale cross-ref comment) - explorer/routes/ontology.py: ProposalState - explorer/schemas.py: ErrorResponse, TemporalSnapshotResponse, ExportResponse, StandardMessageResponse - semantic_extract/methods.py: _parse_entity_result, _parse_triplet_result - triplet_store/methods.py: _get_query_engine (+ now-unused _global_query_engine) Co-Authored-By: Vinv-AI <309466812+Vinv-AI@users.noreply.github.com> * Address review: drop now-orphaned helper and fix stale docstring - Remove _coerce_embedding_vector from explorer/routes/graph.py: its only non-recursive caller was _extract_node_embeddings (removed in this PR), so it is now dead. The live coercion logic lives in GraphSession._coerce_embedding_vector. - Update explorer/dependencies.py module docstring: it no longer injects ConnectionManager (get_ws_manager was removed); note that websocket manager access is via app.state.ws_manager. Co-Authored-By: Vinv-AI <309466812+Vinv-AI@users.noreply.github.com> * Keep public helpers with a DeprecationWarning instead of removing them create_graph_snapshot_record() and drop_decision_schema() are not underscore-prefixed, so downstream users can import them directly from their modules even though they are not re-exported from the package __init__.py. A repo search only proves there are no in-tree callers. Restore both unchanged and emit a DeprecationWarning on call, with a matching ".. deprecated::" note in each docstring pointing at the replacement. This keeps the PR non-breaking; the actual removal can happen in a future major version. The underscore-prefixed helper removals are unaffected. --------- Co-authored-by: noQbot <noQbot@users.noreply.github.com> Co-authored-by: Vinv-AI <309466812+Vinv-AI@users.noreply.github.com> Co-authored-by: noQbot <anshul@vinv.ai>
This commit is contained in:
co-authored by
noQbot
Vinv-AI
noQbot
parent
58aad80d56
commit
2f63896fb4
@@ -187,15 +187,6 @@ def poc_vuln3():
|
|||||||
})
|
})
|
||||||
return nodes
|
return nodes
|
||||||
|
|
||||||
# Simulate the CSV parser — mirrors export_import.py lines 131-133
|
|
||||||
def parse_import_csv_row(row: dict) -> dict:
|
|
||||||
"""Mirrors export_import.py CSV node ID extraction (no sanitization)."""
|
|
||||||
node_id = row.get("id") or row.get("node_id") or row.get(":ID") or row.get("_id")
|
|
||||||
return {
|
|
||||||
"id": str(node_id), # ← UNSANITIZED
|
|
||||||
"type": row.get("type", "entity"),
|
|
||||||
}
|
|
||||||
|
|
||||||
# Attack payloads
|
# Attack payloads
|
||||||
payloads = [
|
payloads = [
|
||||||
# Header injection payload (chained with VULN-1)
|
# Header injection payload (chained with VULN-1)
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ import hashlib
|
|||||||
import json
|
import json
|
||||||
import sqlite3
|
import sqlite3
|
||||||
import threading
|
import threading
|
||||||
|
import warnings
|
||||||
from abc import ABC, abstractmethod
|
from abc import ABC, abstractmethod
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
@@ -62,6 +63,12 @@ def create_graph_snapshot_record(
|
|||||||
"""
|
"""
|
||||||
Creates a standardized snapshot metadata record for a named graph.
|
Creates a standardized snapshot metadata record for a named graph.
|
||||||
|
|
||||||
|
.. deprecated::
|
||||||
|
``create_graph_snapshot_record()`` is deprecated and will be removed in
|
||||||
|
a future major version. It has no callers inside Semantica; build the
|
||||||
|
record inline and checksum it with
|
||||||
|
:func:`semantica.change_management.compute_checksum` instead.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
version_id: Unique identifier for this snapshot
|
version_id: Unique identifier for this snapshot
|
||||||
graph_uri: The underlying named graph URI in the triplet store
|
graph_uri: The underlying named graph URI in the triplet store
|
||||||
@@ -69,6 +76,13 @@ def create_graph_snapshot_record(
|
|||||||
description: Purpose or context of the snapshot
|
description: Purpose or context of the snapshot
|
||||||
metadata: Additional tags or pipeline context
|
metadata: Additional tags or pipeline context
|
||||||
"""
|
"""
|
||||||
|
warnings.warn(
|
||||||
|
"create_graph_snapshot_record() is deprecated and will be removed in a "
|
||||||
|
"future major version. Build the snapshot record inline and use "
|
||||||
|
"semantica.change_management.compute_checksum() instead.",
|
||||||
|
DeprecationWarning,
|
||||||
|
stacklevel=2,
|
||||||
|
)
|
||||||
|
|
||||||
record = {
|
record = {
|
||||||
"label": version_id,
|
"label": version_id,
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ including node labels, relationship types, and indexes for graph databases.
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import json
|
import json
|
||||||
|
import warnings
|
||||||
from typing import Dict, Any, List
|
from typing import Dict, Any, List
|
||||||
|
|
||||||
from ..graph_store import GraphStore
|
from ..graph_store import GraphStore
|
||||||
@@ -460,11 +461,25 @@ def drop_decision_schema(graph_store: GraphStore) -> None:
|
|||||||
"""
|
"""
|
||||||
Drop decision tracking schema (for cleanup/testing).
|
Drop decision tracking schema (for cleanup/testing).
|
||||||
|
|
||||||
|
.. deprecated::
|
||||||
|
``drop_decision_schema()`` is deprecated and will be removed in a future
|
||||||
|
major version. It has no callers inside Semantica; issue the DROP
|
||||||
|
CONSTRAINT / DROP INDEX / DETACH DELETE statements directly against your
|
||||||
|
:class:`~semantica.graph_store.GraphStore` instead.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
graph_store: Graph database instance
|
graph_store: Graph database instance
|
||||||
"""
|
"""
|
||||||
logger = get_logger(__name__)
|
logger = get_logger(__name__)
|
||||||
|
|
||||||
|
warnings.warn(
|
||||||
|
"drop_decision_schema() is deprecated and will be removed in a future "
|
||||||
|
"major version. Issue the DROP CONSTRAINT / DROP INDEX / DETACH DELETE "
|
||||||
|
"statements directly against your GraphStore instead.",
|
||||||
|
DeprecationWarning,
|
||||||
|
stacklevel=2,
|
||||||
|
)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# Drop constraints
|
# Drop constraints
|
||||||
constraints = [
|
constraints = [
|
||||||
|
|||||||
@@ -2,8 +2,9 @@
|
|||||||
Semantica Explorer : FastAPI Dependencies
|
Semantica Explorer : FastAPI Dependencies
|
||||||
|
|
||||||
Provides ``Depends()``-compatible callables for injecting the
|
Provides ``Depends()``-compatible callables for injecting the
|
||||||
current ``GraphSession`` and ``ConnectionManager`` into route handlers,
|
current ``GraphSession`` into route handlers, and for enforcing API-key
|
||||||
and for enforcing API-key authentication on protected routes.
|
authentication on protected routes. WebSocket manager access is handled
|
||||||
|
directly via ``app.state.ws_manager``.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import hmac
|
import hmac
|
||||||
@@ -14,7 +15,6 @@ from fastapi import Request, HTTPException, Security, status
|
|||||||
from fastapi.security.api_key import APIKeyHeader
|
from fastapi.security.api_key import APIKeyHeader
|
||||||
|
|
||||||
from .session import GraphSession
|
from .session import GraphSession
|
||||||
from .ws import ConnectionManager
|
|
||||||
|
|
||||||
_api_key_header = APIKeyHeader(name="X-API-Key", auto_error=False)
|
_api_key_header = APIKeyHeader(name="X-API-Key", auto_error=False)
|
||||||
|
|
||||||
@@ -80,13 +80,3 @@ def get_session(request: Request) -> GraphSession:
|
|||||||
detail="GraphSession not initialized."
|
detail="GraphSession not initialized."
|
||||||
)
|
)
|
||||||
return request.app.state.session
|
return request.app.state.session
|
||||||
|
|
||||||
|
|
||||||
def get_ws_manager(request: Request) -> ConnectionManager:
|
|
||||||
"""Retrieve the ConnectionManager stored on ``app.state``."""
|
|
||||||
if not hasattr(request.app.state, "ws_manager") or request.app.state.ws_manager is None:
|
|
||||||
raise HTTPException(
|
|
||||||
status_code=status.HTTP_503_SERVICE_UNAVAILABLE,
|
|
||||||
detail="WebSocket manager not initialized.",
|
|
||||||
)
|
|
||||||
return request.app.state.ws_manager
|
|
||||||
|
|||||||
@@ -78,66 +78,6 @@ def _parse_bbox(raw_bbox: Optional[str]) -> Optional[tuple[float, float, float,
|
|||||||
return min_x, min_y, max_x, max_y
|
return min_x, min_y, max_x, max_y
|
||||||
|
|
||||||
|
|
||||||
def _coerce_embedding_vector(value: object) -> Optional[List[float]]:
|
|
||||||
if isinstance(value, dict):
|
|
||||||
# Probe keys in priority order: generic first, then framework-specific.
|
|
||||||
# Must stay aligned with the top-level keys in _extract_node_embeddings.
|
|
||||||
for key in ("embedding", "embeddings", "vector", "values", "node2vec", "semantic"):
|
|
||||||
nested = _coerce_embedding_vector(value.get(key))
|
|
||||||
if nested is not None:
|
|
||||||
return nested
|
|
||||||
return None
|
|
||||||
|
|
||||||
if not isinstance(value, (list, tuple)):
|
|
||||||
return None
|
|
||||||
|
|
||||||
vector: List[float] = []
|
|
||||||
for item in value:
|
|
||||||
try:
|
|
||||||
vector.append(float(item))
|
|
||||||
except (TypeError, ValueError):
|
|
||||||
return None
|
|
||||||
|
|
||||||
return vector if vector else None
|
|
||||||
|
|
||||||
|
|
||||||
def _extract_node_embeddings(graph_dict: dict) -> dict[str, List[float]]:
|
|
||||||
"""Extract embeddings from graph dictionary."""
|
|
||||||
# Top-level keys to probe on each entity (and its metadata/properties dicts).
|
|
||||||
# Priority: generic names first, then KG-extras-specific names.
|
|
||||||
# Must stay aligned with the inner probe list in _coerce_embedding_vector.
|
|
||||||
embedding_keys = (
|
|
||||||
"embedding",
|
|
||||||
"embeddings",
|
|
||||||
"vector",
|
|
||||||
"node_embedding",
|
|
||||||
"node2vec_embedding",
|
|
||||||
"semantic_embedding",
|
|
||||||
"reasoning_embedding",
|
|
||||||
)
|
|
||||||
|
|
||||||
embeddings: dict[str, List[float]] = {}
|
|
||||||
for entity in graph_dict.get("entities") or graph_dict.get("nodes") or []:
|
|
||||||
if not isinstance(entity, dict):
|
|
||||||
continue
|
|
||||||
node_id = entity.get("id") or entity.get("node_id")
|
|
||||||
if not node_id:
|
|
||||||
continue
|
|
||||||
|
|
||||||
metadata = entity.get("metadata") if isinstance(entity.get("metadata"), dict) else {}
|
|
||||||
properties = entity.get("properties") if isinstance(entity.get("properties"), dict) else {}
|
|
||||||
|
|
||||||
for key in embedding_keys:
|
|
||||||
vector = _coerce_embedding_vector(
|
|
||||||
entity.get(key, metadata.get(key, properties.get(key)))
|
|
||||||
)
|
|
||||||
if vector is not None:
|
|
||||||
embeddings[str(node_id)] = vector
|
|
||||||
break
|
|
||||||
|
|
||||||
return embeddings
|
|
||||||
|
|
||||||
|
|
||||||
def _get_cached_embeddings(session: GraphSession) -> dict[str, List[float]]:
|
def _get_cached_embeddings(session: GraphSession) -> dict[str, List[float]]:
|
||||||
"""Get embeddings from session cache for optimal performance."""
|
"""Get embeddings from session cache for optimal performance."""
|
||||||
return session.get_cached_embeddings()
|
return session.get_cached_embeddings()
|
||||||
|
|||||||
@@ -456,10 +456,6 @@ class DraftResponse(BaseModel):
|
|||||||
updated_at: str
|
updated_at: str
|
||||||
|
|
||||||
|
|
||||||
class ProposalState(BaseModel):
|
|
||||||
state: Literal["draft", "proposed", "approved", "published", "rejected"]
|
|
||||||
|
|
||||||
|
|
||||||
class ProposalRequest(BaseModel):
|
class ProposalRequest(BaseModel):
|
||||||
draft_id: str
|
draft_id: str
|
||||||
ontology_uri: str
|
ontology_uri: str
|
||||||
|
|||||||
@@ -8,11 +8,6 @@ from typing import Any, Dict, List, Literal, Optional, Tuple
|
|||||||
from pydantic import BaseModel, Field, field_validator
|
from pydantic import BaseModel, Field, field_validator
|
||||||
|
|
||||||
|
|
||||||
class ErrorResponse(BaseModel):
|
|
||||||
detail: str
|
|
||||||
status_code: int = 500
|
|
||||||
|
|
||||||
|
|
||||||
class NodeResponse(BaseModel):
|
class NodeResponse(BaseModel):
|
||||||
id: str
|
id: str
|
||||||
type: str
|
type: str
|
||||||
@@ -187,12 +182,6 @@ class ComplianceResponse(BaseModel):
|
|||||||
violations: List[Dict[str, Any]] = Field(default_factory=list)
|
violations: List[Dict[str, Any]] = Field(default_factory=list)
|
||||||
|
|
||||||
|
|
||||||
class TemporalSnapshotResponse(BaseModel):
|
|
||||||
timestamp: str
|
|
||||||
active_nodes: List[NodeResponse]
|
|
||||||
active_node_count: int
|
|
||||||
|
|
||||||
|
|
||||||
class TemporalDiffResponse(BaseModel):
|
class TemporalDiffResponse(BaseModel):
|
||||||
from_time: str
|
from_time: str
|
||||||
to_time: str
|
to_time: str
|
||||||
@@ -256,13 +245,6 @@ class ExportRequest(BaseModel):
|
|||||||
node_ids: Optional[List[str]] = None
|
node_ids: Optional[List[str]] = None
|
||||||
|
|
||||||
|
|
||||||
class ExportResponse(BaseModel):
|
|
||||||
format: str
|
|
||||||
content_type: str
|
|
||||||
filename: str
|
|
||||||
size_bytes: int = 0
|
|
||||||
|
|
||||||
|
|
||||||
class ImportResponse(BaseModel):
|
class ImportResponse(BaseModel):
|
||||||
status: str = "success"
|
status: str = "success"
|
||||||
message: str = "Import successful"
|
message: str = "Import successful"
|
||||||
@@ -272,11 +254,6 @@ class ImportResponse(BaseModel):
|
|||||||
edges_imported: Optional[int] = None
|
edges_imported: Optional[int] = None
|
||||||
|
|
||||||
|
|
||||||
class StandardMessageResponse(BaseModel):
|
|
||||||
status: str
|
|
||||||
message: str
|
|
||||||
|
|
||||||
|
|
||||||
class AnnotationCreate(BaseModel):
|
class AnnotationCreate(BaseModel):
|
||||||
node_id: str
|
node_id: str
|
||||||
content: str
|
content: str
|
||||||
|
|||||||
@@ -1124,47 +1124,6 @@ Text to extract from:
|
|||||||
return []
|
return []
|
||||||
|
|
||||||
|
|
||||||
def _parse_entity_result(result: Any, provider: str, model: Optional[str]) -> List[Entity]:
|
|
||||||
"""Helper to parse raw LLM result into Entity objects."""
|
|
||||||
entities = []
|
|
||||||
items = []
|
|
||||||
|
|
||||||
if isinstance(result, list):
|
|
||||||
items = result
|
|
||||||
elif isinstance(result, dict):
|
|
||||||
# Handle cases where LLM wraps the list in a key
|
|
||||||
for key in ["entities", "data", "results"]:
|
|
||||||
if key in result and isinstance(result[key], list):
|
|
||||||
items = result[key]
|
|
||||||
break
|
|
||||||
if not items and "text" in result: # Single object instead of list
|
|
||||||
items = [result]
|
|
||||||
|
|
||||||
for item in items:
|
|
||||||
if not isinstance(item, dict):
|
|
||||||
continue
|
|
||||||
|
|
||||||
text = item.get("text", "")
|
|
||||||
if not text:
|
|
||||||
continue
|
|
||||||
|
|
||||||
entities.append(
|
|
||||||
Entity(
|
|
||||||
text=text,
|
|
||||||
label=item.get("label", "UNKNOWN"),
|
|
||||||
start_char=item.get("start", 0),
|
|
||||||
end_char=item.get("end", 0),
|
|
||||||
confidence=item.get("confidence", 0.9),
|
|
||||||
metadata={
|
|
||||||
"provider": provider,
|
|
||||||
"model": model,
|
|
||||||
"extraction_method": "llm",
|
|
||||||
},
|
|
||||||
)
|
|
||||||
)
|
|
||||||
return entities
|
|
||||||
|
|
||||||
|
|
||||||
def _extract_entities_chunked(
|
def _extract_entities_chunked(
|
||||||
text: str,
|
text: str,
|
||||||
provider: str,
|
provider: str,
|
||||||
@@ -2559,48 +2518,6 @@ Text to extract from:
|
|||||||
return []
|
return []
|
||||||
|
|
||||||
|
|
||||||
def _parse_triplet_result(result: Any, provider: str, model: Optional[str]) -> List[Triplet]:
|
|
||||||
"""Helper to parse raw LLM result into Triplet objects."""
|
|
||||||
triplets = []
|
|
||||||
items = []
|
|
||||||
|
|
||||||
if isinstance(result, list):
|
|
||||||
items = result
|
|
||||||
elif isinstance(result, dict):
|
|
||||||
for key in ["triplets", "data", "results"]:
|
|
||||||
if key in result and isinstance(result[key], list):
|
|
||||||
items = result[key]
|
|
||||||
break
|
|
||||||
if not items and "subject" in result:
|
|
||||||
items = [result]
|
|
||||||
|
|
||||||
for item in items:
|
|
||||||
if not isinstance(item, dict):
|
|
||||||
continue
|
|
||||||
|
|
||||||
subject = item.get("subject", "")
|
|
||||||
predicate = item.get("predicate", "")
|
|
||||||
obj = item.get("object", "")
|
|
||||||
|
|
||||||
if not subject or not predicate or not obj:
|
|
||||||
continue
|
|
||||||
|
|
||||||
triplets.append(
|
|
||||||
Triplet(
|
|
||||||
subject=str(subject),
|
|
||||||
predicate=str(predicate),
|
|
||||||
object=str(obj),
|
|
||||||
confidence=item.get("confidence", 0.9),
|
|
||||||
metadata={
|
|
||||||
"provider": provider,
|
|
||||||
"model": model,
|
|
||||||
"extraction_method": "llm",
|
|
||||||
},
|
|
||||||
)
|
|
||||||
)
|
|
||||||
return triplets
|
|
||||||
|
|
||||||
|
|
||||||
def _extract_triplets_chunked(
|
def _extract_triplets_chunked(
|
||||||
text: str,
|
text: str,
|
||||||
provider: str,
|
provider: str,
|
||||||
|
|||||||
@@ -101,7 +101,6 @@ from .triplet_store import TripletStore
|
|||||||
# Global store registry
|
# Global store registry
|
||||||
_global_stores: Dict[str, TripletStore] = {}
|
_global_stores: Dict[str, TripletStore] = {}
|
||||||
_default_store_id: Optional[str] = None
|
_default_store_id: Optional[str] = None
|
||||||
_global_query_engine: Optional[QueryEngine] = None
|
|
||||||
_global_bulk_loader: Optional[BulkLoader] = None
|
_global_bulk_loader: Optional[BulkLoader] = None
|
||||||
|
|
||||||
|
|
||||||
@@ -131,25 +130,6 @@ def _get_store(store_id: Optional[str] = None) -> TripletStore:
|
|||||||
return _global_stores[target_id]
|
return _global_stores[target_id]
|
||||||
|
|
||||||
|
|
||||||
def _get_query_engine() -> QueryEngine:
|
|
||||||
"""Get or create global QueryEngine instance."""
|
|
||||||
global _global_query_engine
|
|
||||||
if _global_query_engine is None:
|
|
||||||
# We need a store backend for the engine, but QueryEngine in this module
|
|
||||||
# seems to be initialized with config in the old code.
|
|
||||||
# In the new code, TripletStore has its own query_engine.
|
|
||||||
# If we use this standalone function, we might need to rely on the store's engine.
|
|
||||||
# But let's keep a standalone one if needed, or better, delegate to store.
|
|
||||||
config = triplet_store_config.get_all()
|
|
||||||
# QueryEngine now expects a backend, but we can initialize it without one
|
|
||||||
# if we pass the backend at execution time?
|
|
||||||
# Checking QueryEngine implementation... it takes `store_backend` in __init__.
|
|
||||||
# So we can't easily have a global one without a store.
|
|
||||||
# We'll rely on the store's engine.
|
|
||||||
pass
|
|
||||||
return None # Deprecated use of global engine
|
|
||||||
|
|
||||||
|
|
||||||
def _get_bulk_loader() -> BulkLoader:
|
def _get_bulk_loader() -> BulkLoader:
|
||||||
"""Get or create global BulkLoader instance."""
|
"""Get or create global BulkLoader instance."""
|
||||||
global _global_bulk_loader
|
global _global_bulk_loader
|
||||||
|
|||||||
Reference in New Issue
Block a user