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.
- openai_sdk_helpers/__init__.py +41 -7
- openai_sdk_helpers/agent/base.py +5 -1
- openai_sdk_helpers/agent/coordination.py +4 -5
- openai_sdk_helpers/agent/runner.py +4 -1
- openai_sdk_helpers/agent/search/base.py +1 -0
- openai_sdk_helpers/agent/search/vector.py +2 -0
- openai_sdk_helpers/cli.py +265 -0
- openai_sdk_helpers/config.py +93 -2
- openai_sdk_helpers/context_manager.py +1 -1
- openai_sdk_helpers/deprecation.py +167 -0
- openai_sdk_helpers/environment.py +3 -2
- openai_sdk_helpers/errors.py +0 -12
- openai_sdk_helpers/logging_config.py +24 -95
- openai_sdk_helpers/prompt/base.py +1 -1
- openai_sdk_helpers/response/base.py +84 -115
- openai_sdk_helpers/response/messages.py +1 -0
- openai_sdk_helpers/retry.py +1 -1
- openai_sdk_helpers/streamlit_app/app.py +14 -3
- openai_sdk_helpers/streamlit_app/streamlit_web_search.py +15 -8
- openai_sdk_helpers/structure/base.py +6 -6
- openai_sdk_helpers/structure/plan/helpers.py +1 -0
- openai_sdk_helpers/structure/plan/task.py +7 -7
- openai_sdk_helpers/tools.py +116 -13
- openai_sdk_helpers/utils/__init__.py +82 -35
- openai_sdk_helpers/{async_utils.py → utils/async_utils.py} +5 -6
- openai_sdk_helpers/utils/coercion.py +138 -0
- openai_sdk_helpers/utils/deprecation.py +167 -0
- openai_sdk_helpers/utils/json_utils.py +98 -0
- openai_sdk_helpers/utils/output_validation.py +448 -0
- openai_sdk_helpers/utils/path_utils.py +46 -0
- openai_sdk_helpers/{validation.py → utils/validation.py} +7 -3
- openai_sdk_helpers/vector_storage/storage.py +9 -6
- {openai_sdk_helpers-0.1.0.dist-info → openai_sdk_helpers-0.1.1.dist-info}/METADATA +59 -3
- {openai_sdk_helpers-0.1.0.dist-info → openai_sdk_helpers-0.1.1.dist-info}/RECORD +37 -30
- openai_sdk_helpers-0.1.1.dist-info/entry_points.txt +2 -0
- openai_sdk_helpers/utils/core.py +0 -596
- {openai_sdk_helpers-0.1.0.dist-info → openai_sdk_helpers-0.1.1.dist-info}/WHEEL +0 -0
- {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
|
|
54
|
-
return path
|
|
55
|
+
return ensure_directory(path)
|
openai_sdk_helpers/errors.py
CHANGED
|
@@ -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
|
-
|
|
16
|
-
|
|
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
|
-
|
|
21
|
-
|
|
22
|
-
>>>
|
|
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
|
-
|
|
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():
|