openai-sdk-helpers 0.1.0__py3-none-any.whl → 0.1.1__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 (38) hide show
  1. openai_sdk_helpers/__init__.py +41 -7
  2. openai_sdk_helpers/agent/base.py +5 -1
  3. openai_sdk_helpers/agent/coordination.py +4 -5
  4. openai_sdk_helpers/agent/runner.py +4 -1
  5. openai_sdk_helpers/agent/search/base.py +1 -0
  6. openai_sdk_helpers/agent/search/vector.py +2 -0
  7. openai_sdk_helpers/cli.py +265 -0
  8. openai_sdk_helpers/config.py +93 -2
  9. openai_sdk_helpers/context_manager.py +1 -1
  10. openai_sdk_helpers/deprecation.py +167 -0
  11. openai_sdk_helpers/environment.py +3 -2
  12. openai_sdk_helpers/errors.py +0 -12
  13. openai_sdk_helpers/logging_config.py +24 -95
  14. openai_sdk_helpers/prompt/base.py +1 -1
  15. openai_sdk_helpers/response/base.py +84 -115
  16. openai_sdk_helpers/response/messages.py +1 -0
  17. openai_sdk_helpers/retry.py +1 -1
  18. openai_sdk_helpers/streamlit_app/app.py +14 -3
  19. openai_sdk_helpers/streamlit_app/streamlit_web_search.py +15 -8
  20. openai_sdk_helpers/structure/base.py +6 -6
  21. openai_sdk_helpers/structure/plan/helpers.py +1 -0
  22. openai_sdk_helpers/structure/plan/task.py +7 -7
  23. openai_sdk_helpers/tools.py +116 -13
  24. openai_sdk_helpers/utils/__init__.py +82 -35
  25. openai_sdk_helpers/{async_utils.py → utils/async_utils.py} +5 -6
  26. openai_sdk_helpers/utils/coercion.py +138 -0
  27. openai_sdk_helpers/utils/deprecation.py +167 -0
  28. openai_sdk_helpers/utils/json_utils.py +98 -0
  29. openai_sdk_helpers/utils/output_validation.py +448 -0
  30. openai_sdk_helpers/utils/path_utils.py +46 -0
  31. openai_sdk_helpers/{validation.py → utils/validation.py} +7 -3
  32. openai_sdk_helpers/vector_storage/storage.py +9 -6
  33. {openai_sdk_helpers-0.1.0.dist-info → openai_sdk_helpers-0.1.1.dist-info}/METADATA +59 -3
  34. {openai_sdk_helpers-0.1.0.dist-info → openai_sdk_helpers-0.1.1.dist-info}/RECORD +37 -30
  35. openai_sdk_helpers-0.1.1.dist-info/entry_points.txt +2 -0
  36. openai_sdk_helpers/utils/core.py +0 -596
  37. {openai_sdk_helpers-0.1.0.dist-info → openai_sdk_helpers-0.1.1.dist-info}/WHEEL +0 -0
  38. {openai_sdk_helpers-0.1.0.dist-info → openai_sdk_helpers-0.1.1.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,167 @@
1
+ """Deprecation utilities for managing deprecated features.
2
+
3
+ This module provides infrastructure for marking and managing deprecated
4
+ functions, classes, and features with consistent warning messages.
5
+
6
+ Functions
7
+ ---------
8
+ deprecated
9
+ Decorator to mark functions or classes as deprecated.
10
+ warn_deprecated
11
+ Emit a deprecation warning with optional custom message.
12
+
13
+ Classes
14
+ -------
15
+ DeprecationHelper
16
+ Utility class for managing deprecation warnings and versions.
17
+ """
18
+
19
+ from __future__ import annotations
20
+
21
+ import functools
22
+ import warnings
23
+ from typing import Any, Callable, TypeVar
24
+
25
+ F = TypeVar("F", bound=Callable[..., Any])
26
+
27
+
28
+ class DeprecationHelper:
29
+ """Utility class for managing deprecation warnings.
30
+
31
+ Provides consistent formatting and control of deprecation warnings
32
+ across the package.
33
+
34
+ Methods
35
+ -------
36
+ warn
37
+ Emit a deprecation warning with standard formatting.
38
+ """
39
+
40
+ @staticmethod
41
+ def warn(
42
+ feature_name: str,
43
+ removal_version: str,
44
+ alternative: str | None = None,
45
+ extra_message: str | None = None,
46
+ ) -> None:
47
+ """Emit a deprecation warning for a feature.
48
+
49
+ Parameters
50
+ ----------
51
+ feature_name : str
52
+ Name of the deprecated feature (e.g., "MyClass.old_method").
53
+ removal_version : str
54
+ Version in which the feature will be removed.
55
+ alternative : str, optional
56
+ Recommended alternative to use instead.
57
+ extra_message : str, optional
58
+ Additional context or migration instructions.
59
+
60
+ Raises
61
+ ------
62
+ DeprecationWarning
63
+ Always issues a DeprecationWarning to stderr.
64
+ """
65
+ msg = f"{feature_name} is deprecated and will be removed in version {removal_version}."
66
+ if alternative:
67
+ msg += f" Use {alternative} instead."
68
+ if extra_message:
69
+ msg += f" {extra_message}"
70
+
71
+ warnings.warn(msg, DeprecationWarning, stacklevel=3)
72
+
73
+
74
+ def deprecated(
75
+ removal_version: str,
76
+ alternative: str | None = None,
77
+ extra_message: str | None = None,
78
+ ) -> Callable[[F], F]:
79
+ """Mark a function or class as deprecated.
80
+
81
+ Parameters
82
+ ----------
83
+ removal_version : str
84
+ Version in which the decorated feature will be removed.
85
+ alternative : str, optional
86
+ Recommended alternative to use instead.
87
+ extra_message : str, optional
88
+ Additional context or migration instructions.
89
+
90
+ Returns
91
+ -------
92
+ Callable
93
+ Decorator function that wraps the target function or class.
94
+
95
+ Examples
96
+ --------
97
+ >>> @deprecated("1.0.0", "new_function")
98
+ ... def old_function():
99
+ ... pass
100
+
101
+ >>> class OldClass:
102
+ ... @deprecated("1.0.0", "NewClass")
103
+ ... def old_method(self):
104
+ ... pass
105
+ """
106
+
107
+ def decorator(func_or_class: F) -> F:
108
+ feature_name = f"{func_or_class.__module__}.{func_or_class.__qualname__}"
109
+
110
+ if isinstance(func_or_class, type):
111
+ # Handle class deprecation
112
+ original_init = func_or_class.__init__
113
+
114
+ @functools.wraps(original_init)
115
+ def new_init(self: Any, *args: Any, **kwargs: Any) -> None:
116
+ DeprecationHelper.warn(
117
+ feature_name,
118
+ removal_version,
119
+ alternative,
120
+ extra_message,
121
+ )
122
+ original_init(self, *args, **kwargs)
123
+
124
+ func_or_class.__init__ = new_init
125
+ else:
126
+ # Handle function deprecation
127
+ @functools.wraps(func_or_class)
128
+ def wrapper(*args: Any, **kwargs: Any) -> Any:
129
+ DeprecationHelper.warn(
130
+ feature_name,
131
+ removal_version,
132
+ alternative,
133
+ extra_message,
134
+ )
135
+ return func_or_class(*args, **kwargs)
136
+
137
+ return wrapper # type: ignore
138
+
139
+ return func_or_class # type: ignore[return-value]
140
+
141
+ return decorator
142
+
143
+
144
+ def warn_deprecated(
145
+ feature_name: str,
146
+ removal_version: str,
147
+ alternative: str | None = None,
148
+ extra_message: str | None = None,
149
+ ) -> None:
150
+ """Issue a deprecation warning.
151
+
152
+ Parameters
153
+ ----------
154
+ feature_name : str
155
+ Name of the deprecated feature.
156
+ removal_version : str
157
+ Version in which the feature will be removed.
158
+ alternative : str, optional
159
+ Recommended alternative to use instead.
160
+ extra_message : str, optional
161
+ Additional context or migration instructions.
162
+
163
+ Examples
164
+ --------
165
+ >>> warn_deprecated("old_config_key", "1.0.0", "new_config_key")
166
+ """
167
+ DeprecationHelper.warn(feature_name, removal_version, alternative, extra_message)
@@ -20,6 +20,8 @@ from __future__ import annotations
20
20
 
21
21
  from pathlib import Path
22
22
 
23
+ from openai_sdk_helpers.utils import ensure_directory
24
+
23
25
  DATETIME_FMT = "%Y%m%d_%H%M%S"
24
26
  DEFAULT_MODEL = "gpt-4o-mini"
25
27
 
@@ -50,5 +52,4 @@ def get_data_path(name: str) -> Path:
50
52
  """
51
53
  base = Path.home() / ".openai-sdk-helpers"
52
54
  path = base / name
53
- path.mkdir(parents=True, exist_ok=True)
54
- return path
55
+ return ensure_directory(path)
@@ -4,11 +4,8 @@ Provides specific exception types for different error scenarios,
4
4
  improving error handling and debugging capabilities.
5
5
  """
6
6
 
7
- import logging
8
7
  from collections.abc import Mapping
9
8
 
10
- from openai_sdk_helpers.utils.core import log
11
-
12
9
 
13
10
  class OpenAISDKError(Exception):
14
11
  """Base exception for openai-sdk-helpers library.
@@ -40,15 +37,6 @@ class OpenAISDKError(Exception):
40
37
  """Initialize the exception with message and optional context."""
41
38
  super().__init__(message)
42
39
  self.context = dict(context) if context is not None else {}
43
- self._log_context()
44
-
45
- def _log_context(self) -> None:
46
- """Log error with context for debugging."""
47
- context_str = f"\nContext: {self.context}" if self.context else ""
48
- log(
49
- f"{self.__class__.__name__}: {str(self)}{context_str}",
50
- level=logging.ERROR,
51
- )
52
40
 
53
41
 
54
42
  class ConfigurationError(OpenAISDKError):
@@ -1,105 +1,34 @@
1
- """Centralized logging configuration for openai-sdk-helpers.
2
-
3
- Provides a centralized factory for creating and configuring loggers
4
- with consistent formatting and handler management.
5
- """
1
+ """Centralized logging configuration for openai-sdk-helpers."""
6
2
 
7
3
  import logging
8
- import threading
9
- from typing import Any
10
-
11
4
 
12
- class LoggerFactory:
13
- """Centralized logger creation and configuration.
14
5
 
15
- Manages logger initialization and configuration to ensure consistent
16
- logging behavior across the entire SDK. Thread-safe.
6
+ def log(
7
+ message: str,
8
+ level: int = logging.INFO,
9
+ *,
10
+ logger_name: str = "openai_sdk_helpers",
11
+ ) -> None:
12
+ """Log a message using Python's standard logging.
13
+
14
+ Parameters
15
+ ----------
16
+ message : str
17
+ The message to log.
18
+ level : int
19
+ Logging level (e.g., logging.DEBUG, logging.INFO).
20
+ Default is logging.INFO.
21
+ logger_name : str
22
+ Name of the logger. Default is "openai_sdk_helpers".
17
23
 
18
24
  Examples
19
25
  --------
20
- Configure logging once at application startup:
21
-
22
- >>> from openai_sdk_helpers.logging_config import LoggerFactory
23
- >>> import logging
24
- >>> LoggerFactory.configure(
25
- ... level=logging.DEBUG,
26
- ... handlers=[logging.StreamHandler()],
27
- ... )
28
-
29
- Get a logger instance in your module:
30
-
31
- >>> logger = LoggerFactory.get_logger("openai_sdk_helpers.agent")
32
- >>> logger.debug("Debug message")
26
+ >>> from openai_sdk_helpers.logging_config import log
27
+ >>> log("Operation completed")
28
+ >>> log("Debug info", level=logging.DEBUG)
33
29
  """
30
+ logger = logging.getLogger(logger_name)
31
+ logger.log(level, message)
34
32
 
35
- _initialized = False
36
- _log_level = logging.INFO
37
- _handlers: list[logging.Handler] = []
38
- _lock = threading.Lock()
39
-
40
- @classmethod
41
- def configure(
42
- cls,
43
- level: int = logging.INFO,
44
- handlers: list[logging.Handler] | None = None,
45
- ) -> None:
46
- """Configure logging globally.
47
-
48
- Parameters
49
- ----------
50
- level : int
51
- Logging level (e.g., logging.DEBUG, logging.INFO).
52
- Default is logging.INFO.
53
- handlers : list[logging.Handler] | None
54
- List of logging handlers. If None, a default
55
- StreamHandler is created. Default is None.
56
-
57
- Notes
58
- -----
59
- This method is thread-safe and can be called multiple times.
60
- """
61
- with cls._lock:
62
- cls._log_level = level
63
- if handlers:
64
- cls._handlers = handlers
65
- else:
66
- handler = logging.StreamHandler()
67
- handler.setLevel(level)
68
- formatter = logging.Formatter(
69
- "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
70
- )
71
- handler.setFormatter(formatter)
72
- cls._handlers = [handler]
73
- cls._initialized = True
74
-
75
- @classmethod
76
- def get_logger(cls, name: str) -> logging.Logger:
77
- """Get configured logger instance.
78
-
79
- Parameters
80
- ----------
81
- name : str
82
- Logger name, typically __name__ of calling module.
83
-
84
- Returns
85
- -------
86
- logging.Logger
87
- Configured logger instance.
88
- """
89
- logger = logging.getLogger(name)
90
-
91
- # Skip configuration if already configured
92
- if logger.handlers:
93
- return logger
94
-
95
- with cls._lock:
96
- if not cls._initialized:
97
- cls.configure()
98
-
99
- for handler in cls._handlers:
100
- logger.addHandler(handler)
101
-
102
- logger.setLevel(cls._log_level)
103
- logger.propagate = False
104
33
 
105
- return logger
34
+ __all__ = ["log"]
@@ -176,7 +176,7 @@ class PromptRenderer:
176
176
  ... context={"key": "value"}
177
177
  ... )
178
178
  """
179
- from openai_sdk_helpers.validation import validate_safe_path
179
+ from openai_sdk_helpers.utils.validation import validate_safe_path
180
180
 
181
181
  path = Path(template_path)
182
182
  if path.is_absolute():