opensecureconf-client 2.0.2__tar.gz → 2.3.0__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.
- {opensecureconf_client-2.0.2/opensecureconf_client.egg-info → opensecureconf_client-2.3.0}/PKG-INFO +1 -1
- {opensecureconf_client-2.0.2 → opensecureconf_client-2.3.0/opensecureconf_client.egg-info}/PKG-INFO +1 -1
- {opensecureconf_client-2.0.2 → opensecureconf_client-2.3.0}/opensecureconf_client.py +58 -55
- {opensecureconf_client-2.0.2 → opensecureconf_client-2.3.0}/pyproject.toml +1 -1
- {opensecureconf_client-2.0.2 → opensecureconf_client-2.3.0}/ADVANCED_EXAMPLES.md +0 -0
- {opensecureconf_client-2.0.2 → opensecureconf_client-2.3.0}/LICENSE +0 -0
- {opensecureconf_client-2.0.2 → opensecureconf_client-2.3.0}/MANIFEST.in +0 -0
- {opensecureconf_client-2.0.2 → opensecureconf_client-2.3.0}/README.md +0 -0
- {opensecureconf_client-2.0.2 → opensecureconf_client-2.3.0}/example_enhanced_usage.py +0 -0
- {opensecureconf_client-2.0.2 → opensecureconf_client-2.3.0}/example_usage.py +0 -0
- {opensecureconf_client-2.0.2 → opensecureconf_client-2.3.0}/opensecureconf_client.egg-info/SOURCES.txt +0 -0
- {opensecureconf_client-2.0.2 → opensecureconf_client-2.3.0}/opensecureconf_client.egg-info/dependency_links.txt +0 -0
- {opensecureconf_client-2.0.2 → opensecureconf_client-2.3.0}/opensecureconf_client.egg-info/requires.txt +0 -0
- {opensecureconf_client-2.0.2 → opensecureconf_client-2.3.0}/opensecureconf_client.egg-info/top_level.txt +0 -0
- {opensecureconf_client-2.0.2 → opensecureconf_client-2.3.0}/setup.cfg +0 -0
- {opensecureconf_client-2.0.2 → opensecureconf_client-2.3.0}/setup.py +0 -0
{opensecureconf_client-2.0.2/opensecureconf_client.egg-info → opensecureconf_client-2.3.0}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: opensecureconf-client
|
|
3
|
-
Version: 2.0
|
|
3
|
+
Version: 2.3.0
|
|
4
4
|
Summary: Python client library for OpenSecureConf encrypted configuration management API with clustering support
|
|
5
5
|
Author-email: Alessandro Pioli <alessandro.pioli+apioli-pypi@gmail.com>
|
|
6
6
|
Maintainer-email: Alessandro Pioli <alessandro.pioli+apioli-pypi@gmail.com>
|
{opensecureconf_client-2.0.2 → opensecureconf_client-2.3.0/opensecureconf_client.egg-info}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: opensecureconf-client
|
|
3
|
-
Version: 2.0
|
|
3
|
+
Version: 2.3.0
|
|
4
4
|
Summary: Python client library for OpenSecureConf encrypted configuration management API with clustering support
|
|
5
5
|
Author-email: Alessandro Pioli <alessandro.pioli+apioli-pypi@gmail.com>
|
|
6
6
|
Maintainer-email: Alessandro Pioli <alessandro.pioli+apioli-pypi@gmail.com>
|
|
@@ -12,9 +12,10 @@ Enhanced Features:
|
|
|
12
12
|
- Batch operations
|
|
13
13
|
- Enhanced input validation
|
|
14
14
|
- Health check utilities
|
|
15
|
+
- Support for multiple value types (dict, str, int, bool, list)
|
|
15
16
|
"""
|
|
16
17
|
|
|
17
|
-
from typing import Any, Dict, List, Optional
|
|
18
|
+
from typing import Any, Dict, List, Optional, Union
|
|
18
19
|
import logging
|
|
19
20
|
import time
|
|
20
21
|
import requests
|
|
@@ -22,7 +23,6 @@ from requests.adapters import HTTPAdapter
|
|
|
22
23
|
from requests.exceptions import Timeout, RequestException
|
|
23
24
|
from urllib3.util.retry import Retry
|
|
24
25
|
|
|
25
|
-
|
|
26
26
|
# ============================================================================
|
|
27
27
|
# EXCEPTIONS
|
|
28
28
|
# ============================================================================
|
|
@@ -30,23 +30,18 @@ from urllib3.util.retry import Retry
|
|
|
30
30
|
class OpenSecureConfError(Exception):
|
|
31
31
|
"""Base exception for OpenSecureConf client errors."""
|
|
32
32
|
|
|
33
|
-
|
|
34
33
|
class AuthenticationError(OpenSecureConfError):
|
|
35
34
|
"""Raised when authentication fails (invalid or missing user key)."""
|
|
36
35
|
|
|
37
|
-
|
|
38
36
|
class ConfigurationNotFoundError(OpenSecureConfError):
|
|
39
37
|
"""Raised when a requested configuration key does not exist."""
|
|
40
38
|
|
|
41
|
-
|
|
42
39
|
class ConfigurationExistsError(OpenSecureConfError):
|
|
43
40
|
"""Raised when attempting to create a configuration that already exists."""
|
|
44
41
|
|
|
45
|
-
|
|
46
42
|
class ClusterError(OpenSecureConfError):
|
|
47
43
|
"""Raised when cluster operations fail."""
|
|
48
44
|
|
|
49
|
-
|
|
50
45
|
# ============================================================================
|
|
51
46
|
# CLIENT
|
|
52
47
|
# ============================================================================
|
|
@@ -73,9 +68,14 @@ class OpenSecureConfClient:
|
|
|
73
68
|
... enable_retry=True,
|
|
74
69
|
... log_level="INFO"
|
|
75
70
|
... )
|
|
71
|
+
>>> # Dict value
|
|
76
72
|
>>> config = client.create("database", {"host": "localhost", "port": 5432})
|
|
77
|
-
>>>
|
|
78
|
-
|
|
73
|
+
>>> # String value
|
|
74
|
+
>>> config = client.create("api_token", "secret-token-123")
|
|
75
|
+
>>> # Int value
|
|
76
|
+
>>> config = client.create("max_connections", 100)
|
|
77
|
+
>>> # Bool value
|
|
78
|
+
>>> config = client.create("debug_mode", True)
|
|
79
79
|
"""
|
|
80
80
|
|
|
81
81
|
def __init__(
|
|
@@ -171,12 +171,10 @@ class OpenSecureConfClient:
|
|
|
171
171
|
"x-user-key": self.user_key,
|
|
172
172
|
"Content-Type": "application/json"
|
|
173
173
|
}
|
|
174
|
-
|
|
175
174
|
if self.api_key:
|
|
176
175
|
headers["X-API-Key"] = self.api_key
|
|
177
176
|
|
|
178
177
|
self._session.headers.update(headers)
|
|
179
|
-
|
|
180
178
|
self.logger.info(f"Client initialized for {self.base_url}")
|
|
181
179
|
|
|
182
180
|
def _make_request(self, method: str, endpoint: str, **kwargs) -> Any:
|
|
@@ -208,7 +206,6 @@ class OpenSecureConfClient:
|
|
|
208
206
|
try:
|
|
209
207
|
response = self._session.request(method, url, **kwargs)
|
|
210
208
|
duration = time.time() - start_time
|
|
211
|
-
|
|
212
209
|
self.logger.info(
|
|
213
210
|
f"{method} {endpoint} - Status: {response.status_code} - Duration: {duration:.3f}s"
|
|
214
211
|
)
|
|
@@ -295,7 +292,7 @@ class OpenSecureConfClient:
|
|
|
295
292
|
Example:
|
|
296
293
|
>>> info = client.get_service_info()
|
|
297
294
|
>>> print(info["version"])
|
|
298
|
-
2.
|
|
295
|
+
2.2.0
|
|
299
296
|
"""
|
|
300
297
|
return self._make_request("GET", "/")
|
|
301
298
|
|
|
@@ -350,9 +347,9 @@ class OpenSecureConfClient:
|
|
|
350
347
|
# ========================================================================
|
|
351
348
|
|
|
352
349
|
def create(
|
|
353
|
-
self,
|
|
354
|
-
key: str,
|
|
355
|
-
value: Dict[str, Any],
|
|
350
|
+
self,
|
|
351
|
+
key: str,
|
|
352
|
+
value: Union[Dict[str, Any], str, int, bool, list],
|
|
356
353
|
category: Optional[str] = None
|
|
357
354
|
) -> Dict[str, Any]:
|
|
358
355
|
"""
|
|
@@ -360,7 +357,7 @@ class OpenSecureConfClient:
|
|
|
360
357
|
|
|
361
358
|
Args:
|
|
362
359
|
key: Unique configuration key (1-255 characters)
|
|
363
|
-
value: Configuration data
|
|
360
|
+
value: Configuration data (dict, string, int, bool, or list - will be encrypted)
|
|
364
361
|
category: Optional category for grouping (max 100 characters)
|
|
365
362
|
|
|
366
363
|
Returns:
|
|
@@ -372,22 +369,25 @@ class OpenSecureConfClient:
|
|
|
372
369
|
|
|
373
370
|
Raises:
|
|
374
371
|
ConfigurationExistsError: If configuration key already exists
|
|
375
|
-
ValueError: If key
|
|
372
|
+
ValueError: If key is invalid
|
|
376
373
|
|
|
377
374
|
Example:
|
|
378
|
-
>>>
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
375
|
+
>>> # Dict value
|
|
376
|
+
>>> config = client.create("database", {"host": "localhost", "port": 5432}, "prod")
|
|
377
|
+
>>> # String value
|
|
378
|
+
>>> config = client.create("api_token", "secret-token-123", "auth")
|
|
379
|
+
>>> # Integer value
|
|
380
|
+
>>> config = client.create("max_retries", 3)
|
|
381
|
+
>>> # Boolean value
|
|
382
|
+
>>> config = client.create("debug_enabled", False)
|
|
383
|
+
>>> # List value
|
|
384
|
+
>>> config = client.create("allowed_ips", ["192.168.1.1", "10.0.0.1"])
|
|
383
385
|
"""
|
|
384
386
|
# Enhanced validation
|
|
385
387
|
if not key or not isinstance(key, str):
|
|
386
388
|
raise ValueError("Key must be a non-empty string")
|
|
387
389
|
if len(key) > 255:
|
|
388
390
|
raise ValueError("Key must be between 1 and 255 characters")
|
|
389
|
-
if not isinstance(value, dict):
|
|
390
|
-
raise ValueError("Value must be a dictionary")
|
|
391
391
|
if category and len(category) > 100:
|
|
392
392
|
raise ValueError("Category must be max 100 characters")
|
|
393
393
|
|
|
@@ -403,6 +403,7 @@ class OpenSecureConfClient:
|
|
|
403
403
|
|
|
404
404
|
Returns:
|
|
405
405
|
Dictionary containing the configuration with decrypted value
|
|
406
|
+
The value can be dict, str, int, bool, or list depending on what was stored
|
|
406
407
|
|
|
407
408
|
Raises:
|
|
408
409
|
ConfigurationNotFoundError: If configuration key does not exist
|
|
@@ -410,8 +411,7 @@ class OpenSecureConfClient:
|
|
|
410
411
|
|
|
411
412
|
Example:
|
|
412
413
|
>>> config = client.read("database")
|
|
413
|
-
>>> print(config["value"]
|
|
414
|
-
localhost
|
|
414
|
+
>>> print(config["value"]) # Could be any supported type
|
|
415
415
|
"""
|
|
416
416
|
if not key or not isinstance(key, str):
|
|
417
417
|
raise ValueError("Key must be a non-empty string")
|
|
@@ -419,9 +419,9 @@ class OpenSecureConfClient:
|
|
|
419
419
|
return self._make_request("GET", f"/configs/{key}")
|
|
420
420
|
|
|
421
421
|
def update(
|
|
422
|
-
self,
|
|
423
|
-
key: str,
|
|
424
|
-
value: Dict[str, Any],
|
|
422
|
+
self,
|
|
423
|
+
key: str,
|
|
424
|
+
value: Union[Dict[str, Any], str, int, bool, list],
|
|
425
425
|
category: Optional[str] = None
|
|
426
426
|
) -> Dict[str, Any]:
|
|
427
427
|
"""
|
|
@@ -429,7 +429,7 @@ class OpenSecureConfClient:
|
|
|
429
429
|
|
|
430
430
|
Args:
|
|
431
431
|
key: Configuration key to update
|
|
432
|
-
value: New configuration data
|
|
432
|
+
value: New configuration data (dict, string, int, bool, or list - will be encrypted)
|
|
433
433
|
category: Optional new category
|
|
434
434
|
|
|
435
435
|
Returns:
|
|
@@ -437,18 +437,18 @@ class OpenSecureConfClient:
|
|
|
437
437
|
|
|
438
438
|
Raises:
|
|
439
439
|
ConfigurationNotFoundError: If configuration key does not exist
|
|
440
|
-
ValueError: If
|
|
440
|
+
ValueError: If key is invalid
|
|
441
441
|
|
|
442
442
|
Example:
|
|
443
|
-
>>>
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
443
|
+
>>> # Update with dict
|
|
444
|
+
>>> config = client.update("database", {"host": "db.example.com", "port": 5432})
|
|
445
|
+
>>> # Update with string
|
|
446
|
+
>>> config = client.update("api_token", "new-token-456")
|
|
447
|
+
>>> # Update with int
|
|
448
|
+
>>> config = client.update("timeout", 60)
|
|
447
449
|
"""
|
|
448
450
|
if not key or not isinstance(key, str):
|
|
449
451
|
raise ValueError("Key must be a non-empty string")
|
|
450
|
-
if not isinstance(value, dict):
|
|
451
|
-
raise ValueError("Value must be a dictionary")
|
|
452
452
|
if category and len(category) > 100:
|
|
453
453
|
raise ValueError("Category must be max 100 characters")
|
|
454
454
|
|
|
@@ -489,6 +489,7 @@ class OpenSecureConfClient:
|
|
|
489
489
|
|
|
490
490
|
Returns:
|
|
491
491
|
List of configuration dictionaries with decrypted values
|
|
492
|
+
Each value can be dict, str, int, bool, or list
|
|
492
493
|
|
|
493
494
|
Example:
|
|
494
495
|
>>> configs = client.list_all(category="production")
|
|
@@ -503,8 +504,8 @@ class OpenSecureConfClient:
|
|
|
503
504
|
# ========================================================================
|
|
504
505
|
|
|
505
506
|
def bulk_create(
|
|
506
|
-
self,
|
|
507
|
-
configs: List[Dict[str, Any]],
|
|
507
|
+
self,
|
|
508
|
+
configs: List[Dict[str, Any]],
|
|
508
509
|
ignore_errors: bool = False
|
|
509
510
|
) -> List[Dict[str, Any]]:
|
|
510
511
|
"""
|
|
@@ -512,6 +513,7 @@ class OpenSecureConfClient:
|
|
|
512
513
|
|
|
513
514
|
Args:
|
|
514
515
|
configs: List of configuration dictionaries with 'key', 'value', and optional 'category'
|
|
516
|
+
Value can be dict, str, int, bool, or list
|
|
515
517
|
ignore_errors: If True, continue on errors and return partial results
|
|
516
518
|
|
|
517
519
|
Returns:
|
|
@@ -524,7 +526,8 @@ class OpenSecureConfClient:
|
|
|
524
526
|
Example:
|
|
525
527
|
>>> configs = [
|
|
526
528
|
... {"key": "db1", "value": {"host": "localhost"}, "category": "prod"},
|
|
527
|
-
... {"key": "
|
|
529
|
+
... {"key": "token", "value": "secret-123", "category": "auth"},
|
|
530
|
+
... {"key": "retries", "value": 3, "category": "config"}
|
|
528
531
|
... ]
|
|
529
532
|
>>> results = client.bulk_create(configs)
|
|
530
533
|
>>> print(f"Created {len(results)} configurations")
|
|
@@ -562,8 +565,8 @@ class OpenSecureConfClient:
|
|
|
562
565
|
return results
|
|
563
566
|
|
|
564
567
|
def bulk_read(
|
|
565
|
-
self,
|
|
566
|
-
keys: List[str],
|
|
568
|
+
self,
|
|
569
|
+
keys: List[str],
|
|
567
570
|
ignore_errors: bool = False
|
|
568
571
|
) -> List[Dict[str, Any]]:
|
|
569
572
|
"""
|
|
@@ -577,7 +580,7 @@ class OpenSecureConfClient:
|
|
|
577
580
|
List of configuration dictionaries
|
|
578
581
|
|
|
579
582
|
Example:
|
|
580
|
-
>>> configs = client.bulk_read(["db1", "
|
|
583
|
+
>>> configs = client.bulk_read(["db1", "token", "retries"])
|
|
581
584
|
>>> print(f"Retrieved {len(configs)} configurations")
|
|
582
585
|
"""
|
|
583
586
|
if not isinstance(keys, list):
|
|
@@ -604,8 +607,8 @@ class OpenSecureConfClient:
|
|
|
604
607
|
return results
|
|
605
608
|
|
|
606
609
|
def bulk_delete(
|
|
607
|
-
self,
|
|
608
|
-
keys: List[str],
|
|
610
|
+
self,
|
|
611
|
+
keys: List[str],
|
|
609
612
|
ignore_errors: bool = False
|
|
610
613
|
) -> Dict[str, Any]:
|
|
611
614
|
"""
|
|
@@ -666,25 +669,25 @@ class OpenSecureConfClient:
|
|
|
666
669
|
return False
|
|
667
670
|
|
|
668
671
|
def get_or_default(
|
|
669
|
-
self,
|
|
670
|
-
key: str,
|
|
671
|
-
default: Dict[str, Any]
|
|
672
|
+
self,
|
|
673
|
+
key: str,
|
|
674
|
+
default: Union[Dict[str, Any], str, int, bool, list]
|
|
672
675
|
) -> Dict[str, Any]:
|
|
673
676
|
"""
|
|
674
677
|
Get configuration value or return default if not found.
|
|
675
678
|
|
|
676
679
|
Args:
|
|
677
680
|
key: Configuration key to retrieve
|
|
678
|
-
default: Default value to return if key not found
|
|
681
|
+
default: Default value to return if key not found (any supported type)
|
|
679
682
|
|
|
680
683
|
Returns:
|
|
681
|
-
Configuration dictionary or default value
|
|
684
|
+
Configuration dictionary or default value wrapped in dict format
|
|
682
685
|
|
|
683
686
|
Example:
|
|
684
|
-
>>>
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
687
|
+
>>> # Dict default
|
|
688
|
+
>>> config = client.get_or_default("database", {"host": "localhost", "port": 5432})
|
|
689
|
+
>>> # String default
|
|
690
|
+
>>> config = client.get_or_default("token", "default-token")
|
|
688
691
|
"""
|
|
689
692
|
try:
|
|
690
693
|
return self.read(key)
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "opensecureconf-client"
|
|
7
|
-
version = "2.0
|
|
7
|
+
version = "2.3.0"
|
|
8
8
|
description = "Python client library for OpenSecureConf encrypted configuration management API with clustering support"
|
|
9
9
|
readme = "README.md" # Updated to use the complete README
|
|
10
10
|
requires-python = ">=3.8"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|