prismlib-plus 0.7.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. prism/__init__.py +9 -0
  2. prism/api/__init__.py +83 -0
  3. prism/api/auth.py +127 -0
  4. prism/api/consumer.py +573 -0
  5. prism/api/integrations/__init__.py +30 -0
  6. prism/api/integrations/langgraph.py +382 -0
  7. prism/api/mcp.py +341 -0
  8. prism/api/multi_provider.py +315 -0
  9. prism/api/provider.py +496 -0
  10. prism/api/schema.py +296 -0
  11. prism/bridge/__init__.py +32 -0
  12. prism/bridge/vector.py +704 -0
  13. prism/cache/__init__.py +54 -0
  14. prism/cache/cache.py +637 -0
  15. prism/cache/embedder.py +438 -0
  16. prism/cache/metrics.py +273 -0
  17. prism/cache/store.py +370 -0
  18. prism/cluster/__init__.py +20 -0
  19. prism/cluster/alerts.py +550 -0
  20. prism/cluster/cache.py +480 -0
  21. prism/cluster/health.py +87 -0
  22. prism/cluster/node.py +288 -0
  23. prism/cluster/transport.py +81 -0
  24. prism/enterprise/__init__.py +5 -0
  25. prism/enterprise/app.py +70 -0
  26. prism/ffi/__init__.py +34 -0
  27. prism/ffi/bindings.py +1055 -0
  28. prism/ffi/grpc_client.py +121 -0
  29. prism/lib/__init__.py +17 -0
  30. prism/lib/fabric.py +1141 -0
  31. prism/lib/lang.py +531 -0
  32. prism/lib/resonance.py +691 -0
  33. prism/observability/__init__.py +110 -0
  34. prism/observability/otel.py +85 -0
  35. prism/observability/prometheus.py +11 -0
  36. prism/security/__init__.py +17 -0
  37. prism/security/audit.py +80 -0
  38. prism/security/rate_limit.py +74 -0
  39. prism/security/tls.py +48 -0
  40. prism/wrapper/__init__.py +49 -0
  41. prism/wrapper/config.py +132 -0
  42. prism/wrapper/daemon.py +261 -0
  43. prism/wrapper/grpc_server.py +248 -0
  44. prism/wrapper/interceptor.py +543 -0
  45. prism/wrapper/main.py +5 -0
  46. prism/wrapper/proto/__init__.py +0 -0
  47. prism/wrapper/proto/chorus_pb2.py +71 -0
  48. prism/wrapper/proto/chorus_pb2_grpc.py +454 -0
  49. prism/wrapper/publisher.py +255 -0
  50. prism/wrapper/row_events.py +129 -0
  51. prism/wrapper/subscribe_server.py +78 -0
  52. prismlib_plus-0.7.0.dist-info/METADATA +748 -0
  53. prismlib_plus-0.7.0.dist-info/RECORD +56 -0
  54. prismlib_plus-0.7.0.dist-info/WHEEL +5 -0
  55. prismlib_plus-0.7.0.dist-info/entry_points.txt +2 -0
  56. prismlib_plus-0.7.0.dist-info/top_level.txt +1 -0
prism/__init__.py ADDED
@@ -0,0 +1,9 @@
1
+ """
2
+ Prism Ecosystem — Tensor-Native Distributed Data Plane
3
+ =======================================================
4
+ PrismLib: Core mathematical primitives, wave-mechanics retrieval engine,
5
+ state-compression/isolation layers, and CHORUS Fabric transport interface.
6
+ """
7
+
8
+ __version__ = "0.7.0"
9
+ __author__ = "InsightIts"
prism/api/__init__.py ADDED
@@ -0,0 +1,83 @@
1
+ """
2
+ prism.api — Vector-native API layer for AI agents
3
+ ==================================================
4
+
5
+ PrismAPI lets an API serve content that is ALREADY embedded and projected
6
+ into PrismResonance space, delivered over CHORUS as raw float32 vectors.
7
+ The consuming agent retrieves results directly with no JSON parsing and no
8
+ re-embedding call.
9
+
10
+ Quick start::
11
+
12
+ # Provider side (one line to adopt)
13
+ from prism.api import PrismAPIProvider
14
+ from prism.api.schema import SentenceTransformerEmbedder
15
+ from prism.lib.lang import PrismProjector, ProjectionConfig
16
+
17
+ projector = PrismProjector(ProjectionConfig(tenant_id="my-tenant"))
18
+ embedder = SentenceTransformerEmbedder()
19
+ provider = PrismAPIProvider(projector, embedder,
20
+ semantic_fields=["title", "body"],
21
+ id_field="doc_id")
22
+
23
+ @provider.expose
24
+ def search(query: str, top_k: int = 10) -> list[dict]:
25
+ return my_db.search(query, top_k) # unchanged
26
+
27
+ # Consumer side
28
+ from prism.api import PrismAPIClient
29
+
30
+ client = PrismAPIClient(projector, embedder, loopback_provider=provider)
31
+ response = client.query("how does inflation affect bonds?", top_k=5)
32
+ # response.vectors → np.ndarray (5, 64) — ready for PrismResonance
33
+ # response.sidecars → list of exact metadata dicts — no re-embedding
34
+
35
+ See prism/api/README.md for full documentation and benchmark numbers.
36
+ """
37
+
38
+ from prism.api.provider import ASGIAdapter, ExposedHandler, PrismAPIProvider
39
+ from prism.api.consumer import LangGraphTool, PrismAPIClient, RetryConfig
40
+ from prism.api.auth import AuthConfig, AuthError, generate_api_key
41
+ from prism.api.multi_provider import MultiProviderClient, MultiProviderResponse
42
+ from prism.api.schema import (
43
+ APIRequest,
44
+ APIResponse,
45
+ Embedder,
46
+ ExactSidecar,
47
+ SemanticItem,
48
+ SentenceTransformerEmbedder,
49
+ )
50
+ from prism.api.integrations.langgraph import (
51
+ PrismRetrieverNode,
52
+ MultiProviderRetrieverNode,
53
+ create_retriever_node,
54
+ )
55
+
56
+ __all__ = [
57
+ # Provider
58
+ "PrismAPIProvider",
59
+ "ExposedHandler",
60
+ "ASGIAdapter",
61
+ # Consumer
62
+ "PrismAPIClient",
63
+ "RetryConfig",
64
+ "LangGraphTool",
65
+ # Multi-provider
66
+ "MultiProviderClient",
67
+ "MultiProviderResponse",
68
+ # LangGraph integration
69
+ "PrismRetrieverNode",
70
+ "MultiProviderRetrieverNode",
71
+ "create_retriever_node",
72
+ # Schema
73
+ "Embedder",
74
+ "SentenceTransformerEmbedder",
75
+ "SemanticItem",
76
+ "ExactSidecar",
77
+ "APIRequest",
78
+ "APIResponse",
79
+ # Auth
80
+ "AuthConfig",
81
+ "AuthError",
82
+ "generate_api_key",
83
+ ]
prism/api/auth.py ADDED
@@ -0,0 +1,127 @@
1
+ """
2
+ prism.api.auth — API key and bearer authentication for PrismAPI endpoints.
3
+ """
4
+
5
+ from __future__ import annotations
6
+
7
+ import hmac
8
+ import os
9
+ import secrets
10
+ from dataclasses import dataclass, field
11
+ from typing import Callable, Optional, TYPE_CHECKING
12
+
13
+ if TYPE_CHECKING:
14
+ from prism.security.audit import AuditLogger
15
+ from prism.security.rate_limit import RateLimiter
16
+
17
+
18
+ class AuthError(Exception):
19
+ """Raised when authentication fails."""
20
+
21
+
22
+ @dataclass
23
+ class AuthConfig:
24
+ """
25
+ Authentication configuration for PrismAPI ASGI endpoints.
26
+
27
+ api_keys:
28
+ Valid API keys (plain strings). Compared with timing-safe equality.
29
+ bearer_tokens:
30
+ Valid bearer tokens (without the 'Bearer ' prefix).
31
+ header_api_key:
32
+ Header name for API key auth (default X-API-Key).
33
+ require_auth:
34
+ If True, reject requests with no credentials. If False, auth is
35
+ optional when api_keys/bearer_tokens are configured.
36
+ """
37
+
38
+ api_keys: tuple[str, ...] = field(default_factory=tuple)
39
+ bearer_tokens: tuple[str, ...] = field(default_factory=tuple)
40
+ header_api_key: str = "X-API-Key"
41
+ require_auth: bool = True
42
+ rate_limit_rpm: int = 120
43
+ rate_limit_burst: int = 30
44
+
45
+ @classmethod
46
+ def from_env(cls, *, prefix: str = "PRISM_API") -> "AuthConfig":
47
+ keys = os.environ.get(f"{prefix}_KEYS", "")
48
+ tokens = os.environ.get(f"{prefix}_BEARER_TOKENS", "")
49
+ require = os.environ.get(f"{prefix}_REQUIRE_AUTH", "true").lower() in (
50
+ "1", "true", "yes",
51
+ )
52
+ rpm = int(os.environ.get(f"{prefix}_RATE_LIMIT_RPM", "120"))
53
+ burst = int(os.environ.get(f"{prefix}_RATE_LIMIT_BURST", "30"))
54
+ return cls(
55
+ api_keys=tuple(k.strip() for k in keys.split(",") if k.strip()),
56
+ bearer_tokens=tuple(t.strip() for t in tokens.split(",") if t.strip()),
57
+ require_auth=require,
58
+ rate_limit_rpm=rpm,
59
+ rate_limit_burst=burst,
60
+ )
61
+
62
+ @property
63
+ def enabled(self) -> bool:
64
+ return bool(self.api_keys or self.bearer_tokens)
65
+
66
+ def validate_headers(self, headers: dict[str, str]) -> bool:
67
+ """Return True if headers contain valid credentials."""
68
+ if not self.enabled:
69
+ return not self.require_auth
70
+
71
+ lowered = {k.lower(): v for k, v in headers.items()}
72
+
73
+ api_key = lowered.get(self.header_api_key.lower())
74
+ if api_key and any(_safe_eq(api_key, k) for k in self.api_keys):
75
+ return True
76
+
77
+ auth = lowered.get("authorization", "")
78
+ if auth.lower().startswith("bearer "):
79
+ token = auth[7:].strip()
80
+ if any(_safe_eq(token, t) for t in self.bearer_tokens):
81
+ return True
82
+
83
+ return False
84
+
85
+
86
+ def _safe_eq(a: str, b: str) -> bool:
87
+ return hmac.compare_digest(a.encode(), b.encode())
88
+
89
+
90
+ def generate_api_key() -> str:
91
+ """Generate a URL-safe API key."""
92
+ return secrets.token_urlsafe(32)
93
+
94
+
95
+ def actor_from_headers(headers: dict[str, str], header_api_key: str = "X-API-Key") -> str:
96
+ """Derive audit actor id from request headers (API key prefix or client IP)."""
97
+ lowered = {k.lower(): v for k, v in headers.items()}
98
+ key = lowered.get(header_api_key.lower(), "")
99
+ if key:
100
+ return f"apikey:{key[:8]}"
101
+ auth = lowered.get("authorization", "")
102
+ if auth.lower().startswith("bearer "):
103
+ return f"bearer:{auth[7:13]}"
104
+ return lowered.get("x-forwarded-for", lowered.get("x-real-ip", "anonymous"))
105
+
106
+
107
+ def auth_dependency(config: AuthConfig) -> Callable:
108
+ """
109
+ FastAPI dependency factory for PrismAPI routes.
110
+
111
+ Usage::
112
+
113
+ from fastapi import Depends
114
+ from prism.api.auth import AuthConfig, auth_dependency
115
+
116
+ auth = AuthConfig.from_env()
117
+ app.add_api_route("/chorus/search", handler, dependencies=[Depends(auth_dependency(auth))])
118
+ """
119
+ def _check(headers: dict[str, str]) -> None:
120
+ if not config.validate_headers(headers):
121
+ raise AuthError("Unauthorized")
122
+
123
+ async def _fastapi_dep(request: object) -> None:
124
+ hdrs = {k: v for k, v in getattr(request, "headers", {}).items()}
125
+ _check(hdrs)
126
+
127
+ return _fastapi_dep