koreshield 0.1.4__py3-none-any.whl → 0.2.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.
@@ -0,0 +1,361 @@
1
+ """Framework-specific integration helpers for KoreShield SDK."""
2
+
3
+ from typing import Dict, List, Optional, Any, Callable, Union
4
+ from functools import wraps
5
+ import asyncio
6
+ import time
7
+
8
+ from ..async_client import AsyncKoreShieldClient
9
+ from ..types import DetectionResult, SecurityPolicy, ThreatLevel
10
+ from ..exceptions import KoreShieldError
11
+
12
+
13
+ class FastAPIIntegration:
14
+ """FastAPI integration helper for KoreShield security middleware."""
15
+
16
+ def __init__(
17
+ self,
18
+ client: AsyncKoreShieldClient,
19
+ scan_request_body: bool = True,
20
+ scan_response_body: bool = False,
21
+ threat_threshold: ThreatLevel = ThreatLevel.MEDIUM,
22
+ block_on_threat: bool = False,
23
+ exclude_paths: Optional[List[str]] = None,
24
+ custom_scanner: Optional[Callable] = None,
25
+ ):
26
+ """Initialize FastAPI integration.
27
+
28
+ Args:
29
+ client: AsyncKoreShieldClient instance
30
+ scan_request_body: Whether to scan request bodies
31
+ scan_response_body: Whether to scan response bodies
32
+ threat_threshold: Minimum threat level to flag
33
+ block_on_threat: Whether to block requests with threats
34
+ exclude_paths: List of paths to exclude from scanning
35
+ custom_scanner: Custom scanning function
36
+ """
37
+ self.client = client
38
+ self.scan_request_body = scan_request_body
39
+ self.scan_response_body = scan_response_body
40
+ self.threat_threshold = threat_threshold
41
+ self.block_on_threat = block_on_threat
42
+ self.exclude_paths = exclude_paths or ["/health", "/docs", "/openapi.json"]
43
+ self.custom_scanner = custom_scanner
44
+
45
+ def create_middleware(self):
46
+ """Create FastAPI middleware for automatic security scanning."""
47
+ from fastapi import Request, Response, HTTPException
48
+ from fastapi.responses import JSONResponse
49
+ import json
50
+
51
+ async def koreshield_middleware(request: Request, call_next):
52
+ # Skip excluded paths
53
+ if request.url.path in self.exclude_paths:
54
+ return await call_next(request)
55
+
56
+ scan_results = []
57
+
58
+ # Scan request body
59
+ if self.scan_request_body and request.method in ["POST", "PUT", "PATCH"]:
60
+ try:
61
+ body = await request.body()
62
+ if body:
63
+ # Try to parse as JSON for better scanning
64
+ try:
65
+ json_body = json.loads(body.decode())
66
+ # Extract text content from common fields
67
+ text_content = self._extract_text_from_request(json_body)
68
+ if text_content:
69
+ result = await self.client.scan_prompt(text_content)
70
+ scan_results.append(("request", result))
71
+ except (json.JSONDecodeError, UnicodeDecodeError):
72
+ # If not JSON, scan raw content
73
+ if len(body) < 10000: # Limit scan size
74
+ result = await self.client.scan_prompt(body.decode(errors='ignore'))
75
+ scan_results.append(("request", result))
76
+ except Exception as e:
77
+ # Log error but don't block request
78
+ print(f"KoreShield request scan error: {e}")
79
+
80
+ # Check for threats in request
81
+ for scan_type, result in scan_results:
82
+ if not result.is_safe and self._is_above_threshold(result):
83
+ if self.block_on_threat:
84
+ return JSONResponse(
85
+ status_code=403,
86
+ content={
87
+ "error": "Security threat detected",
88
+ "threat_level": result.threat_level.value,
89
+ "confidence": result.confidence,
90
+ "scan_type": scan_type
91
+ }
92
+ )
93
+ else:
94
+ # Add security headers
95
+ request.state.koreshield_threat = result
96
+
97
+ # Process response
98
+ response = await call_next(request)
99
+
100
+ # Scan response body if enabled
101
+ if self.scan_response_body and hasattr(response, 'body'):
102
+ try:
103
+ # This would need to be implemented based on response type
104
+ pass
105
+ except Exception as e:
106
+ print(f"KoreShield response scan error: {e}")
107
+
108
+ # Add security headers
109
+ response.headers["X-KoreShield-Scanned"] = "true"
110
+ if scan_results:
111
+ threat_levels = [r.threat_level.value for _, r in scan_results]
112
+ response.headers["X-KoreShield-Threat-Levels"] = ",".join(threat_levels)
113
+
114
+ return response
115
+
116
+ return koreshield_middleware
117
+
118
+ def _extract_text_from_request(self, data: Any) -> str:
119
+ """Extract text content from request data."""
120
+ if isinstance(data, str):
121
+ return data
122
+ elif isinstance(data, dict):
123
+ # Common text fields in APIs
124
+ text_fields = ['prompt', 'message', 'content', 'text', 'query', 'input']
125
+ texts = []
126
+ for field in text_fields:
127
+ if field in data and isinstance(data[field], str):
128
+ texts.append(data[field])
129
+ return " ".join(texts)
130
+ elif isinstance(data, list):
131
+ return " ".join(str(item) for item in data if isinstance(item, str))
132
+ return ""
133
+
134
+ def _is_above_threshold(self, result: DetectionResult) -> bool:
135
+ """Check if detection result is above threat threshold."""
136
+ levels = [ThreatLevel.SAFE, ThreatLevel.LOW, ThreatLevel.MEDIUM, ThreatLevel.HIGH, ThreatLevel.CRITICAL]
137
+ result_level_index = levels.index(result.threat_level)
138
+ threshold_index = levels.index(self.threat_threshold)
139
+ return result_level_index >= threshold_index
140
+
141
+
142
+ class FlaskIntegration:
143
+ """Flask integration helper for KoreShield security middleware."""
144
+
145
+ def __init__(
146
+ self,
147
+ client: AsyncKoreShieldClient,
148
+ scan_request_body: bool = True,
149
+ threat_threshold: ThreatLevel = ThreatLevel.MEDIUM,
150
+ block_on_threat: bool = False,
151
+ exclude_paths: Optional[List[str]] = None,
152
+ ):
153
+ """Initialize Flask integration.
154
+
155
+ Args:
156
+ client: AsyncKoreShieldClient instance
157
+ scan_request_body: Whether to scan request bodies
158
+ threat_threshold: Minimum threat level to flag
159
+ block_on_threat: Whether to block requests with threats
160
+ exclude_paths: List of paths to exclude from scanning
161
+ """
162
+ self.client = client
163
+ self.scan_request_body = scan_request_body
164
+ self.threat_threshold = threat_threshold
165
+ self.block_on_threat = block_on_threat
166
+ self.exclude_paths = exclude_paths or ["/health", "/static"]
167
+
168
+ def create_middleware(self):
169
+ """Create Flask middleware for automatic security scanning."""
170
+ from flask import request, jsonify, g
171
+ import json
172
+
173
+ def koreshield_middleware():
174
+ # Skip excluded paths
175
+ if request.path in self.exclude_paths:
176
+ return None
177
+
178
+ # Only scan POST/PUT/PATCH requests with bodies
179
+ if request.method not in ["POST", "PUT", "PATCH"] or not request.is_json:
180
+ return None
181
+
182
+ try:
183
+ data = request.get_json()
184
+ text_content = self._extract_text_from_request(data)
185
+
186
+ if text_content:
187
+ # Use asyncio to run async scan in sync context
188
+ loop = asyncio.new_event_loop()
189
+ asyncio.set_event_loop(loop)
190
+ try:
191
+ result = loop.run_until_complete(self.client.scan_prompt(text_content))
192
+ g.koreshield_result = result
193
+
194
+ if not result.is_safe and self._is_above_threshold(result):
195
+ if self.block_on_threat:
196
+ return jsonify({
197
+ "error": "Security threat detected",
198
+ "threat_level": result.threat_level.value,
199
+ "confidence": result.confidence
200
+ }), 403
201
+ finally:
202
+ loop.close()
203
+
204
+ except Exception as e:
205
+ # Log error but don't block
206
+ print(f"KoreShield middleware error: {e}")
207
+
208
+ return None
209
+
210
+ return koreshield_middleware
211
+
212
+ def _extract_text_from_request(self, data: Any) -> str:
213
+ """Extract text content from request data."""
214
+ if isinstance(data, str):
215
+ return data
216
+ elif isinstance(data, dict):
217
+ text_fields = ['prompt', 'message', 'content', 'text', 'query', 'input']
218
+ texts = []
219
+ for field in text_fields:
220
+ if field in data and isinstance(data[field], str):
221
+ texts.append(data[field])
222
+ return " ".join(texts)
223
+ elif isinstance(data, list):
224
+ return " ".join(str(item) for item in data if isinstance(item, str))
225
+ return ""
226
+
227
+ def _is_above_threshold(self, result: DetectionResult) -> bool:
228
+ """Check if detection result is above threat threshold."""
229
+ levels = [ThreatLevel.SAFE, ThreatLevel.LOW, ThreatLevel.MEDIUM, ThreatLevel.HIGH, ThreatLevel.CRITICAL]
230
+ result_level_index = levels.index(result.threat_level)
231
+ threshold_index = levels.index(self.threat_threshold)
232
+ return result_level_index >= threshold_index
233
+
234
+
235
+ class DjangoIntegration:
236
+ """Django integration helper for KoreShield security middleware."""
237
+
238
+ def __init__(
239
+ self,
240
+ client: AsyncKoreShieldClient,
241
+ scan_request_body: bool = True,
242
+ threat_threshold: ThreatLevel = ThreatLevel.MEDIUM,
243
+ block_on_threat: bool = False,
244
+ exclude_paths: Optional[List[str]] = None,
245
+ ):
246
+ """Initialize Django integration.
247
+
248
+ Args:
249
+ client: AsyncKoreShieldClient instance
250
+ scan_request_body: Whether to scan request bodies
251
+ threat_threshold: Minimum threat level to flag
252
+ block_on_threat: Whether to block requests with threats
253
+ exclude_paths: List of paths to exclude from scanning
254
+ """
255
+ self.client = client
256
+ self.scan_request_body = scan_request_body
257
+ self.threat_threshold = threat_threshold
258
+ self.block_on_threat = block_on_threat
259
+ self.exclude_paths = exclude_paths or ["/admin", "/static", "/media"]
260
+
261
+ def create_middleware(self):
262
+ """Create Django middleware for automatic security scanning."""
263
+ from django.http import JsonResponse
264
+ from django.core.exceptions import MiddlewareNotUsed
265
+ import json
266
+ import asyncio
267
+
268
+ class KoreShieldMiddleware:
269
+ def __init__(self, get_response):
270
+ self.get_response = get_response
271
+
272
+ def __call__(self, request):
273
+ # Skip excluded paths
274
+ if request.path in self.exclude_paths:
275
+ return self.get_response(request)
276
+
277
+ # Only scan POST/PUT/PATCH requests
278
+ if request.method not in ["POST", "PUT", "PATCH"]:
279
+ return self.get_response(request)
280
+
281
+ # Scan request body
282
+ if self.scan_request_body:
283
+ try:
284
+ if request.content_type == 'application/json':
285
+ data = json.loads(request.body.decode())
286
+ text_content = self._extract_text_from_request(data)
287
+
288
+ if text_content:
289
+ # Run async scan in sync context
290
+ loop = asyncio.new_event_loop()
291
+ asyncio.set_event_loop(loop)
292
+ try:
293
+ result = loop.run_until_complete(self.client.scan_prompt(text_content))
294
+
295
+ if not result.is_safe and self._is_above_threshold(result):
296
+ if self.block_on_threat:
297
+ return JsonResponse({
298
+ "error": "Security threat detected",
299
+ "threat_level": result.threat_level.value,
300
+ "confidence": result.confidence
301
+ }, status=403)
302
+ else:
303
+ # Store result for later use
304
+ request.koreshield_result = result
305
+ finally:
306
+ loop.close()
307
+
308
+ except Exception as e:
309
+ print(f"KoreShield middleware error: {e}")
310
+
311
+ response = self.get_response(request)
312
+
313
+ # Add security headers
314
+ response["X-KoreShield-Scanned"] = "true"
315
+ if hasattr(request, 'koreshield_result'):
316
+ response["X-KoreShield-Threat-Level"] = request.koreshield_result.threat_level.value
317
+
318
+ return response
319
+
320
+ return KoreShieldMiddleware
321
+
322
+ def _extract_text_from_request(self, data: Any) -> str:
323
+ """Extract text content from request data."""
324
+ if isinstance(data, str):
325
+ return data
326
+ elif isinstance(data, dict):
327
+ text_fields = ['prompt', 'message', 'content', 'text', 'query', 'input']
328
+ texts = []
329
+ for field in text_fields:
330
+ if field in data and isinstance(data[field], str):
331
+ texts.append(data[field])
332
+ return " ".join(texts)
333
+ elif isinstance(data, list):
334
+ return " ".join(str(item) for item in data if isinstance(item, str))
335
+ return ""
336
+
337
+ def _is_above_threshold(self, result: DetectionResult) -> bool:
338
+ """Check if detection result is above threat threshold."""
339
+ levels = [ThreatLevel.SAFE, ThreatLevel.LOW, ThreatLevel.MEDIUM, ThreatLevel.HIGH, ThreatLevel.CRITICAL]
340
+ result_level_index = levels.index(result.threat_level)
341
+ threshold_index = levels.index(self.threat_threshold)
342
+ return result_level_index >= threshold_index
343
+
344
+
345
+ # Convenience functions for quick setup
346
+ def create_fastapi_middleware(client: AsyncKoreShieldClient, **kwargs):
347
+ """Create FastAPI middleware for KoreShield."""
348
+ integration = FastAPIIntegration(client, **kwargs)
349
+ return integration.create_middleware()
350
+
351
+
352
+ def create_flask_middleware(client: AsyncKoreShieldClient, **kwargs):
353
+ """Create Flask middleware for KoreShield."""
354
+ integration = FlaskIntegration(client, **kwargs)
355
+ return integration.create_middleware()
356
+
357
+
358
+ def create_django_middleware(client: AsyncKoreShieldClient, **kwargs):
359
+ """Create Django middleware for KoreShield."""
360
+ integration = DjangoIntegration(client, **kwargs)
361
+ return integration.create_middleware()
koreshield_sdk/types.py CHANGED
@@ -87,4 +87,56 @@ class BatchScanResponse(BaseModel):
87
87
  total_unsafe: int
88
88
  processing_time_ms: float
89
89
  request_id: str
90
- timestamp: str
90
+ timestamp: str
91
+ version: str
92
+
93
+
94
+ class StreamingScanRequest(BaseModel):
95
+ """Request for streaming security scanning."""
96
+ content: str
97
+ chunk_size: int = 1000
98
+ overlap: int = 100
99
+ context: Optional[Dict[str, Any]] = None
100
+ user_id: Optional[str] = None
101
+ session_id: Optional[str] = None
102
+ metadata: Optional[Dict[str, Any]] = None
103
+
104
+ model_config = ConfigDict(extra="allow")
105
+
106
+
107
+ class StreamingScanResponse(BaseModel):
108
+ """Response from streaming security scanning."""
109
+ chunk_results: List[DetectionResult]
110
+ overall_result: DetectionResult
111
+ total_chunks: int
112
+ processing_time_ms: float
113
+ request_id: str
114
+ timestamp: str
115
+ version: str
116
+
117
+
118
+ class SecurityPolicy(BaseModel):
119
+ """Custom security policy configuration."""
120
+ name: str
121
+ description: Optional[str] = None
122
+ threat_threshold: ThreatLevel = ThreatLevel.MEDIUM
123
+ blocked_detection_types: List[DetectionType] = Field(default_factory=list)
124
+ custom_rules: List[Dict[str, Any]] = Field(default_factory=list)
125
+ allowlist_patterns: List[str] = Field(default_factory=list)
126
+ blocklist_patterns: List[str] = Field(default_factory=list)
127
+ metadata: Optional[Dict[str, Any]] = None
128
+
129
+
130
+ class PerformanceMetrics(BaseModel):
131
+ """SDK performance and usage metrics."""
132
+ total_requests: int = 0
133
+ total_processing_time_ms: float = 0.0
134
+ average_response_time_ms: float = 0.0
135
+ requests_per_second: float = 0.0
136
+ error_count: int = 0
137
+ cache_hit_rate: float = 0.0
138
+ batch_efficiency: float = 0.0
139
+ streaming_chunks_processed: int = 0
140
+ uptime_seconds: float = 0.0
141
+ memory_usage_mb: Optional[float] = None
142
+ custom_metrics: Dict[str, Any] = Field(default_factory=dict)
@@ -1,13 +0,0 @@
1
- koreshield-0.1.4.dist-info/licenses/LICENSE,sha256=k3qeCwQxhbOO1GtxA10Do4-_veQzgflqjOp5uZD5mug,1071
2
- koreshield_sdk/__init__.py,sha256=JXErgUsoxTgM4EU--Os4ZTobARKWj1Mfurln-hNgCQw,785
3
- koreshield_sdk/async_client.py,sha256=7GqmesiFlGAMQnCV4rqDUyn9Dfbt3W8LAegynTafFZ8,8516
4
- koreshield_sdk/client.py,sha256=cUBE2B8SSKcrMr4NfUrDyCsTXdnfrvsLYuH83vsGdJw,7523
5
- koreshield_sdk/exceptions.py,sha256=3j1FR4VFbe1Vv4i0bofBgQ_ZGwBfpOInBd9OyNQFUxo,945
6
- koreshield_sdk/py.typed,sha256=8ZJUsxZiuOy1oJeVhsTWQhTG_6pTVHVXk5hJL79ebTk,25
7
- koreshield_sdk/types.py,sha256=HPaxcK8NOK9p4VgDQTuTa3LENGQ5tgaWXZ_23S2QJcQ,2253
8
- koreshield_sdk/integrations/__init__.py,sha256=po_sLSND55Wdu1vDmx4Nrjm072HLf04yxmtWj43yv7Y,382
9
- koreshield_sdk/integrations/langchain.py,sha256=Dw_Kp7LyIdNr36TWv05yk3xPPNSZKOHEkHLKeMbobyw,10259
10
- koreshield-0.1.4.dist-info/METADATA,sha256=w5_oiKGgtmCb8z0_4dt9YU8tAqRnxAKOYWXSzTiWTFA,11507
11
- koreshield-0.1.4.dist-info/WHEEL,sha256=qELbo2s1Yzl39ZmrAibXA2jjPLUYfnVhUNTlyF1rq0Y,92
12
- koreshield-0.1.4.dist-info/top_level.txt,sha256=ePw2ZI3SrHZ5CaTRCyj3aya3j_qTcmRAQjoU7s3gAdM,15
13
- koreshield-0.1.4.dist-info/RECORD,,