openai-sdk-helpers 0.2.0__py3-none-any.whl → 0.4.0__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 (58) hide show
  1. openai_sdk_helpers/__init__.py +6 -6
  2. openai_sdk_helpers/agent/__init__.py +4 -2
  3. openai_sdk_helpers/agent/base.py +391 -106
  4. openai_sdk_helpers/agent/config.py +405 -44
  5. openai_sdk_helpers/agent/coordination.py +68 -31
  6. openai_sdk_helpers/agent/runner.py +29 -19
  7. openai_sdk_helpers/agent/search/base.py +103 -54
  8. openai_sdk_helpers/agent/search/vector.py +99 -68
  9. openai_sdk_helpers/agent/search/web.py +84 -50
  10. openai_sdk_helpers/agent/summarizer.py +33 -7
  11. openai_sdk_helpers/agent/translator.py +58 -24
  12. openai_sdk_helpers/agent/validation.py +35 -4
  13. openai_sdk_helpers/cli.py +42 -0
  14. openai_sdk_helpers/config.py +0 -1
  15. openai_sdk_helpers/environment.py +3 -2
  16. openai_sdk_helpers/files_api.py +35 -3
  17. openai_sdk_helpers/prompt/base.py +6 -0
  18. openai_sdk_helpers/response/__init__.py +3 -3
  19. openai_sdk_helpers/response/base.py +161 -22
  20. openai_sdk_helpers/response/config.py +50 -200
  21. openai_sdk_helpers/response/files.py +5 -5
  22. openai_sdk_helpers/response/messages.py +3 -3
  23. openai_sdk_helpers/response/runner.py +7 -7
  24. openai_sdk_helpers/response/tool_call.py +94 -4
  25. openai_sdk_helpers/response/vector_store.py +3 -3
  26. openai_sdk_helpers/streamlit_app/app.py +16 -16
  27. openai_sdk_helpers/streamlit_app/config.py +38 -37
  28. openai_sdk_helpers/streamlit_app/streamlit_web_search.py +2 -2
  29. openai_sdk_helpers/structure/__init__.py +6 -2
  30. openai_sdk_helpers/structure/agent_blueprint.py +2 -2
  31. openai_sdk_helpers/structure/base.py +8 -99
  32. openai_sdk_helpers/structure/plan/plan.py +2 -2
  33. openai_sdk_helpers/structure/plan/task.py +9 -9
  34. openai_sdk_helpers/structure/prompt.py +2 -2
  35. openai_sdk_helpers/structure/responses.py +15 -15
  36. openai_sdk_helpers/structure/summary.py +3 -3
  37. openai_sdk_helpers/structure/translation.py +32 -0
  38. openai_sdk_helpers/structure/validation.py +2 -2
  39. openai_sdk_helpers/structure/vector_search.py +7 -7
  40. openai_sdk_helpers/structure/web_search.py +6 -6
  41. openai_sdk_helpers/tools.py +41 -15
  42. openai_sdk_helpers/utils/__init__.py +19 -5
  43. openai_sdk_helpers/utils/instructions.py +35 -0
  44. openai_sdk_helpers/utils/json/__init__.py +55 -0
  45. openai_sdk_helpers/utils/json/base_model.py +181 -0
  46. openai_sdk_helpers/utils/{json_utils.py → json/data_class.py} +43 -70
  47. openai_sdk_helpers/utils/json/ref.py +113 -0
  48. openai_sdk_helpers/utils/json/utils.py +203 -0
  49. openai_sdk_helpers/utils/output_validation.py +21 -1
  50. openai_sdk_helpers/utils/path_utils.py +34 -1
  51. openai_sdk_helpers/utils/registry.py +194 -0
  52. openai_sdk_helpers/vector_storage/storage.py +10 -0
  53. {openai_sdk_helpers-0.2.0.dist-info → openai_sdk_helpers-0.4.0.dist-info}/METADATA +7 -7
  54. openai_sdk_helpers-0.4.0.dist-info/RECORD +86 -0
  55. openai_sdk_helpers-0.2.0.dist-info/RECORD +0 -79
  56. {openai_sdk_helpers-0.2.0.dist-info → openai_sdk_helpers-0.4.0.dist-info}/WHEEL +0 -0
  57. {openai_sdk_helpers-0.2.0.dist-info → openai_sdk_helpers-0.4.0.dist-info}/entry_points.txt +0 -0
  58. {openai_sdk_helpers-0.2.0.dist-info → openai_sdk_helpers-0.4.0.dist-info}/licenses/LICENSE +0 -0
@@ -1,7 +1,7 @@
1
1
  """OpenAI response and tool helpers for structured outputs.
2
2
 
3
3
  This module provides helper functions for creating OpenAI API response formats
4
- and tool definitions from BaseStructure classes. These helpers simplify the
4
+ and tool definitions from StructureBase classes. These helpers simplify the
5
5
  process of configuring structured outputs for both Assistant and chat
6
6
  completion APIs.
7
7
  """
@@ -13,12 +13,12 @@ from openai.types.responses.response_format_text_json_schema_config_param import
13
13
  )
14
14
  from openai.types.responses.response_text_config_param import ResponseTextConfigParam
15
15
 
16
- from .base import BaseStructure
16
+ from .base import StructureBase
17
17
  from ..utils import log
18
18
 
19
19
 
20
20
  def assistant_tool_definition(
21
- structure: type[BaseStructure], name: str, description: str
21
+ structure: type[StructureBase], name: str, description: str
22
22
  ) -> dict:
23
23
  """Build a function tool definition for OpenAI Assistants.
24
24
 
@@ -27,7 +27,7 @@ def assistant_tool_definition(
27
27
 
28
28
  Parameters
29
29
  ----------
30
- structure : type[BaseStructure]
30
+ structure : type[StructureBase]
31
31
  Structure class that defines the tool schema.
32
32
  name : str
33
33
  Name of the function tool.
@@ -41,9 +41,9 @@ def assistant_tool_definition(
41
41
 
42
42
  Examples
43
43
  --------
44
- >>> from openai_sdk_helpers.structure import BaseStructure
44
+ >>> from openai_sdk_helpers.structure import StructureBase
45
45
  >>> tool = assistant_tool_definition(
46
- ... BaseStructure,
46
+ ... StructureBase,
47
47
  ... "process_data",
48
48
  ... "Process input data"
49
49
  ... )
@@ -59,7 +59,7 @@ def assistant_tool_definition(
59
59
  }
60
60
 
61
61
 
62
- def assistant_format(structure: type[BaseStructure]) -> dict:
62
+ def assistant_format(structure: type[StructureBase]) -> dict:
63
63
  """Build a response format definition for OpenAI Assistants.
64
64
 
65
65
  Creates a response format specification that instructs the Assistant API
@@ -67,7 +67,7 @@ def assistant_format(structure: type[BaseStructure]) -> dict:
67
67
 
68
68
  Parameters
69
69
  ----------
70
- structure : type[BaseStructure]
70
+ structure : type[StructureBase]
71
71
  Structure class that defines the response schema.
72
72
 
73
73
  Returns
@@ -77,7 +77,7 @@ def assistant_format(structure: type[BaseStructure]) -> dict:
77
77
 
78
78
  Examples
79
79
  --------
80
- >>> format_def = assistant_format(BaseStructure)
80
+ >>> format_def = assistant_format(StructureBase)
81
81
  """
82
82
  log(f"{structure.__name__}::assistant_format")
83
83
  return {
@@ -90,7 +90,7 @@ def assistant_format(structure: type[BaseStructure]) -> dict:
90
90
 
91
91
 
92
92
  def response_tool_definition(
93
- structure: type[BaseStructure],
93
+ structure: type[StructureBase],
94
94
  tool_name: str,
95
95
  tool_description: str,
96
96
  ) -> dict:
@@ -101,7 +101,7 @@ def response_tool_definition(
101
101
 
102
102
  Parameters
103
103
  ----------
104
- structure : type[BaseStructure]
104
+ structure : type[StructureBase]
105
105
  Structure class that defines the tool schema.
106
106
  tool_name : str
107
107
  Name of the function tool.
@@ -116,7 +116,7 @@ def response_tool_definition(
116
116
  Examples
117
117
  --------
118
118
  >>> tool = response_tool_definition(
119
- ... BaseStructure,
119
+ ... StructureBase,
120
120
  ... "analyze",
121
121
  ... "Analyze data"
122
122
  ... )
@@ -132,7 +132,7 @@ def response_tool_definition(
132
132
  }
133
133
 
134
134
 
135
- def response_format(structure: type[BaseStructure]) -> ResponseTextConfigParam:
135
+ def response_format(structure: type[StructureBase]) -> ResponseTextConfigParam:
136
136
  """Build a response format for OpenAI chat completions.
137
137
 
138
138
  Creates a response format specification that instructs the chat
@@ -140,7 +140,7 @@ def response_format(structure: type[BaseStructure]) -> ResponseTextConfigParam:
140
140
 
141
141
  Parameters
142
142
  ----------
143
- structure : type[BaseStructure]
143
+ structure : type[StructureBase]
144
144
  Structure class that defines the response schema.
145
145
 
146
146
  Returns
@@ -150,7 +150,7 @@ def response_format(structure: type[BaseStructure]) -> ResponseTextConfigParam:
150
150
 
151
151
  Examples
152
152
  --------
153
- >>> format_spec = response_format(BaseStructure)
153
+ >>> format_spec = response_format(StructureBase)
154
154
  """
155
155
  log(f"{structure.__name__}::response_format")
156
156
  response_format_text_JSONSchema_config_param = (
@@ -6,10 +6,10 @@ including topic-level summaries with citations and consolidated text summaries.
6
6
 
7
7
  from __future__ import annotations
8
8
 
9
- from .base import BaseStructure, spec_field
9
+ from .base import StructureBase, spec_field
10
10
 
11
11
 
12
- class SummaryTopic(BaseStructure):
12
+ class SummaryTopic(StructureBase):
13
13
  """Capture a topic-level summary with supporting citations.
14
14
 
15
15
  Represents a single topic or micro-trend identified in source excerpts,
@@ -55,7 +55,7 @@ class SummaryTopic(BaseStructure):
55
55
  )
56
56
 
57
57
 
58
- class SummaryStructure(BaseStructure):
58
+ class SummaryStructure(StructureBase):
59
59
  """Consolidated summary returned by the summarizer agent.
60
60
 
61
61
  Represents a synthesized summary text derived from multiple source excerpts.
@@ -0,0 +1,32 @@
1
+ """Structured output model for translations."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from .base import StructureBase, spec_field
6
+
7
+
8
+ class TranslationStructure(StructureBase):
9
+ """Structured representation of translated text.
10
+
11
+ Attributes
12
+ ----------
13
+ text : str
14
+ Translated text output from the agent.
15
+
16
+ Methods
17
+ -------
18
+ print()
19
+ Return the formatted model fields.
20
+
21
+ Examples
22
+ --------
23
+ >>> translation = TranslationStructure(text="Hola mundo")
24
+ >>> print(translation.text)
25
+ 'Hola mundo'
26
+ """
27
+
28
+ text: str = spec_field(
29
+ "text",
30
+ description="Translated text output from the agent.",
31
+ examples=["Hola mundo", "Bonjour le monde"],
32
+ )
@@ -6,10 +6,10 @@ validation checks on user inputs and agent outputs.
6
6
 
7
7
  from __future__ import annotations
8
8
 
9
- from .base import BaseStructure, spec_field
9
+ from .base import StructureBase, spec_field
10
10
 
11
11
 
12
- class ValidationResultStructure(BaseStructure):
12
+ class ValidationResultStructure(StructureBase):
13
13
  """Capture guardrail validation findings for user and agent messages.
14
14
 
15
15
  Represents the results of safety and policy validation checks performed
@@ -7,10 +7,10 @@ workflows with error tracking and result aggregation.
7
7
 
8
8
  from __future__ import annotations
9
9
 
10
- from .base import BaseStructure, spec_field
10
+ from .base import StructureBase, spec_field
11
11
 
12
12
 
13
- class VectorSearchItemStructure(BaseStructure):
13
+ class VectorSearchItemStructure(StructureBase):
14
14
  """A single vector search to perform.
15
15
 
16
16
  Represents one vector search query with rationale for its inclusion
@@ -35,7 +35,7 @@ class VectorSearchItemStructure(BaseStructure):
35
35
  query: str = spec_field("query")
36
36
 
37
37
 
38
- class VectorSearchPlanStructure(BaseStructure):
38
+ class VectorSearchPlanStructure(StructureBase):
39
39
  """Collection of vector searches required to satisfy the query.
40
40
 
41
41
  Represents a plan containing multiple vector searches that together
@@ -56,7 +56,7 @@ class VectorSearchPlanStructure(BaseStructure):
56
56
  searches: list[VectorSearchItemStructure] = spec_field("searches")
57
57
 
58
58
 
59
- class VectorSearchItemResultStructure(BaseStructure):
59
+ class VectorSearchItemResultStructure(StructureBase):
60
60
  """Result of a single vector search.
61
61
 
62
62
  Contains the text results retrieved from executing one vector search query.
@@ -74,7 +74,7 @@ class VectorSearchItemResultStructure(BaseStructure):
74
74
  texts: list[str] = spec_field("texts")
75
75
 
76
76
 
77
- class VectorSearchItemResultsStructure(BaseStructure):
77
+ class VectorSearchItemResultsStructure(StructureBase):
78
78
  """Collection of search results from multiple queries.
79
79
 
80
80
  Aggregates results from multiple vector searches while tracking any
@@ -119,7 +119,7 @@ class VectorSearchItemResultsStructure(BaseStructure):
119
119
  self.item_results.append(item)
120
120
 
121
121
 
122
- class VectorSearchReportStructure(BaseStructure):
122
+ class VectorSearchReportStructure(StructureBase):
123
123
  """Structured output from the vector search writer agent.
124
124
 
125
125
  Contains the final synthesized report from vector search results,
@@ -152,7 +152,7 @@ class VectorSearchReportStructure(BaseStructure):
152
152
  sources: list[str] = spec_field("sources")
153
153
 
154
154
 
155
- class VectorSearchStructure(BaseStructure):
155
+ class VectorSearchStructure(StructureBase):
156
156
  """Complete output of a vector search workflow.
157
157
 
158
158
  Represents the full lifecycle of a vector search operation, from the
@@ -7,10 +7,10 @@ workflows with comprehensive reporting.
7
7
 
8
8
  from __future__ import annotations
9
9
 
10
- from .base import BaseStructure, spec_field
10
+ from .base import StructureBase, spec_field
11
11
 
12
12
 
13
- class WebSearchReportStructure(BaseStructure):
13
+ class WebSearchReportStructure(StructureBase):
14
14
  """Structured output from the web search writer agent.
15
15
 
16
16
  Contains the final synthesized report from web search results,
@@ -43,7 +43,7 @@ class WebSearchReportStructure(BaseStructure):
43
43
  sources: list[str] = spec_field("sources")
44
44
 
45
45
 
46
- class WebSearchItemStructure(BaseStructure):
46
+ class WebSearchItemStructure(StructureBase):
47
47
  """A single web search to perform.
48
48
 
49
49
  Represents one web search query with rationale for its inclusion
@@ -68,7 +68,7 @@ class WebSearchItemStructure(BaseStructure):
68
68
  query: str = spec_field("query")
69
69
 
70
70
 
71
- class WebSearchItemResultStructure(BaseStructure):
71
+ class WebSearchItemResultStructure(StructureBase):
72
72
  """Result of a single web search.
73
73
 
74
74
  Contains the text content retrieved from executing one web search query.
@@ -86,7 +86,7 @@ class WebSearchItemResultStructure(BaseStructure):
86
86
  text: str = spec_field("text")
87
87
 
88
88
 
89
- class WebSearchPlanStructure(BaseStructure):
89
+ class WebSearchPlanStructure(StructureBase):
90
90
  """Collection of web searches required to satisfy the query.
91
91
 
92
92
  Represents a plan containing multiple web searches that together
@@ -107,7 +107,7 @@ class WebSearchPlanStructure(BaseStructure):
107
107
  searches: list[WebSearchItemStructure] = spec_field("searches")
108
108
 
109
109
 
110
- class WebSearchStructure(BaseStructure):
110
+ class WebSearchStructure(StructureBase):
111
111
  """Complete output of a web search workflow.
112
112
 
113
113
  Represents the full lifecycle of a web search operation, from the
@@ -10,19 +10,21 @@ definitions from named metadata structures.
10
10
 
11
11
  from __future__ import annotations
12
12
 
13
+ import asyncio
13
14
  import inspect
15
+ import threading
14
16
  from dataclasses import dataclass
15
17
  from typing import Any, Callable, TypeAlias, TypeVar
16
18
 
17
19
  from pydantic import BaseModel, ValidationError
18
20
 
19
21
  from openai_sdk_helpers.response.tool_call import parse_tool_arguments
20
- from openai_sdk_helpers.structure.base import BaseStructure
22
+ from openai_sdk_helpers.structure.base import StructureBase
21
23
  from openai_sdk_helpers.utils import coerce_jsonable, customJSONEncoder
22
24
  import json
23
25
 
24
26
  T = TypeVar("T", bound=BaseModel)
25
- StructureType: TypeAlias = type[BaseStructure]
27
+ StructureType: TypeAlias = type[StructureBase]
26
28
 
27
29
 
28
30
  def serialize_tool_result(result: Any) -> str:
@@ -81,7 +83,7 @@ def tool_handler_factory(
81
83
  The returned handler:
82
84
  1. Parses tool_call.arguments using parse_tool_arguments
83
85
  2. Validates arguments with input_model if provided
84
- 3. Calls func with validated/parsed arguments
86
+ 3. Calls func with validated/parsed arguments (handles both sync and async)
85
87
  4. Serializes the result using serialize_tool_result
86
88
 
87
89
  Parameters
@@ -124,7 +126,13 @@ def tool_handler_factory(
124
126
  ... limit: int = 10
125
127
  >>> def search_tool(query: str, limit: int = 10):
126
128
  ... return {"results": [f"Result for {query}"]}
127
- >>> handler = tool_handler_factory(search_tool, SearchInput)
129
+ >>> handler = tool_handler_factory(search_tool, input_model=SearchInput)
130
+
131
+ With async function:
132
+
133
+ >>> async def async_search_tool(query: str, limit: int = 10):
134
+ ... return {"results": [f"Result for {query}"]}
135
+ >>> handler = tool_handler_factory(async_search_tool)
128
136
 
129
137
  The handler can then be used with OpenAI tool calls:
130
138
 
@@ -135,6 +143,7 @@ def tool_handler_factory(
135
143
  >>> tool_call = ToolCall()
136
144
  >>> result = handler(tool_call) # doctest: +SKIP
137
145
  """
146
+ is_async = inspect.iscoroutinefunction(func)
138
147
 
139
148
  def handler(tool_call: Any) -> str:
140
149
  """Handle tool execution with parsing, validation, and serialization.
@@ -170,15 +179,32 @@ def tool_handler_factory(
170
179
  else:
171
180
  call_kwargs = parsed_args
172
181
 
173
- # Execute function (sync only - async functions not supported)
174
- if inspect.iscoroutinefunction(func):
175
- raise TypeError(
176
- f"Async functions are not supported by tool_handler_factory. "
177
- f"Function '{func.__name__}' is async. "
178
- "Wrap async functions in a synchronous adapter before passing to tool_handler_factory."
179
- )
180
-
181
- result = func(**call_kwargs)
182
+ # Execute function (sync or async with event loop detection)
183
+ if is_async:
184
+ # Handle async function with proper event loop detection
185
+ try:
186
+ loop = asyncio.get_running_loop()
187
+ # We're inside an event loop, need to run in thread
188
+ result_holder: dict[str, Any] = {"value": None, "exception": None}
189
+
190
+ def _thread_func() -> None:
191
+ try:
192
+ result_holder["value"] = asyncio.run(func(**call_kwargs))
193
+ except Exception as exc:
194
+ result_holder["exception"] = exc
195
+
196
+ thread = threading.Thread(target=_thread_func)
197
+ thread.start()
198
+ thread.join()
199
+
200
+ if result_holder["exception"]:
201
+ raise result_holder["exception"]
202
+ result = result_holder["value"]
203
+ except RuntimeError:
204
+ # No event loop running, can use asyncio.run directly
205
+ result = asyncio.run(func(**call_kwargs))
206
+ else:
207
+ result = func(**call_kwargs)
182
208
 
183
209
  # Serialize result
184
210
  return serialize_tool_result(result)
@@ -200,14 +226,14 @@ class ToolSpec:
200
226
  Attributes
201
227
  ----------
202
228
  structure : StructureType
203
- The BaseStructure class that defines the tool's input parameter schema.
229
+ The StructureBase class that defines the tool's input parameter schema.
204
230
  Used to generate the OpenAI tool definition.
205
231
  tool_name : str
206
232
  Name identifier for the tool.
207
233
  tool_description : str
208
234
  Human-readable description of what the tool does.
209
235
  output_structure : StructureType or None, default=None
210
- Optional BaseStructure class that defines the tool's output schema.
236
+ Optional StructureBase class that defines the tool's output schema.
211
237
  This is for documentation/reference only and is not sent to OpenAI.
212
238
  Useful when a tool accepts one type of input but returns a different
213
239
  structured output.
@@ -21,8 +21,8 @@ coercion
21
21
  Numeric coercion helpers and list normalization.
22
22
  path_utils
23
23
  File and path helpers.
24
- json_utils
25
- JSON encoding helpers and mixins.
24
+ json
25
+ JSON encoding helpers and mixins for dataclasses and Pydantic models.
26
26
  logging_config
27
27
  Centralized logger factory and convenience log helper.
28
28
  validation
@@ -45,11 +45,18 @@ from .coercion import (
45
45
  coerce_optional_int,
46
46
  ensure_list,
47
47
  )
48
- from .json_utils import (
49
- JSONSerializable,
48
+ from .json import (
49
+ BaseModelJSONSerializable,
50
+ DataclassJSONSerializable,
50
51
  coerce_jsonable,
51
52
  customJSONEncoder,
53
+ decode_module_qualname,
54
+ encode_module_qualname,
55
+ get_module_qualname,
56
+ to_jsonable,
52
57
  )
58
+ from .registry import BaseRegistry
59
+
53
60
  from .path_utils import check_filepath, ensure_directory
54
61
  from openai_sdk_helpers.logging_config import log
55
62
  from .validation import (
@@ -88,9 +95,14 @@ __all__ = [
88
95
  "coerce_optional_float",
89
96
  "coerce_optional_int",
90
97
  "coerce_dict",
98
+ "to_jsonable",
91
99
  "coerce_jsonable",
92
- "JSONSerializable",
100
+ "DataclassJSONSerializable",
101
+ "BaseModelJSONSerializable",
93
102
  "customJSONEncoder",
103
+ "get_module_qualname",
104
+ "encode_module_qualname",
105
+ "decode_module_qualname",
94
106
  "log",
95
107
  # Validation helpers
96
108
  "validate_non_empty_string",
@@ -122,4 +134,6 @@ __all__ = [
122
134
  "create_image_data_url",
123
135
  "create_file_data_url",
124
136
  "is_image_file",
137
+ # Registry
138
+ "BaseRegistry",
125
139
  ]
@@ -0,0 +1,35 @@
1
+ """Utilities for resolving instructions from strings or file paths."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from pathlib import Path
6
+
7
+
8
+ def resolve_instructions_from_path(instructions: str | Path) -> str:
9
+ """Resolve instructions from a string or file path.
10
+
11
+ Parameters
12
+ ----------
13
+ instructions : str or Path
14
+ Either plain-text instructions or a path to a file containing
15
+ instructions.
16
+
17
+ Returns
18
+ -------
19
+ str
20
+ The resolved instruction text.
21
+
22
+ Raises
23
+ ------
24
+ ValueError
25
+ If instructions is a Path that cannot be read.
26
+ """
27
+ if isinstance(instructions, Path):
28
+ instruction_path = instructions.expanduser()
29
+ try:
30
+ return instruction_path.read_text(encoding="utf-8")
31
+ except OSError as exc:
32
+ raise ValueError(
33
+ f"Unable to read instructions at '{instruction_path}': {exc}"
34
+ ) from exc
35
+ return instructions
@@ -0,0 +1,55 @@
1
+ """JSON serialization helpers for dataclasses, Pydantic models, and reference encoding.
2
+
3
+ This package provides consistent to_json/from_json flows and a JSONEncoder that
4
+ handles common types including dataclasses, Pydantic models, and reference encoding.
5
+
6
+ Package Layout
7
+ --------------
8
+ utils.py
9
+ to_jsonable(), coerce_jsonable(), customJSONEncoder.
10
+ data_class.py
11
+ DataclassJSONSerializable mixin with to_json, to_json_file, from_json, from_json_file.
12
+ base_model.py
13
+ BaseModelJSONSerializable for Pydantic, with _serialize_fields/_deserialize_fields hooks.
14
+ ref.py
15
+ Reference helpers get_module_qualname, encode_module_qualname, decode_module_qualname.
16
+
17
+ Public API
18
+ ----------
19
+ to_jsonable(value)
20
+ Convert common types to JSON-safe forms; recursive for containers/dicts.
21
+ coerce_jsonable(value)
22
+ Ensures json.dumps succeeds; falls back to str when necessary. Special-cases ResponseBase.
23
+ customJSONEncoder
24
+ json.JSONEncoder subclass delegating to to_jsonable.
25
+ DataclassJSONSerializable
26
+ Mixin adding to_json(), to_json_file(path) -> str, from_json(data) -> T, from_json_file(path) -> T.
27
+ BaseModelJSONSerializable
28
+ Pydantic BaseModel subclass adding to_json() -> dict, to_json_file(path) -> str,
29
+ from_json(data) -> T, from_json_file(path) -> T, plus overridable _serialize_fields(data)
30
+ and _deserialize_fields(data).
31
+ get_module_qualname(obj) -> (module, qualname)
32
+ Safe retrieval.
33
+ encode_module_qualname(obj) -> dict|None
34
+ {module, qualname} for import reconstruction.
35
+ decode_module_qualname(ref) -> object|None
36
+ Import and getattr by encoded reference.
37
+ """
38
+
39
+ from __future__ import annotations
40
+
41
+ from .base_model import BaseModelJSONSerializable
42
+ from .data_class import DataclassJSONSerializable
43
+ from .ref import decode_module_qualname, encode_module_qualname, get_module_qualname
44
+ from .utils import coerce_jsonable, customJSONEncoder, to_jsonable
45
+
46
+ __all__ = [
47
+ "to_jsonable",
48
+ "coerce_jsonable",
49
+ "customJSONEncoder",
50
+ "DataclassJSONSerializable",
51
+ "BaseModelJSONSerializable",
52
+ "get_module_qualname",
53
+ "encode_module_qualname",
54
+ "decode_module_qualname",
55
+ ]