provide-foundation 0.0.0.dev1__py3-none-any.whl → 0.0.0.dev2__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 (93) hide show
  1. provide/foundation/__init__.py +29 -3
  2. provide/foundation/archive/operations.py +4 -6
  3. provide/foundation/cli/__init__.py +2 -2
  4. provide/foundation/cli/commands/deps.py +13 -7
  5. provide/foundation/cli/commands/logs/__init__.py +1 -1
  6. provide/foundation/cli/commands/logs/query.py +1 -1
  7. provide/foundation/cli/commands/logs/send.py +1 -1
  8. provide/foundation/cli/commands/logs/tail.py +1 -1
  9. provide/foundation/cli/decorators.py +11 -10
  10. provide/foundation/cli/main.py +1 -1
  11. provide/foundation/cli/testing.py +2 -35
  12. provide/foundation/cli/utils.py +21 -17
  13. provide/foundation/config/__init__.py +35 -2
  14. provide/foundation/config/converters.py +479 -0
  15. provide/foundation/config/defaults.py +67 -0
  16. provide/foundation/config/env.py +4 -19
  17. provide/foundation/config/loader.py +9 -3
  18. provide/foundation/console/input.py +5 -5
  19. provide/foundation/console/output.py +35 -13
  20. provide/foundation/context/__init__.py +8 -4
  21. provide/foundation/context/core.py +85 -109
  22. provide/foundation/crypto/certificates/operations.py +1 -1
  23. provide/foundation/errors/__init__.py +2 -3
  24. provide/foundation/errors/decorators.py +0 -231
  25. provide/foundation/errors/types.py +0 -97
  26. provide/foundation/file/directory.py +13 -22
  27. provide/foundation/file/lock.py +3 -1
  28. provide/foundation/hub/components.py +72 -384
  29. provide/foundation/hub/config.py +151 -0
  30. provide/foundation/hub/discovery.py +62 -0
  31. provide/foundation/hub/handlers.py +81 -0
  32. provide/foundation/hub/lifecycle.py +194 -0
  33. provide/foundation/hub/manager.py +4 -4
  34. provide/foundation/hub/processors.py +44 -0
  35. provide/foundation/integrations/__init__.py +11 -0
  36. provide/foundation/{observability → integrations}/openobserve/__init__.py +10 -7
  37. provide/foundation/{observability → integrations}/openobserve/auth.py +1 -1
  38. provide/foundation/{observability → integrations}/openobserve/client.py +12 -12
  39. provide/foundation/{observability → integrations}/openobserve/commands.py +3 -3
  40. provide/foundation/integrations/openobserve/config.py +37 -0
  41. provide/foundation/{observability → integrations}/openobserve/formatters.py +1 -1
  42. provide/foundation/{observability → integrations}/openobserve/otlp.py +1 -1
  43. provide/foundation/{observability → integrations}/openobserve/search.py +2 -2
  44. provide/foundation/{observability → integrations}/openobserve/streaming.py +4 -4
  45. provide/foundation/logger/config/logging.py +68 -298
  46. provide/foundation/logger/config/telemetry.py +41 -121
  47. provide/foundation/logger/setup/coordinator.py +1 -1
  48. provide/foundation/observability/__init__.py +2 -2
  49. provide/foundation/process/__init__.py +9 -0
  50. provide/foundation/process/exit.py +47 -0
  51. provide/foundation/process/lifecycle.py +33 -33
  52. provide/foundation/resilience/__init__.py +35 -0
  53. provide/foundation/resilience/circuit.py +164 -0
  54. provide/foundation/resilience/decorators.py +220 -0
  55. provide/foundation/resilience/fallback.py +193 -0
  56. provide/foundation/resilience/retry.py +325 -0
  57. provide/foundation/streams/config.py +79 -0
  58. provide/foundation/streams/console.py +7 -8
  59. provide/foundation/streams/core.py +6 -3
  60. provide/foundation/streams/file.py +12 -2
  61. provide/foundation/testing/__init__.py +7 -2
  62. provide/foundation/testing/cli.py +30 -17
  63. provide/foundation/testing/common/__init__.py +0 -2
  64. provide/foundation/testing/common/fixtures.py +0 -27
  65. provide/foundation/testing/file/content_fixtures.py +316 -0
  66. provide/foundation/testing/file/directory_fixtures.py +107 -0
  67. provide/foundation/testing/file/fixtures.py +45 -516
  68. provide/foundation/testing/file/special_fixtures.py +153 -0
  69. provide/foundation/testing/logger.py +76 -0
  70. provide/foundation/testing/process/async_fixtures.py +405 -0
  71. provide/foundation/testing/process/fixtures.py +50 -571
  72. provide/foundation/testing/process/subprocess_fixtures.py +209 -0
  73. provide/foundation/testing/threading/basic_fixtures.py +101 -0
  74. provide/foundation/testing/threading/data_fixtures.py +99 -0
  75. provide/foundation/testing/threading/execution_fixtures.py +263 -0
  76. provide/foundation/testing/threading/fixtures.py +34 -500
  77. provide/foundation/testing/threading/sync_fixtures.py +97 -0
  78. provide/foundation/testing/time/fixtures.py +4 -4
  79. provide/foundation/tools/cache.py +8 -6
  80. provide/foundation/tools/downloader.py +23 -12
  81. provide/foundation/tracer/spans.py +2 -2
  82. provide/foundation/transport/config.py +26 -95
  83. provide/foundation/transport/middleware.py +30 -36
  84. provide/foundation/utils/deps.py +14 -12
  85. provide/foundation/utils/parsing.py +49 -4
  86. {provide_foundation-0.0.0.dev1.dist-info → provide_foundation-0.0.0.dev2.dist-info}/METADATA +1 -1
  87. {provide_foundation-0.0.0.dev1.dist-info → provide_foundation-0.0.0.dev2.dist-info}/RECORD +93 -68
  88. /provide/foundation/{observability → integrations}/openobserve/exceptions.py +0 -0
  89. /provide/foundation/{observability → integrations}/openobserve/models.py +0 -0
  90. {provide_foundation-0.0.0.dev1.dist-info → provide_foundation-0.0.0.dev2.dist-info}/WHEEL +0 -0
  91. {provide_foundation-0.0.0.dev1.dist-info → provide_foundation-0.0.0.dev2.dist-info}/entry_points.txt +0 -0
  92. {provide_foundation-0.0.0.dev1.dist-info → provide_foundation-0.0.0.dev2.dist-info}/licenses/LICENSE +0 -0
  93. {provide_foundation-0.0.0.dev1.dist-info → provide_foundation-0.0.0.dev2.dist-info}/top_level.txt +0 -0
@@ -9,12 +9,12 @@ Primary public interface for the library, re-exporting common components.
9
9
  # Export config module for easy access
10
10
  # New foundation components
11
11
  # Make the errors module available for detailed imports
12
- from provide.foundation import config, errors, platform, process
12
+ from provide.foundation import config, errors, platform, process, resilience
13
13
  from provide.foundation._version import __version__
14
14
 
15
15
  # Console I/O functions (always available - handles click dependency internally)
16
16
  from provide.foundation.console import perr, pin, pout
17
- from provide.foundation.context import Context
17
+ from provide.foundation.context import CLIContext, Context
18
18
 
19
19
  # Error handling exports - only the essentials
20
20
  from provide.foundation.errors import (
@@ -27,6 +27,19 @@ from provide.foundation.errors import (
27
27
  with_error_handling,
28
28
  )
29
29
 
30
+ # Resilience exports
31
+ from provide.foundation.resilience import (
32
+ retry,
33
+ circuit_breaker,
34
+ fallback,
35
+ RetryPolicy,
36
+ RetryExecutor,
37
+ BackoffStrategy,
38
+ CircuitBreaker,
39
+ CircuitState,
40
+ FallbackChain,
41
+ )
42
+
30
43
  # Hub and Registry exports (public API)
31
44
  from provide.foundation.hub.components import ComponentCategory, get_component_registry
32
45
  from provide.foundation.hub.manager import Hub, clear_hub, get_hub
@@ -92,7 +105,8 @@ __all__ = [
92
105
  "show_event_matrix",
93
106
  "ConsoleFormatterStr",
94
107
  # New foundation modules
95
- "Context",
108
+ "CLIContext",
109
+ "Context", # Backward compatibility
96
110
  # Event set types
97
111
  "EventMapping",
98
112
  "EventSet",
@@ -129,7 +143,19 @@ __all__ = [
129
143
  "pout",
130
144
  "platform",
131
145
  "process",
146
+ # Resilience patterns
147
+ "retry",
148
+ "circuit_breaker",
149
+ "fallback",
150
+ "RetryPolicy",
151
+ "RetryExecutor",
152
+ "BackoffStrategy",
153
+ "CircuitBreaker",
154
+ "CircuitState",
155
+ "FallbackChain",
156
+ # Backward compatibility (deprecated)
132
157
  "retry_on_error",
158
+ "resilience", # The resilience module for detailed imports
133
159
  "setup_logging", # Backward compatibility
134
160
  "setup_logger", # Consistent naming
135
161
  "setup_telemetry",
@@ -2,7 +2,7 @@
2
2
 
3
3
  import tempfile
4
4
  from pathlib import Path
5
- from typing import Callable, Optional
5
+ from typing import Callable
6
6
 
7
7
  from attrs import define, field
8
8
 
@@ -12,6 +12,7 @@ from provide.foundation.archive.gzip import GzipCompressor
12
12
  from provide.foundation.archive.bzip2 import Bzip2Compressor
13
13
  from provide.foundation.archive.zip import ZipArchive
14
14
  from provide.foundation.file import ensure_parent_dir
15
+ from provide.foundation.file.safe import safe_delete
15
16
  from provide.foundation.logger import get_logger
16
17
 
17
18
  logger = get_logger(__name__)
@@ -68,12 +69,9 @@ class OperationChain:
68
69
  except Exception as e:
69
70
  raise ArchiveError(f"Operation chain failed: {e}") from e
70
71
  finally:
71
- # Clean up temp files
72
+ # Clean up temp files using Foundation's safe file operations
72
73
  for temp in temp_files:
73
- try:
74
- temp.unlink()
75
- except Exception:
76
- pass
74
+ safe_delete(temp, missing_ok=True)
77
75
 
78
76
  def reverse(self, source: Path, output: Path) -> Path:
79
77
  """
@@ -17,12 +17,12 @@ from provide.foundation.cli.decorators import (
17
17
  )
18
18
  from provide.foundation.cli.testing import (
19
19
  CliTestCase,
20
- MockContext,
21
20
  create_test_cli,
22
21
  isolated_cli_runner,
23
- mock_logger,
24
22
  temp_config_file,
25
23
  )
24
+ from provide.foundation.testing.cli import MockContext
25
+ from provide.foundation.testing.logger import mock_logger
26
26
  from provide.foundation.cli.utils import (
27
27
  CliTestRunner,
28
28
  assert_cli_error,
@@ -8,7 +8,9 @@ except ImportError:
8
8
  click = None
9
9
  _HAS_CLICK = False
10
10
 
11
- from provide.foundation.utils.deps import check_optional_deps
11
+ from provide.foundation.utils.deps import check_optional_deps, has_dependency
12
+ from provide.foundation.console.output import pout
13
+ from provide.foundation.process import exit_success, exit_error
12
14
 
13
15
 
14
16
  def _require_click():
@@ -23,21 +25,25 @@ def _require_click():
23
25
  def _deps_command_impl(quiet: bool, check: str | None) -> None:
24
26
  """Implementation of deps command logic."""
25
27
  if check:
26
- from provide.foundation.utils.deps import has_dependency
27
-
28
28
  available = has_dependency(check)
29
29
  if not quiet:
30
30
  status = "✅" if available else "❌"
31
- print(f"{status} {check}: {'Available' if available else 'Missing'}")
31
+ pout(f"{status} {check}: {'Available' if available else 'Missing'}")
32
32
  if not available:
33
- print(f"Install with: pip install 'provide-foundation[{check}]'")
34
- exit(0 if available else 1)
33
+ pout(f"Install with: pip install 'provide-foundation[{check}]'")
34
+ if available:
35
+ exit_success()
36
+ else:
37
+ exit_error("Dependency check failed")
35
38
  else:
36
39
  # Check all dependencies
37
40
  deps = check_optional_deps(quiet=quiet, return_status=True)
38
41
  available_count = sum(1 for dep in deps if dep.available)
39
42
  total_count = len(deps)
40
- exit(0 if available_count == total_count else 1)
43
+ if available_count == total_count:
44
+ exit_success()
45
+ else:
46
+ exit_error(f"Missing {total_count - available_count} dependencies")
41
47
 
42
48
 
43
49
  if _HAS_CLICK:
@@ -28,7 +28,7 @@ if _HAS_CLICK:
28
28
 
29
29
  # Try to get OpenObserve client if available
30
30
  try:
31
- from provide.foundation.observability.openobserve import OpenObserveClient
31
+ from provide.foundation.integrations.openobserve import OpenObserveClient
32
32
 
33
33
  ctx.obj["client"] = OpenObserveClient.from_config()
34
34
  except Exception as e:
@@ -89,7 +89,7 @@ if _HAS_CLICK:
89
89
  # Custom SQL query
90
90
  foundation logs query --sql "SELECT * FROM default WHERE duration_ms > 1000"
91
91
  """
92
- from provide.foundation.observability.openobserve import (
92
+ from provide.foundation.integrations.openobserve import (
93
93
  format_output,
94
94
  search_logs,
95
95
  )
@@ -83,7 +83,7 @@ if _HAS_CLICK:
83
83
  # Send with JSON attributes
84
84
  foundation logs send -m "Error occurred" -j '{"error_code": 500, "path": "/api/users"}'
85
85
  """
86
- from provide.foundation.observability.openobserve.otlp import send_log
86
+ from provide.foundation.integrations.openobserve.otlp import send_log
87
87
 
88
88
  # Get message from stdin if not provided
89
89
  if not message:
@@ -69,7 +69,7 @@ if _HAS_CLICK:
69
69
  # Tail with JSON output
70
70
  foundation logs tail --format json
71
71
  """
72
- from provide.foundation.observability.openobserve import (
72
+ from provide.foundation.integrations.openobserve import (
73
73
  format_output,
74
74
  tail_logs,
75
75
  )
@@ -11,7 +11,8 @@ try:
11
11
  except ImportError:
12
12
  click = None
13
13
 
14
- from provide.foundation.context import Context
14
+ from provide.foundation.context import CLIContext
15
+ from provide.foundation.process import exit_error, exit_interrupted
15
16
 
16
17
  F = TypeVar("F", bound=Callable[..., Any])
17
18
 
@@ -162,7 +163,7 @@ def error_handler(f: F) -> F:
162
163
  except KeyboardInterrupt:
163
164
  if not json_output:
164
165
  click.secho("\nInterrupted by user", fg="yellow", err=True)
165
- sys.exit(130) # Standard exit code for SIGINT
166
+ exit_interrupted()
166
167
  except Exception as e:
167
168
  if debug:
168
169
  # In debug mode, show full traceback
@@ -179,16 +180,16 @@ def error_handler(f: F) -> F:
179
180
  else:
180
181
  click.secho(f"Error: {e}", fg="red", err=True)
181
182
 
182
- sys.exit(1)
183
+ exit_error(f"Command failed: {str(e)}")
183
184
 
184
185
  return wrapper
185
186
 
186
187
 
187
188
  def pass_context(f: F) -> F:
188
189
  """
189
- Decorator to pass the foundation Context to a command.
190
+ Decorator to pass the foundation CLIContext to a command.
190
191
 
191
- Creates or retrieves a Context from Click's context object
192
+ Creates or retrieves a CLIContext from Click's context object
192
193
  and passes it as the first argument to the decorated function.
193
194
  """
194
195
 
@@ -197,15 +198,15 @@ def pass_context(f: F) -> F:
197
198
  def wrapper(ctx: click.Context, *args, **kwargs):
198
199
  # Get or create foundation context
199
200
  if not hasattr(ctx, "obj") or ctx.obj is None:
200
- ctx.obj = Context()
201
- elif not isinstance(ctx.obj, Context):
201
+ ctx.obj = CLIContext()
202
+ elif not isinstance(ctx.obj, CLIContext):
202
203
  # If obj exists but isn't a Context, wrap it
203
204
  if isinstance(ctx.obj, dict):
204
- ctx.obj = Context.from_dict(ctx.obj)
205
+ ctx.obj = CLIContext.from_dict(ctx.obj)
205
206
  else:
206
- # Store existing obj and create new Context
207
+ # Store existing obj and create new CLIContext
207
208
  old_obj = ctx.obj
208
- ctx.obj = Context()
209
+ ctx.obj = CLIContext()
209
210
  ctx.obj._cli_data = old_obj
210
211
 
211
212
  # Update context from command options
@@ -46,7 +46,7 @@ if _HAS_CLICK:
46
46
 
47
47
  # Register OpenObserve commands if available
48
48
  try:
49
- from provide.foundation.observability.openobserve.commands import (
49
+ from provide.foundation.integrations.openobserve.commands import (
50
50
  openobserve_group,
51
51
  )
52
52
 
@@ -11,31 +11,12 @@ from unittest.mock import MagicMock
11
11
  import click
12
12
  from click.testing import CliRunner
13
13
 
14
- from provide.foundation.context import Context
14
+ from provide.foundation.context import CLIContext
15
15
  from provide.foundation.logger import get_logger
16
16
 
17
17
  log = get_logger(__name__)
18
18
 
19
19
 
20
- class MockContext(Context):
21
- """Mock context for testing that tracks method calls."""
22
-
23
- def __init__(self, **kwargs) -> None:
24
- """Initialize mock context with tracking."""
25
- super().__init__(**kwargs)
26
- self.calls = []
27
- self.saved_configs = []
28
- self.loaded_configs = []
29
-
30
- def save_config(self, path: str | Path) -> None:
31
- """Track save_config calls."""
32
- self.saved_configs.append(path)
33
- super().save_config(path)
34
-
35
- def load_config(self, path: str | Path) -> None:
36
- """Track load_config calls."""
37
- self.loaded_configs.append(path)
38
- super().load_config(path)
39
20
 
40
21
 
41
22
  @contextmanager
@@ -150,7 +131,7 @@ def create_test_cli(
150
131
  @click.pass_context
151
132
  def cli(ctx, **kwargs) -> None:
152
133
  """Test CLI for testing."""
153
- ctx.obj = Context(**{k: v for k, v in kwargs.items() if v is not None})
134
+ ctx.obj = CLIContext(**{k: v for k, v in kwargs.items() if v is not None})
154
135
 
155
136
  if commands:
156
137
  for cmd in commands:
@@ -159,20 +140,6 @@ def create_test_cli(
159
140
  return cli
160
141
 
161
142
 
162
- def mock_logger():
163
- """
164
- Create a mock logger for testing.
165
-
166
- Returns:
167
- MagicMock with common logger methods
168
- """
169
- mock = MagicMock()
170
- mock.debug = MagicMock()
171
- mock.info = MagicMock()
172
- mock.warning = MagicMock()
173
- mock.error = MagicMock()
174
- mock.critical = MagicMock()
175
- return mock
176
143
 
177
144
 
178
145
  class CliTestCase:
@@ -6,7 +6,8 @@ from typing import Any
6
6
  import click
7
7
  from click.testing import CliRunner, Result
8
8
 
9
- from provide.foundation.context import Context
9
+ from provide.foundation.console.output import pout, perr
10
+ from provide.foundation.context import CLIContext
10
11
  from provide.foundation.logger import (
11
12
  LoggingConfig,
12
13
  TelemetryConfig,
@@ -25,7 +26,10 @@ def echo_json(data: Any, err: bool = False) -> None:
25
26
  data: Data to output as JSON
26
27
  err: Whether to output to stderr
27
28
  """
28
- click.echo(json.dumps(data, indent=2, default=str), err=err)
29
+ if err:
30
+ perr(data)
31
+ else:
32
+ pout(data)
29
33
 
30
34
 
31
35
  def echo_error(message: str, json_output: bool = False) -> None:
@@ -37,9 +41,9 @@ def echo_error(message: str, json_output: bool = False) -> None:
37
41
  json_output: Whether to output as JSON
38
42
  """
39
43
  if json_output:
40
- echo_json({"error": message}, err=True)
44
+ perr(message, json_key="error")
41
45
  else:
42
- click.secho(f"✗ {message}", fg="red", err=True)
46
+ perr(f"✗ {message}", color="red")
43
47
 
44
48
 
45
49
  def echo_success(message: str, json_output: bool = False) -> None:
@@ -51,9 +55,9 @@ def echo_success(message: str, json_output: bool = False) -> None:
51
55
  json_output: Whether to output as JSON
52
56
  """
53
57
  if json_output:
54
- echo_json({"success": message})
58
+ pout(message, json_key="success")
55
59
  else:
56
- click.secho(f"✓ {message}", fg="green")
60
+ pout(f"✓ {message}", color="green")
57
61
 
58
62
 
59
63
  def echo_warning(message: str, json_output: bool = False) -> None:
@@ -65,9 +69,9 @@ def echo_warning(message: str, json_output: bool = False) -> None:
65
69
  json_output: Whether to output as JSON
66
70
  """
67
71
  if json_output:
68
- echo_json({"warning": message}, err=True)
72
+ perr(message, json_key="warning")
69
73
  else:
70
- click.secho(f"⚠ {message}", fg="yellow", err=True)
74
+ perr(f"⚠ {message}", color="yellow")
71
75
 
72
76
 
73
77
  def echo_info(message: str, json_output: bool = False) -> None:
@@ -79,23 +83,23 @@ def echo_info(message: str, json_output: bool = False) -> None:
79
83
  json_output: Whether to output as JSON
80
84
  """
81
85
  if json_output:
82
- echo_json({"info": message})
86
+ pout(message, json_key="info")
83
87
  else:
84
- click.echo(f"ℹ {message}")
88
+ pout(f"ℹ {message}")
85
89
 
86
90
 
87
91
  def setup_cli_logging(
88
- ctx: Context,
92
+ ctx: CLIContext,
89
93
  ) -> None:
90
94
  """
91
- Setup logging for CLI applications using a Context object.
95
+ Setup logging for CLI applications using a CLIContext object.
92
96
 
93
97
  This function is the designated way to configure logging within a CLI
94
98
  application built with foundation. It uses the provided context object
95
99
  to construct a full TelemetryConfig and initializes the system.
96
100
 
97
101
  Args:
98
- ctx: The foundation Context, populated by CLI decorators.
102
+ ctx: The foundation CLIContext, populated by CLI decorators.
99
103
  """
100
104
  console_formatter = "json" if ctx.json_output else ctx.log_format
101
105
 
@@ -116,9 +120,9 @@ def setup_cli_logging(
116
120
  setup_telemetry(config=telemetry_config)
117
121
 
118
122
 
119
- def create_cli_context(**kwargs) -> Context:
123
+ def create_cli_context(**kwargs) -> CLIContext:
120
124
  """
121
- Create a Context for CLI usage.
125
+ Create a CLIContext for CLI usage.
122
126
 
123
127
  Loads from environment, then overlays any provided kwargs.
124
128
 
@@ -126,9 +130,9 @@ def create_cli_context(**kwargs) -> Context:
126
130
  **kwargs: Override values for the context
127
131
 
128
132
  Returns:
129
- Configured Context instance
133
+ Configured CLIContext instance
130
134
  """
131
- ctx = Context.from_env()
135
+ ctx = CLIContext.from_env()
132
136
  for key, value in kwargs.items():
133
137
  if value is not None and hasattr(ctx, key):
134
138
  setattr(ctx, key, value)
@@ -45,10 +45,27 @@ from provide.foundation.config.types import (
45
45
  ConfigSource,
46
46
  ConfigValue,
47
47
  )
48
- from provide.foundation.config.validators import (
49
- validate_choice,
48
+ from provide.foundation.config.converters import (
49
+ parse_bool_extended,
50
+ parse_comma_list,
51
+ parse_console_formatter,
52
+ parse_float_with_validation,
53
+ parse_headers,
54
+ parse_json_dict,
55
+ parse_json_list,
56
+ parse_log_level,
57
+ parse_module_levels,
58
+ parse_rate_limits,
59
+ parse_sample_rate,
60
+ validate_log_level,
50
61
  validate_non_negative,
62
+ validate_overflow_policy,
63
+ validate_port,
51
64
  validate_positive,
65
+ validate_sample_rate,
66
+ )
67
+ from provide.foundation.config.validators import (
68
+ validate_choice,
52
69
  validate_range,
53
70
  )
54
71
  from provide.foundation.errors.config import (
@@ -96,11 +113,27 @@ __all__ = [
96
113
  "parse_dict",
97
114
  "parse_list",
98
115
  "set_config",
116
+ # Converters
117
+ "parse_bool_extended",
118
+ "parse_comma_list",
119
+ "parse_console_formatter",
120
+ "parse_float_with_validation",
121
+ "parse_headers",
122
+ "parse_json_dict",
123
+ "parse_json_list",
124
+ "parse_log_level",
125
+ "parse_module_levels",
126
+ "parse_rate_limits",
127
+ "parse_sample_rate",
99
128
  # Validators
100
129
  "validate_choice",
101
130
  "validate_config",
131
+ "validate_log_level",
102
132
  "validate_non_negative",
133
+ "validate_overflow_policy",
134
+ "validate_port",
103
135
  "validate_positive",
104
136
  "validate_range",
137
+ "validate_sample_rate",
105
138
  "validate_schema",
106
139
  ]