opensecureconf-client 1.0.2__tar.gz → 2.0.2__tar.gz

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 (22) hide show
  1. opensecureconf_client-2.0.2/ADVANCED_EXAMPLES.md +754 -0
  2. opensecureconf_client-2.0.2/MANIFEST.in +6 -0
  3. opensecureconf_client-2.0.2/PKG-INFO +1289 -0
  4. opensecureconf_client-2.0.2/README.md +1247 -0
  5. opensecureconf_client-2.0.2/example_enhanced_usage.py +278 -0
  6. opensecureconf_client-2.0.2/example_usage.py +166 -0
  7. opensecureconf_client-2.0.2/opensecureconf_client.egg-info/PKG-INFO +1289 -0
  8. {opensecureconf_client-1.0.2 → opensecureconf_client-2.0.2}/opensecureconf_client.egg-info/SOURCES.txt +3 -0
  9. {opensecureconf_client-1.0.2 → opensecureconf_client-2.0.2}/opensecureconf_client.egg-info/requires.txt +6 -0
  10. opensecureconf_client-2.0.2/opensecureconf_client.py +769 -0
  11. opensecureconf_client-2.0.2/pyproject.toml +119 -0
  12. opensecureconf_client-1.0.2/MANIFEST.in +0 -3
  13. opensecureconf_client-1.0.2/PKG-INFO +0 -229
  14. opensecureconf_client-1.0.2/README.md +0 -194
  15. opensecureconf_client-1.0.2/opensecureconf_client.egg-info/PKG-INFO +0 -229
  16. opensecureconf_client-1.0.2/opensecureconf_client.py +0 -314
  17. opensecureconf_client-1.0.2/pyproject.toml +0 -52
  18. {opensecureconf_client-1.0.2 → opensecureconf_client-2.0.2}/LICENSE +0 -0
  19. {opensecureconf_client-1.0.2 → opensecureconf_client-2.0.2}/opensecureconf_client.egg-info/dependency_links.txt +0 -0
  20. {opensecureconf_client-1.0.2 → opensecureconf_client-2.0.2}/opensecureconf_client.egg-info/top_level.txt +0 -0
  21. {opensecureconf_client-1.0.2 → opensecureconf_client-2.0.2}/setup.cfg +0 -0
  22. {opensecureconf_client-1.0.2 → opensecureconf_client-2.0.2}/setup.py +0 -0
@@ -0,0 +1,754 @@
1
+ # Advanced Usage Examples
2
+
3
+ This document contains advanced usage patterns and real-world examples for the OpenSecureConf Python Client.
4
+
5
+ ## Table of Contents
6
+
7
+ - [Production Deployment Patterns](#production-deployment-patterns)
8
+ - [Microservices Configuration](#microservices-configuration)
9
+ - [High Availability Patterns](#high-availability-patterns)
10
+ - [Performance Optimization](#performance-optimization)
11
+ - [Integration Examples](#integration-examples)
12
+ - [Security Best Practices](#security-best-practices)
13
+
14
+ ## Production Deployment Patterns
15
+
16
+ ### Environment-Based Configuration
17
+
18
+ ```python
19
+ import os
20
+ from opensecureconf_client_enhanced import OpenSecureConfClient
21
+
22
+ def get_client():
23
+ """Factory function to create client based on environment."""
24
+ env = os.getenv("ENVIRONMENT", "development")
25
+
26
+ if env == "production":
27
+ return OpenSecureConfClient(
28
+ base_url=os.getenv("OSC_URL"),
29
+ user_key=os.getenv("OSC_USER_KEY"),
30
+ api_key=os.getenv("OSC_API_KEY"),
31
+ timeout=60,
32
+ verify_ssl=True,
33
+ enable_retry=True,
34
+ max_retries=5,
35
+ backoff_factor=2.0,
36
+ pool_connections=50,
37
+ pool_maxsize=100,
38
+ log_level="INFO"
39
+ )
40
+ elif env == "staging":
41
+ return OpenSecureConfClient(
42
+ base_url=os.getenv("OSC_URL", "http://staging-osc.internal:9000"),
43
+ user_key=os.getenv("OSC_USER_KEY"),
44
+ api_key=os.getenv("OSC_API_KEY"),
45
+ timeout=30,
46
+ verify_ssl=True,
47
+ enable_retry=True,
48
+ max_retries=3,
49
+ log_level="DEBUG"
50
+ )
51
+ else: # development
52
+ return OpenSecureConfClient(
53
+ base_url="http://localhost:9000",
54
+ user_key="dev-key-12345678",
55
+ api_key="dev-api-key",
56
+ timeout=10,
57
+ verify_ssl=False,
58
+ enable_retry=False,
59
+ log_level="DEBUG"
60
+ )
61
+
62
+ # Usage
63
+ client = get_client()
64
+ ```
65
+
66
+ ### Configuration Singleton Pattern
67
+
68
+ ```python
69
+ from opensecureconf_client_enhanced import OpenSecureConfClient
70
+ from threading import Lock
71
+ import os
72
+
73
+ class ConfigurationManager:
74
+ """Thread-safe singleton for managing OpenSecureConf client."""
75
+
76
+ _instance = None
77
+ _lock = Lock()
78
+
79
+ def __new__(cls):
80
+ if cls._instance is None:
81
+ with cls._lock:
82
+ if cls._instance is None:
83
+ cls._instance = super().__new__(cls)
84
+ cls._instance._initialize()
85
+ return cls._instance
86
+
87
+ def _initialize(self):
88
+ """Initialize the client."""
89
+ self.client = OpenSecureConfClient(
90
+ base_url=os.getenv("OSC_URL"),
91
+ user_key=os.getenv("OSC_USER_KEY"),
92
+ api_key=os.getenv("OSC_API_KEY"),
93
+ enable_retry=True,
94
+ log_level="INFO"
95
+ )
96
+ self._cache = {}
97
+ self._cache_ttl = 300 # 5 minutes
98
+
99
+ def get_config(self, key: str, use_cache: bool = True):
100
+ """Get configuration with optional caching."""
101
+ if use_cache and key in self._cache:
102
+ return self._cache[key]
103
+
104
+ config = self.client.read(key)
105
+ if use_cache:
106
+ self._cache[key] = config
107
+ return config
108
+
109
+ def invalidate_cache(self, key: str = None):
110
+ """Invalidate cache for specific key or all keys."""
111
+ if key:
112
+ self._cache.pop(key, None)
113
+ else:
114
+ self._cache.clear()
115
+
116
+ # Usage
117
+ config_manager = ConfigurationManager()
118
+ db_config = config_manager.get_config("database")
119
+ ```
120
+
121
+ ## Microservices Configuration
122
+
123
+ ### Service Discovery Pattern
124
+
125
+ ```python
126
+ from opensecureconf_client_enhanced import OpenSecureConfClient
127
+ from typing import Dict, List
128
+
129
+ class ServiceRegistry:
130
+ """Manage microservice configurations."""
131
+
132
+ def __init__(self, client: OpenSecureConfClient):
133
+ self.client = client
134
+ self.service_category = "microservices"
135
+
136
+ def register_service(self, name: str, config: Dict):
137
+ """Register a new microservice."""
138
+ return self.client.create(
139
+ key=f"service.{name}",
140
+ value={
141
+ "name": name,
142
+ "url": config["url"],
143
+ "port": config.get("port", 8080),
144
+ "health_endpoint": config.get("health_endpoint", "/health"),
145
+ "timeout": config.get("timeout", 30),
146
+ "retries": config.get("retries", 3)
147
+ },
148
+ category=self.service_category
149
+ )
150
+
151
+ def discover_service(self, name: str) -> Dict:
152
+ """Discover service configuration."""
153
+ return self.client.read(f"service.{name}")
154
+
155
+ def list_services(self) -> List[Dict]:
156
+ """List all registered services."""
157
+ return self.client.list_all(category=self.service_category)
158
+
159
+ def update_service(self, name: str, config: Dict):
160
+ """Update service configuration."""
161
+ current = self.discover_service(name)
162
+ updated_config = {**current['value'], **config}
163
+ return self.client.update(f"service.{name}", updated_config)
164
+
165
+ def deregister_service(self, name: str):
166
+ """Remove service from registry."""
167
+ return self.client.delete(f"service.{name}")
168
+
169
+ # Usage
170
+ with OpenSecureConfClient(base_url="...", user_key="...") as client:
171
+ registry = ServiceRegistry(client)
172
+
173
+ # Register services
174
+ registry.register_service("api-gateway", {
175
+ "url": "http://api-gateway.internal",
176
+ "port": 8080
177
+ })
178
+
179
+ registry.register_service("auth-service", {
180
+ "url": "http://auth.internal",
181
+ "port": 8081
182
+ })
183
+
184
+ # Discover service
185
+ api_config = registry.discover_service("api-gateway")
186
+ print(f"API Gateway URL: {api_config['value']['url']}")
187
+
188
+ # List all services
189
+ services = registry.list_services()
190
+ print(f"Total services: {len(services)}")
191
+ ```
192
+
193
+ ### Feature Flags System
194
+
195
+ ```python
196
+ from opensecureconf_client_enhanced import OpenSecureConfClient
197
+ from typing import Any, Dict
198
+ from datetime import datetime
199
+
200
+ class FeatureFlags:
201
+ """Manage feature flags across environments."""
202
+
203
+ def __init__(self, client: OpenSecureConfClient, environment: str):
204
+ self.client = client
205
+ self.environment = environment
206
+ self.category = f"features.{environment}"
207
+
208
+ def create_flag(self, name: str, enabled: bool, metadata: Dict = None):
209
+ """Create a new feature flag."""
210
+ return self.client.create(
211
+ key=f"feature.{name}",
212
+ value={
213
+ "enabled": enabled,
214
+ "environment": self.environment,
215
+ "created_at": datetime.utcnow().isoformat(),
216
+ "metadata": metadata or {}
217
+ },
218
+ category=self.category
219
+ )
220
+
221
+ def is_enabled(self, name: str, default: bool = False) -> bool:
222
+ """Check if feature is enabled."""
223
+ try:
224
+ flag = self.client.read(f"feature.{name}")
225
+ return flag['value']['enabled']
226
+ except:
227
+ return default
228
+
229
+ def enable_flag(self, name: str):
230
+ """Enable a feature flag."""
231
+ flag = self.client.read(f"feature.{name}")
232
+ flag['value']['enabled'] = True
233
+ return self.client.update(f"feature.{name}", flag['value'])
234
+
235
+ def disable_flag(self, name: str):
236
+ """Disable a feature flag."""
237
+ flag = self.client.read(f"feature.{name}")
238
+ flag['value']['enabled'] = False
239
+ return self.client.update(f"feature.{name}", flag['value'])
240
+
241
+ def list_flags(self) -> Dict[str, bool]:
242
+ """List all feature flags."""
243
+ flags = self.client.list_all(category=self.category)
244
+ return {
245
+ flag['key'].replace('feature.', ''): flag['value']['enabled']
246
+ for flag in flags
247
+ }
248
+
249
+ # Usage
250
+ with OpenSecureConfClient(base_url="...", user_key="...") as client:
251
+ features = FeatureFlags(client, environment="production")
252
+
253
+ # Create flags
254
+ features.create_flag("new_ui", enabled=False, metadata={
255
+ "description": "New user interface",
256
+ "owner": "frontend-team"
257
+ })
258
+
259
+ features.create_flag("beta_features", enabled=True, metadata={
260
+ "description": "Beta features access",
261
+ "rollout_percentage": 10
262
+ })
263
+
264
+ # Check flags
265
+ if features.is_enabled("new_ui"):
266
+ # Show new UI
267
+ pass
268
+
269
+ # List all flags
270
+ all_flags = features.list_flags()
271
+ print("Active flags:", [k for k, v in all_flags.items() if v])
272
+ ```
273
+
274
+ ## High Availability Patterns
275
+
276
+ ### Circuit Breaker Pattern
277
+
278
+ ```python
279
+ from opensecureconf_client_enhanced import OpenSecureConfClient
280
+ from datetime import datetime, timedelta
281
+ import time
282
+
283
+ class CircuitBreaker:
284
+ """Circuit breaker for OpenSecureConf client."""
285
+
286
+ CLOSED = "CLOSED"
287
+ OPEN = "OPEN"
288
+ HALF_OPEN = "HALF_OPEN"
289
+
290
+ def __init__(self, client: OpenSecureConfClient,
291
+ failure_threshold: int = 5,
292
+ timeout: int = 60):
293
+ self.client = client
294
+ self.failure_threshold = failure_threshold
295
+ self.timeout = timeout
296
+ self.failures = 0
297
+ self.last_failure_time = None
298
+ self.state = self.CLOSED
299
+
300
+ def call(self, method: str, *args, **kwargs):
301
+ """Execute method with circuit breaker protection."""
302
+ if self.state == self.OPEN:
303
+ if self._should_attempt_reset():
304
+ self.state = self.HALF_OPEN
305
+ else:
306
+ raise Exception("Circuit breaker is OPEN")
307
+
308
+ try:
309
+ result = getattr(self.client, method)(*args, **kwargs)
310
+ self._on_success()
311
+ return result
312
+ except Exception as e:
313
+ self._on_failure()
314
+ raise e
315
+
316
+ def _should_attempt_reset(self) -> bool:
317
+ """Check if circuit breaker should attempt to reset."""
318
+ return (self.last_failure_time and
319
+ datetime.now() - self.last_failure_time > timedelta(seconds=self.timeout))
320
+
321
+ def _on_success(self):
322
+ """Handle successful request."""
323
+ self.failures = 0
324
+ self.state = self.CLOSED
325
+
326
+ def _on_failure(self):
327
+ """Handle failed request."""
328
+ self.failures += 1
329
+ self.last_failure_time = datetime.now()
330
+
331
+ if self.failures >= self.failure_threshold:
332
+ self.state = self.OPEN
333
+
334
+ # Usage
335
+ client = OpenSecureConfClient(base_url="...", user_key="...")
336
+ breaker = CircuitBreaker(client, failure_threshold=3, timeout=30)
337
+
338
+ try:
339
+ config = breaker.call("read", "database")
340
+ except Exception as e:
341
+ print(f"Circuit breaker: {e}")
342
+ ```
343
+
344
+ ### Failover Strategy
345
+
346
+ ```python
347
+ from opensecureconf_client_enhanced import OpenSecureConfClient
348
+ from typing import List
349
+
350
+ class FailoverClient:
351
+ """Client with automatic failover to backup nodes."""
352
+
353
+ def __init__(self, nodes: List[str], user_key: str, api_key: str = None):
354
+ self.nodes = nodes
355
+ self.user_key = user_key
356
+ self.api_key = api_key
357
+ self.current_node = 0
358
+ self.clients = self._create_clients()
359
+
360
+ def _create_clients(self) -> List[OpenSecureConfClient]:
361
+ """Create client for each node."""
362
+ return [
363
+ OpenSecureConfClient(
364
+ base_url=node,
365
+ user_key=self.user_key,
366
+ api_key=self.api_key,
367
+ enable_retry=True,
368
+ timeout=10
369
+ )
370
+ for node in self.nodes
371
+ ]
372
+
373
+ def _execute_with_failover(self, method: str, *args, **kwargs):
374
+ """Execute method with automatic failover."""
375
+ attempts = len(self.clients)
376
+ last_exception = None
377
+
378
+ for i in range(attempts):
379
+ client = self.clients[(self.current_node + i) % len(self.clients)]
380
+ try:
381
+ result = getattr(client, method)(*args, **kwargs)
382
+ self.current_node = (self.current_node + i) % len(self.clients)
383
+ return result
384
+ except Exception as e:
385
+ last_exception = e
386
+ continue
387
+
388
+ raise Exception(f"All nodes failed: {last_exception}")
389
+
390
+ def create(self, *args, **kwargs):
391
+ return self._execute_with_failover("create", *args, **kwargs)
392
+
393
+ def read(self, *args, **kwargs):
394
+ return self._execute_with_failover("read", *args, **kwargs)
395
+
396
+ def update(self, *args, **kwargs):
397
+ return self._execute_with_failover("update", *args, **kwargs)
398
+
399
+ def delete(self, *args, **kwargs):
400
+ return self._execute_with_failover("delete", *args, **kwargs)
401
+
402
+ # Usage
403
+ failover_client = FailoverClient(
404
+ nodes=[
405
+ "http://node1.example.com:9000",
406
+ "http://node2.example.com:9000",
407
+ "http://node3.example.com:9000"
408
+ ],
409
+ user_key="my-key",
410
+ api_key="api-key"
411
+ )
412
+
413
+ # Automatically fails over to healthy nodes
414
+ config = failover_client.read("database")
415
+ ```
416
+
417
+ ## Performance Optimization
418
+
419
+ ### Batch Processing with Progress
420
+
421
+ ```python
422
+ from opensecureconf_client_enhanced import OpenSecureConfClient
423
+ from typing import List, Dict
424
+ from tqdm import tqdm # pip install tqdm
425
+
426
+ def bulk_migrate_configs(
427
+ client: OpenSecureConfClient,
428
+ configs: List[Dict],
429
+ batch_size: int = 100
430
+ ):
431
+ """Migrate large number of configurations with progress bar."""
432
+ total = len(configs)
433
+
434
+ with tqdm(total=total, desc="Migrating configs") as pbar:
435
+ for i in range(0, total, batch_size):
436
+ batch = configs[i:i + batch_size]
437
+ try:
438
+ client.bulk_create(batch, ignore_errors=True)
439
+ pbar.update(len(batch))
440
+ except Exception as e:
441
+ print(f"Batch {i//batch_size} failed: {e}")
442
+
443
+ # Usage
444
+ configs = [
445
+ {"key": f"config_{i}", "value": {"index": i}, "category": "bulk"}
446
+ for i in range(1000)
447
+ ]
448
+
449
+ with OpenSecureConfClient(base_url="...", user_key="...") as client:
450
+ bulk_migrate_configs(client, configs, batch_size=50)
451
+ ```
452
+
453
+ ### Concurrent Operations
454
+
455
+ ```python
456
+ from opensecureconf_client_enhanced import OpenSecureConfClient
457
+ from concurrent.futures import ThreadPoolExecutor, as_completed
458
+ from typing import List
459
+
460
+ def parallel_read_configs(
461
+ client: OpenSecureConfClient,
462
+ keys: List[str],
463
+ max_workers: int = 10
464
+ ) -> Dict[str, Dict]:
465
+ """Read multiple configurations in parallel."""
466
+ results = {}
467
+
468
+ def read_config(key: str):
469
+ try:
470
+ return key, client.read(key)
471
+ except Exception as e:
472
+ return key, {"error": str(e)}
473
+
474
+ with ThreadPoolExecutor(max_workers=max_workers) as executor:
475
+ futures = {executor.submit(read_config, key): key for key in keys}
476
+
477
+ for future in as_completed(futures):
478
+ key, result = future.result()
479
+ results[key] = result
480
+
481
+ return results
482
+
483
+ # Usage
484
+ keys = [f"service_{i}" for i in range(100)]
485
+
486
+ with OpenSecureConfClient(
487
+ base_url="...",
488
+ user_key="...",
489
+ pool_connections=20,
490
+ pool_maxsize=50
491
+ ) as client:
492
+ configs = parallel_read_configs(client, keys, max_workers=20)
493
+ print(f"Retrieved {len(configs)} configurations")
494
+ ```
495
+
496
+ ## Integration Examples
497
+
498
+ ### Flask Integration
499
+
500
+ ```python
501
+ from flask import Flask, g
502
+ from opensecureconf_client_enhanced import OpenSecureConfClient
503
+ import os
504
+
505
+ app = Flask(__name__)
506
+
507
+ def get_config_client():
508
+ """Get or create OpenSecureConf client for current request."""
509
+ if 'osc_client' not in g:
510
+ g.osc_client = OpenSecureConfClient(
511
+ base_url=os.getenv("OSC_URL"),
512
+ user_key=os.getenv("OSC_USER_KEY"),
513
+ api_key=os.getenv("OSC_API_KEY"),
514
+ enable_retry=True
515
+ )
516
+ return g.osc_client
517
+
518
+ @app.teardown_appcontext
519
+ def close_config_client(error):
520
+ """Close client at end of request."""
521
+ client = g.pop('osc_client', None)
522
+ if client is not None:
523
+ client.close()
524
+
525
+ @app.route('/api/config/<key>')
526
+ def get_config(key):
527
+ """Get configuration from OpenSecureConf."""
528
+ client = get_config_client()
529
+ try:
530
+ config = client.read(key)
531
+ return config['value']
532
+ except Exception as e:
533
+ return {"error": str(e)}, 404
534
+
535
+ if __name__ == '__main__':
536
+ app.run()
537
+ ```
538
+
539
+ ### Django Integration
540
+
541
+ ```python
542
+ # settings.py
543
+ from opensecureconf_client_enhanced import OpenSecureConfClient
544
+ import os
545
+
546
+ # Initialize client
547
+ OSC_CLIENT = OpenSecureConfClient(
548
+ base_url=os.getenv("OSC_URL"),
549
+ user_key=os.getenv("OSC_USER_KEY"),
550
+ api_key=os.getenv("OSC_API_KEY"),
551
+ enable_retry=True,
552
+ log_level="INFO"
553
+ )
554
+
555
+ # Load database config from OpenSecureConf
556
+ db_config = OSC_CLIENT.read("database")
557
+
558
+ DATABASES = {
559
+ 'default': {
560
+ 'ENGINE': 'django.db.backends.postgresql',
561
+ 'NAME': db_config['value']['name'],
562
+ 'USER': db_config['value']['user'],
563
+ 'PASSWORD': db_config['value']['password'],
564
+ 'HOST': db_config['value']['host'],
565
+ 'PORT': db_config['value']['port'],
566
+ }
567
+ }
568
+
569
+ # Load cache config
570
+ cache_config = OSC_CLIENT.read("cache")
571
+
572
+ CACHES = {
573
+ 'default': {
574
+ 'BACKEND': 'django.core.cache.backends.redis.RedisCache',
575
+ 'LOCATION': f"redis://{cache_config['value']['host']}:{cache_config['value']['port']}",
576
+ }
577
+ }
578
+ ```
579
+
580
+ ### FastAPI Integration
581
+
582
+ ```python
583
+ from fastapi import FastAPI, Depends, HTTPException
584
+ from opensecureconf_client_enhanced import OpenSecureConfClient
585
+ from typing import Dict
586
+ import os
587
+
588
+ app = FastAPI()
589
+
590
+ # Global client
591
+ osc_client = OpenSecureConfClient(
592
+ base_url=os.getenv("OSC_URL"),
593
+ user_key=os.getenv("OSC_USER_KEY"),
594
+ api_key=os.getenv("OSC_API_KEY"),
595
+ enable_retry=True
596
+ )
597
+
598
+ def get_client() -> OpenSecureConfClient:
599
+ """Dependency to inject OpenSecureConf client."""
600
+ return osc_client
601
+
602
+ @app.get("/config/{key}")
603
+ async def get_config(
604
+ key: str,
605
+ client: OpenSecureConfClient = Depends(get_client)
606
+ ) -> Dict:
607
+ """Get configuration from OpenSecureConf."""
608
+ try:
609
+ config = client.read(key)
610
+ return config['value']
611
+ except Exception as e:
612
+ raise HTTPException(status_code=404, detail=str(e))
613
+
614
+ @app.on_event("shutdown")
615
+ async def shutdown_event():
616
+ """Close client on shutdown."""
617
+ osc_client.close()
618
+ ```
619
+
620
+ ## Security Best Practices
621
+
622
+ ### Credentials from AWS Secrets Manager
623
+
624
+ ```python
625
+ import boto3
626
+ from opensecureconf_client_enhanced import OpenSecureConfClient
627
+ import json
628
+
629
+ def get_credentials_from_aws():
630
+ """Get credentials from AWS Secrets Manager."""
631
+ client = boto3.client('secretsmanager', region_name='us-east-1')
632
+ secret = client.get_secret_value(SecretId='opensecureconf/credentials')
633
+ return json.loads(secret['SecretString'])
634
+
635
+ # Initialize client with AWS credentials
636
+ creds = get_credentials_from_aws()
637
+ osc_client = OpenSecureConfClient(
638
+ base_url=creds['url'],
639
+ user_key=creds['user_key'],
640
+ api_key=creds['api_key'],
641
+ enable_retry=True
642
+ )
643
+ ```
644
+
645
+ ### Credentials from HashiCorp Vault
646
+
647
+ ```python
648
+ import hvac
649
+ from opensecureconf_client_enhanced import OpenSecureConfClient
650
+
651
+ def get_credentials_from_vault():
652
+ """Get credentials from HashiCorp Vault."""
653
+ client = hvac.Client(url='https://vault.example.com')
654
+ client.auth.approle.login(
655
+ role_id='your-role-id',
656
+ secret_id='your-secret-id'
657
+ )
658
+
659
+ secret = client.secrets.kv.v2.read_secret_version(
660
+ path='opensecureconf/credentials'
661
+ )
662
+ return secret['data']['data']
663
+
664
+ # Initialize client with Vault credentials
665
+ creds = get_credentials_from_vault()
666
+ osc_client = OpenSecureConfClient(
667
+ base_url=creds['url'],
668
+ user_key=creds['user_key'],
669
+ api_key=creds['api_key'],
670
+ enable_retry=True
671
+ )
672
+ ```
673
+
674
+ ### Audit Logging Wrapper
675
+
676
+ ```python
677
+ from opensecureconf_client_enhanced import OpenSecureConfClient
678
+ import logging
679
+ from functools import wraps
680
+ from datetime import datetime
681
+
682
+ class AuditedClient:
683
+ """Wrapper that logs all operations for auditing."""
684
+
685
+ def __init__(self, client: OpenSecureConfClient, audit_logger: logging.Logger):
686
+ self.client = client
687
+ self.audit_logger = audit_logger
688
+
689
+ def _audit_log(self, operation: str, key: str, success: bool, error: str = None):
690
+ """Log operation for audit trail."""
691
+ self.audit_logger.info({
692
+ "timestamp": datetime.utcnow().isoformat(),
693
+ "operation": operation,
694
+ "key": key,
695
+ "success": success,
696
+ "error": error
697
+ })
698
+
699
+ def create(self, key: str, value: dict, category: str = None):
700
+ """Create with audit logging."""
701
+ try:
702
+ result = self.client.create(key, value, category)
703
+ self._audit_log("CREATE", key, True)
704
+ return result
705
+ except Exception as e:
706
+ self._audit_log("CREATE", key, False, str(e))
707
+ raise
708
+
709
+ def read(self, key: str):
710
+ """Read with audit logging."""
711
+ try:
712
+ result = self.client.read(key)
713
+ self._audit_log("READ", key, True)
714
+ return result
715
+ except Exception as e:
716
+ self._audit_log("READ", key, False, str(e))
717
+ raise
718
+
719
+ def update(self, key: str, value: dict, category: str = None):
720
+ """Update with audit logging."""
721
+ try:
722
+ result = self.client.update(key, value, category)
723
+ self._audit_log("UPDATE", key, True)
724
+ return result
725
+ except Exception as e:
726
+ self._audit_log("UPDATE", key, False, str(e))
727
+ raise
728
+
729
+ def delete(self, key: str):
730
+ """Delete with audit logging."""
731
+ try:
732
+ result = self.client.delete(key)
733
+ self._audit_log("DELETE", key, True)
734
+ return result
735
+ except Exception as e:
736
+ self._audit_log("DELETE", key, False, str(e))
737
+ raise
738
+
739
+ # Usage
740
+ audit_logger = logging.getLogger('opensecureconf.audit')
741
+ audit_logger.setLevel(logging.INFO)
742
+ handler = logging.FileHandler('/var/log/osc-audit.log')
743
+ audit_logger.addHandler(handler)
744
+
745
+ client = OpenSecureConfClient(base_url="...", user_key="...")
746
+ audited_client = AuditedClient(client, audit_logger)
747
+
748
+ # All operations are now audited
749
+ audited_client.create("secret", {"password": "..."})
750
+ ```
751
+
752
+ ---
753
+
754
+ These advanced examples demonstrate production-ready patterns for using the OpenSecureConf Python Client in real-world scenarios. Adapt them to your specific needs!