teoat commited on
Commit
2a6ebf8
·
verified ·
1 Parent(s): 5446bb1

Upload core/documentation/api_docs.py with huggingface_hub

Browse files
Files changed (1) hide show
  1. core/documentation/api_docs.py +522 -0
core/documentation/api_docs.py ADDED
@@ -0,0 +1,522 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Interactive API Documentation with OpenAPI 3.0
3
+ Enhanced developer experience with comprehensive docs
4
+ """
5
+
6
+ from typing import Any, Dict, List
7
+
8
+ from fastapi import FastAPI
9
+ from fastapi.openapi.utils import get_openapi
10
+ from fastapi.responses import HTMLResponse
11
+
12
+ from core.logging.advanced_logging import structured_logger
13
+
14
+
15
+ class EnhancedAPIDocumentation:
16
+ """Enhanced API documentation with interactive features"""
17
+
18
+ def __init__(self, app: FastAPI):
19
+ self.app = app
20
+ self.logger = structured_logger
21
+ self.custom_examples = {}
22
+ self.api_insights = {}
23
+
24
+ def add_custom_examples(self, endpoint: str, examples: Dict[str, Any]):
25
+ """Add custom examples for API endpoints"""
26
+ self.custom_examples[endpoint] = examples
27
+
28
+ def generate_enhanced_openapi(self) -> Dict[str, Any]:
29
+ """Generate enhanced OpenAPI specification"""
30
+
31
+ # Get base OpenAPI spec
32
+ openapi_schema = get_openapi(
33
+ title=self.app.title,
34
+ version=self.app.version,
35
+ description=self.app.description,
36
+ routes=self.app.routes,
37
+ )
38
+
39
+ # Enhance with custom metadata
40
+ openapi_schema["info"]["contact"] = {
41
+ "name": "Zenith Fraud Detection Platform",
42
+ "email": "support@zenith-fraud.com",
43
+ "url": "https://zenith-fraud.com"
44
+ }
45
+
46
+ openapi_schema["info"]["license"] = {
47
+ "name": "Enterprise License",
48
+ "url": "https://zenith-fraud.com/license"
49
+ }
50
+
51
+ openapi_schema["info"]["x-logo"] = {
52
+ "url": "https://zenith-fraud.com/logo.png",
53
+ "altText": "Zenith Fraud Detection Platform"
54
+ }
55
+
56
+ # Add security schemes
57
+ openapi_schema["components"]["securitySchemes"] = {
58
+ "bearerAuth": {
59
+ "type": "http",
60
+ "scheme": "bearer",
61
+ "bearerFormat": "JWT",
62
+ "description": "JWT Authorization header using the Bearer scheme"
63
+ },
64
+ "apiKey": {
65
+ "type": "apiKey",
66
+ "in": "header",
67
+ "name": "X-API-Key",
68
+ "description": "API Key for service-to-service authentication"
69
+ }
70
+ }
71
+
72
+ # Add global security
73
+ openapi_schema["security"] = [
74
+ {"bearerAuth": []},
75
+ {"apiKey": []}
76
+ ]
77
+
78
+ # Enhance paths with examples and metadata
79
+ if "paths" in openapi_schema:
80
+ for path, methods in openapi_schema["paths"].items():
81
+ for method, operation in methods.items():
82
+ if method.upper() in ["GET", "POST", "PUT", "DELETE", "PATCH"]:
83
+ # Add custom examples
84
+ endpoint_key = f"{method.upper()} {path}"
85
+ if endpoint_key in self.custom_examples:
86
+ examples = self.custom_examples[endpoint_key]
87
+ if "requestBody" not in operation and "parameters" in operation:
88
+ # Add query parameter examples
89
+ for param in operation.get("parameters", []):
90
+ param_name = param.get("name")
91
+ if param_name in examples:
92
+ param["example"] = examples[param_name]
93
+
94
+ # Add response examples
95
+ if "responses" in operation:
96
+ for status_code, response in operation["responses"].items():
97
+ if status_code == "200" and "content" in response:
98
+ for content_type, content in response["content"].items():
99
+ if content_type == "application/json":
100
+ # Add success response examples
101
+ content["example"] = self._generate_response_example(operation, status_code)
102
+
103
+ # Add operation metadata
104
+ operation["x-code-samples"] = self._generate_code_samples(path, method.upper(), operation)
105
+
106
+ return openapi_schema
107
+
108
+ def _generate_response_example(self, operation: Dict[str, Any], status_code: str) -> Dict[str, Any]:
109
+ """Generate response examples for documentation"""
110
+
111
+ operation_id = operation.get("operationId", "")
112
+ if "case" in operation_id.lower():
113
+ if "list" in operation_id.lower():
114
+ return {
115
+ "cases": [
116
+ {
117
+ "id": "case_12345",
118
+ "title": "Suspicious Transaction Pattern",
119
+ "status": "investigating",
120
+ "priority": "high",
121
+ "risk_score": 85.5,
122
+ "created_at": "2024-01-15T10:30:00Z",
123
+ "assignee": "investigator@example.com"
124
+ }
125
+ ],
126
+ "total": 1,
127
+ "page": 1,
128
+ "page_size": 20
129
+ }
130
+ elif "create" in operation_id.lower():
131
+ return {
132
+ "id": "case_12345",
133
+ "title": "New Suspicious Activity",
134
+ "status": "open",
135
+ "priority": "medium",
136
+ "created_at": "2024-01-15T10:30:00Z",
137
+ "message": "Case created successfully"
138
+ }
139
+ elif "auth" in operation_id.lower():
140
+ if "login" in operation_id.lower():
141
+ return {
142
+ "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...",
143
+ "token_type": "bearer",
144
+ "expires_in": 3600,
145
+ "user": {
146
+ "id": "user_123",
147
+ "email": "user@example.com",
148
+ "role": "investigator"
149
+ }
150
+ }
151
+
152
+ # Default example
153
+ return {"message": "Operation completed successfully"}
154
+
155
+ def _generate_code_samples(self, path: str, method: str, operation: Dict[str, Any]) -> List[Dict[str, Any]]:
156
+ """Generate code samples for different languages"""
157
+
158
+ samples = []
159
+
160
+ # Python sample
161
+ python_sample = f'''import requests
162
+
163
+ url = "https://api.zenith-fraud.com{path}"
164
+ headers = {{
165
+ "Authorization": "Bearer YOUR_JWT_TOKEN",
166
+ "Content-Type": "application/json"
167
+ }}
168
+
169
+ response = requests.{method.lower()}(url, headers=headers)
170
+ print(response.json())'''
171
+
172
+ samples.append({
173
+ "lang": "python",
174
+ "source": python_sample
175
+ })
176
+
177
+ # JavaScript sample
178
+ js_sample = f'''const response = await fetch('https://api.zenith-fraud.com{path}', {{
179
+ method: '{method}',
180
+ headers: {{
181
+ 'Authorization': 'Bearer YOUR_JWT_TOKEN',
182
+ 'Content-Type': 'application/json'
183
+ }}
184
+ }});
185
+
186
+ const data = await response.json();
187
+ console.log(data);'''
188
+
189
+ samples.append({
190
+ "lang": "javascript",
191
+ "source": js_sample
192
+ })
193
+
194
+ # cURL sample
195
+ curl_sample = f'''curl -X {method} \\
196
+ https://api.zenith-fraud.com{path} \\
197
+ -H "Authorization: Bearer YOUR_JWT_TOKEN" \\
198
+ -H "Content-Type: application/json"'''
199
+
200
+ samples.append({
201
+ "lang": "curl",
202
+ "source": curl_sample
203
+ })
204
+
205
+ return samples
206
+
207
+
208
+ class InteractiveDocumentation:
209
+ """Interactive documentation with live API testing"""
210
+
211
+ def __init__(self, app: FastAPI):
212
+ self.app = app
213
+ self.enhanced_docs = EnhancedAPIDocumentation(app)
214
+
215
+ def get_enhanced_swagger_ui_html(self) -> HTMLResponse:
216
+ """Get enhanced Swagger UI with custom features"""
217
+
218
+ html_content = f"""
219
+ <!DOCTYPE html>
220
+ <html>
221
+ <head>
222
+ <title>Zenith Fraud Detection API - Interactive Documentation</title>
223
+ <link rel="stylesheet" type="text/css" href="https://unpkg.com/swagger-ui-dist@5.7.2/swagger-ui.css" />
224
+ <style>
225
+ .topbar {{
226
+ display: none !important;
227
+ }}
228
+ .info .title {{
229
+ color: #2c3e50 !important;
230
+ }}
231
+ .swagger-ui .info .description {{
232
+ margin-bottom: 20px;
233
+ }}
234
+ .api-explorer {{
235
+ background: #f8f9fa;
236
+ padding: 20px;
237
+ margin: 20px 0;
238
+ border-radius: 8px;
239
+ border-left: 4px solid #007bff;
240
+ }}
241
+ .performance-metrics {{
242
+ background: #e8f5e8;
243
+ padding: 15px;
244
+ margin: 15px 0;
245
+ border-radius: 6px;
246
+ border-left: 4px solid #28a745;
247
+ }}
248
+ .health-status {{
249
+ background: #fff3cd;
250
+ padding: 10px;
251
+ margin: 10px 0;
252
+ border-radius: 4px;
253
+ border-left: 4px solid #ffc107;
254
+ }}
255
+ </style>
256
+ </head>
257
+ <body>
258
+ <div class="api-explorer">
259
+ <h2>🚀 Zenith Fraud Detection Platform API</h2>
260
+ <p><strong>Version:</strong> {self.app.version}</p>
261
+ <p><strong>Environment:</strong> <span id="environment-badge">Development</span></p>
262
+ <div class="health-status">
263
+ <strong>API Health:</strong> <span id="health-status">Checking...</span>
264
+ </div>
265
+ <div class="performance-metrics">
266
+ <strong>Performance Metrics:</strong>
267
+ <br>• Average Response Time: <span id="avg-response-time">Loading...</span>
268
+ <br>• 95th Percentile: <span id="p95-response-time">Loading...</span>
269
+ <br>• Success Rate: <span id="success-rate">Loading...</span>
270
+ </div>
271
+ </div>
272
+
273
+ <div id="swagger-ui"></div>
274
+
275
+ <script src="https://unpkg.com/swagger-ui-dist@5.7.2/swagger-ui-bundle.js"></script>
276
+ <script>
277
+ const ui = SwaggerUIBundle({{
278
+ url: '/openapi.json',
279
+ dom_id: '#swagger-ui',
280
+ deepLinking: true,
281
+ presets: [
282
+ SwaggerUIBundle.presets.apis,
283
+ SwaggerUIBundle.SwaggerUIStandalonePreset
284
+ ],
285
+ plugins: [
286
+ SwaggerUIBundle.plugins.DownloadUrl
287
+ ],
288
+ layout: "StandaloneLayout",
289
+ validatorUrl: null,
290
+ tryItOutEnabled: true,
291
+ requestInterceptor: function(request) {{
292
+ // Add auth token if available
293
+ const token = localStorage.getItem('api_token');
294
+ if (token) {{
295
+ request.headers.Authorization = 'Bearer ' + token;
296
+ }}
297
+ return request;
298
+ }},
299
+ responseInterceptor: function(response) {{
300
+ // Store auth token from login responses
301
+ if (response.url.includes('/auth/login') && response.status === 200) {{
302
+ try {{
303
+ const data = JSON.parse(response.data);
304
+ if (data.access_token) {{
305
+ localStorage.setItem('api_token', data.access_token);
306
+ }}
307
+ }} catch (e) {{
308
+ // Ignore parsing errors
309
+ }}
310
+ }}
311
+ return response;
312
+ }}
313
+ }});
314
+
315
+ // Update health status periodically
316
+ async function updateHealthStatus() {{
317
+ try {{
318
+ const response = await fetch('/health/detailed');
319
+ const data = await response.json();
320
+
321
+ const statusElement = document.getElementById('health-status');
322
+ const overallStatus = data.status;
323
+
324
+ statusElement.textContent = overallStatus.toUpperCase();
325
+ statusElement.style.color = overallStatus === 'healthy' ? '#28a745' :
326
+ overallStatus === 'degraded' ? '#ffc107' : '#dc3545';
327
+ }} catch (e) {{
328
+ document.getElementById('health-status').textContent = 'ERROR';
329
+ document.getElementById('health-status').style.color = '#dc3545';
330
+ }}
331
+ }}
332
+
333
+ // Update performance metrics
334
+ async function updatePerformanceMetrics() {{
335
+ try {{
336
+ const response = await fetch('/metrics');
337
+ const metrics = await response.text();
338
+
339
+ // Parse Prometheus metrics (simplified)
340
+ const lines = metrics.split('\\n');
341
+ let avgResponseTime = 'N/A';
342
+ let p95ResponseTime = 'N/A';
343
+ let successRate = 'N/A';
344
+
345
+ lines.forEach(line => {{
346
+ if (line.includes('http_request_duration_seconds')) {{
347
+ // This would require more complex parsing in production
348
+ }}
349
+ }});
350
+
351
+ document.getElementById('avg-response-time').textContent = avgResponseTime;
352
+ document.getElementById('p95-response-time').textContent = p95ResponseTime;
353
+ document.getElementById('success-rate').textContent = successRate;
354
+ }} catch (e) {{
355
+ console.log('Could not load performance metrics');
356
+ }}
357
+ }}
358
+
359
+ // Initialize
360
+ updateHealthStatus();
361
+ updatePerformanceMetrics();
362
+
363
+ // Update every 30 seconds
364
+ setInterval(updateHealthStatus, 30000);
365
+ setInterval(updatePerformanceMetrics, 60000);
366
+ </script>
367
+ </body>
368
+ </html>
369
+ """
370
+
371
+ return HTMLResponse(html_content)
372
+
373
+ def get_enhanced_redoc_html(self) -> HTMLResponse:
374
+ """Get enhanced ReDoc documentation"""
375
+
376
+ html_content = f"""
377
+ <!DOCTYPE html>
378
+ <html>
379
+ <head>
380
+ <title>Zenith Fraud Detection API - Reference Documentation</title>
381
+ <meta charset="utf-8"/>
382
+ <meta name="viewport" content="width=device-width, initial-scale=1">
383
+ <link href="https://fonts.googleapis.com/css?family=Montserrat:300,400,700|Roboto:300,400,700" rel="stylesheet">
384
+ <style>
385
+ body {{
386
+ margin: 0;
387
+ padding: 0;
388
+ }}
389
+ .api-header {{
390
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
391
+ color: white;
392
+ padding: 40px 20px;
393
+ text-align: center;
394
+ }}
395
+ .api-header h1 {{
396
+ margin: 0;
397
+ font-size: 2.5em;
398
+ font-weight: 300;
399
+ }}
400
+ .api-header p {{
401
+ margin: 10px 0 0 0;
402
+ font-size: 1.2em;
403
+ opacity: 0.9;
404
+ }}
405
+ .status-indicator {{
406
+ display: inline-block;
407
+ padding: 5px 15px;
408
+ border-radius: 20px;
409
+ font-size: 0.9em;
410
+ margin-left: 10px;
411
+ }}
412
+ .status-healthy {{
413
+ background: #28a745;
414
+ color: white;
415
+ }}
416
+ .status-degraded {{
417
+ background: #ffc107;
418
+ color: black;
419
+ }}
420
+ .status-unhealthy {{
421
+ background: #dc3545;
422
+ color: white;
423
+ }}
424
+ </style>
425
+ </head>
426
+ <body>
427
+ <div class="api-header">
428
+ <h1>Zenith Fraud Detection Platform</h1>
429
+ <p>Enterprise API Reference Documentation</p>
430
+ <div>
431
+ <strong>Version {self.app.version}</strong>
432
+ <span class="status-indicator status-healthy" id="api-status">HEALTHY</span>
433
+ </div>
434
+ </div>
435
+
436
+ <redoc spec-url="/openapi.json"></redoc>
437
+
438
+ <script src="https://cdn.redoc.ly/redoc/latest/bundles/redoc.standalone.js"></script>
439
+ <script>
440
+ // Initialize ReDoc
441
+ Redoc.init('/openapi.json', {{
442
+ title: 'Zenith Fraud Detection API',
443
+ theme: {{
444
+ colors: {{
445
+ primary: {{
446
+ main: '#667eea'
447
+ }}
448
+ }},
449
+ typography: {{
450
+ fontFamily: '"Roboto", "Helvetica", "Arial", sans-serif'
451
+ }}
452
+ }}
453
+ }}, document.querySelector('redoc'));
454
+
455
+ // Update API status
456
+ async function updateApiStatus() {{
457
+ try {{
458
+ const response = await fetch('/health');
459
+ const data = await response.json();
460
+
461
+ const statusElement = document.getElementById('api-status');
462
+ const status = data.status.toUpperCase();
463
+
464
+ statusElement.textContent = status;
465
+ statusElement.className = 'status-indicator status-' + data.status.toLowerCase();
466
+ }} catch (e) {{
467
+ document.getElementById('api-status').textContent = 'UNKNOWN';
468
+ document.getElementById('api-status').className = 'status-indicator status-unhealthy';
469
+ }}
470
+ }}
471
+
472
+ updateApiStatus();
473
+ setInterval(updateApiStatus, 30000);
474
+ </script>
475
+ </body>
476
+ </html>
477
+ """
478
+
479
+ return HTMLResponse(html_content)
480
+
481
+
482
+ # Global documentation instance
483
+ api_documentation = None
484
+
485
+
486
+ def init_api_documentation(app: FastAPI) -> None:
487
+ """Initialize enhanced API documentation"""
488
+ global api_documentation
489
+ api_documentation = InteractiveDocumentation(app)
490
+
491
+ # Add custom examples
492
+ api_documentation.enhanced_docs.add_custom_examples(
493
+ "POST /api/v1/cases/",
494
+ {
495
+ "title": "Suspicious credit card transaction pattern",
496
+ "description": "Multiple high-value transactions from unusual locations",
497
+ "priority": "high",
498
+ "risk_score": 88.5
499
+ }
500
+ )
501
+
502
+ api_documentation.enhanced_docs.add_custom_examples(
503
+ "GET /api/v1/cases/",
504
+ {
505
+ "status": "open",
506
+ "priority": "high",
507
+ "limit": 20,
508
+ "offset": 0
509
+ }
510
+ )
511
+
512
+
513
+ def get_enhanced_openapi_schema():
514
+ """Get enhanced OpenAPI schema"""
515
+ if api_documentation:
516
+ return api_documentation.enhanced_docs.generate_enhanced_openapi()
517
+ return get_openapi(
518
+ title="Zenith Fraud Detection API",
519
+ version="1.0.0",
520
+ description="Enterprise fraud detection and case management platform",
521
+ routes=[],
522
+ )