string-schema 0.1.5__py3-none-any.whl → 0.1.6__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.
- string_schema/utilities.py +61 -7
- {string_schema-0.1.5.dist-info → string_schema-0.1.6.dist-info}/METADATA +8 -1
- {string_schema-0.1.5.dist-info → string_schema-0.1.6.dist-info}/RECORD +6 -6
- {string_schema-0.1.5.dist-info → string_schema-0.1.6.dist-info}/WHEEL +0 -0
- {string_schema-0.1.5.dist-info → string_schema-0.1.6.dist-info}/licenses/LICENSE +0 -0
- {string_schema-0.1.5.dist-info → string_schema-0.1.6.dist-info}/top_level.txt +0 -0
string_schema/utilities.py
CHANGED
|
@@ -15,6 +15,7 @@ Key Functions:
|
|
|
15
15
|
|
|
16
16
|
import functools
|
|
17
17
|
import uuid
|
|
18
|
+
from datetime import datetime, timezone
|
|
18
19
|
from typing import Any, Dict, Type, Union, Callable, Optional, List
|
|
19
20
|
import logging
|
|
20
21
|
|
|
@@ -30,6 +31,48 @@ except ImportError:
|
|
|
30
31
|
logger = logging.getLogger(__name__)
|
|
31
32
|
|
|
32
33
|
|
|
34
|
+
def _ensure_timezone_aware_dict(data: Dict[str, Any]) -> Dict[str, Any]:
|
|
35
|
+
"""
|
|
36
|
+
Ensure all datetime values in a dictionary have timezone information.
|
|
37
|
+
|
|
38
|
+
This function recursively processes dictionaries and lists to add UTC timezone
|
|
39
|
+
information to naive datetime objects, ensuring consistent API responses.
|
|
40
|
+
|
|
41
|
+
Args:
|
|
42
|
+
data: Dictionary that may contain datetime values
|
|
43
|
+
|
|
44
|
+
Returns:
|
|
45
|
+
Dictionary with timezone-aware datetime values converted to ISO format
|
|
46
|
+
"""
|
|
47
|
+
if not isinstance(data, dict):
|
|
48
|
+
return data
|
|
49
|
+
|
|
50
|
+
result = {}
|
|
51
|
+
for key, value in data.items():
|
|
52
|
+
if isinstance(value, datetime):
|
|
53
|
+
# Add UTC timezone to naive datetime objects
|
|
54
|
+
if value.tzinfo is None:
|
|
55
|
+
value = value.replace(tzinfo=timezone.utc)
|
|
56
|
+
# Convert to ISO format string for consistent API responses
|
|
57
|
+
result[key] = value.isoformat()
|
|
58
|
+
elif isinstance(value, dict):
|
|
59
|
+
# Recursively process nested dictionaries
|
|
60
|
+
result[key] = _ensure_timezone_aware_dict(value)
|
|
61
|
+
elif isinstance(value, list):
|
|
62
|
+
# Process lists that may contain dictionaries or datetime objects
|
|
63
|
+
result[key] = [
|
|
64
|
+
_ensure_timezone_aware_dict(item) if isinstance(item, dict)
|
|
65
|
+
else item.isoformat() if isinstance(item, datetime) and item.tzinfo is None
|
|
66
|
+
else item.replace(tzinfo=timezone.utc).isoformat() if isinstance(item, datetime)
|
|
67
|
+
else item
|
|
68
|
+
for item in value
|
|
69
|
+
]
|
|
70
|
+
else:
|
|
71
|
+
result[key] = value
|
|
72
|
+
|
|
73
|
+
return result
|
|
74
|
+
|
|
75
|
+
|
|
33
76
|
def string_to_model(schema_str: str, name: Optional[str] = None) -> Type[BaseModel]:
|
|
34
77
|
"""
|
|
35
78
|
Create Pydantic model from string schema.
|
|
@@ -218,13 +261,21 @@ def validate_to_dict(data: Union[Dict[str, Any], Any], schema_str: str) -> Union
|
|
|
218
261
|
try:
|
|
219
262
|
# Try Pydantic v2 RootModel style
|
|
220
263
|
validated_instance = TempModel(data)
|
|
221
|
-
# Return the validated array data
|
|
222
|
-
|
|
264
|
+
# Return the validated array data with timezone-aware conversion
|
|
265
|
+
result_data = validated_instance.model_dump() if hasattr(validated_instance, 'model_dump') else validated_instance.dict()
|
|
266
|
+
# Process array items for timezone-aware datetime conversion
|
|
267
|
+
if isinstance(result_data, list):
|
|
268
|
+
return [_ensure_timezone_aware_dict(item) if isinstance(item, dict) else item for item in result_data]
|
|
269
|
+
return result_data
|
|
223
270
|
except:
|
|
224
271
|
# Fallback to Pydantic v1 style
|
|
225
272
|
validated_instance = TempModel(__root__=data)
|
|
226
|
-
# Return the validated array data
|
|
227
|
-
|
|
273
|
+
# Return the validated array data with timezone-aware conversion
|
|
274
|
+
result_data = validated_instance.model_dump()['__root__'] if hasattr(validated_instance, 'model_dump') else validated_instance.dict()['__root__']
|
|
275
|
+
# Process array items for timezone-aware datetime conversion
|
|
276
|
+
if isinstance(result_data, list):
|
|
277
|
+
return [_ensure_timezone_aware_dict(item) if isinstance(item, dict) else item for item in result_data]
|
|
278
|
+
return result_data
|
|
228
279
|
else:
|
|
229
280
|
# Handle different input types for object schemas
|
|
230
281
|
if isinstance(data, dict):
|
|
@@ -236,11 +287,14 @@ def validate_to_dict(data: Union[Dict[str, Any], Any], schema_str: str) -> Union
|
|
|
236
287
|
# Try direct validation
|
|
237
288
|
validated_instance = TempModel(data)
|
|
238
289
|
|
|
239
|
-
# Return as dictionary
|
|
290
|
+
# Return as dictionary with timezone-aware datetime handling
|
|
240
291
|
if hasattr(validated_instance, 'model_dump'):
|
|
241
|
-
|
|
292
|
+
result_dict = validated_instance.model_dump()
|
|
242
293
|
else:
|
|
243
|
-
|
|
294
|
+
result_dict = validated_instance.dict()
|
|
295
|
+
|
|
296
|
+
# Ensure timezone-aware datetime conversion for consistent API responses
|
|
297
|
+
return _ensure_timezone_aware_dict(result_dict)
|
|
244
298
|
|
|
245
299
|
except ValidationError as e:
|
|
246
300
|
# Re-raise the original validation error
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: string-schema
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.6
|
|
4
4
|
Summary: A simple, LLM-friendly schema definition library for converting string syntax to structured schemas
|
|
5
5
|
Home-page: https://github.com/xychenmsn/string-schema
|
|
6
6
|
Author: Michael Chen
|
|
@@ -151,6 +151,7 @@ String Schema takes human-readable text descriptions and converts them into stru
|
|
|
151
151
|
- **🤖 LLM Data Extraction**: Define extraction schemas that LLMs can easily follow
|
|
152
152
|
- **🔧 API Development**: Generate Pydantic models and OpenAPI docs from simple syntax
|
|
153
153
|
- **✅ Data Validation**: Create robust validation schemas with minimal code
|
|
154
|
+
- **🌍 Timezone-Aware APIs**: Automatic UTC conversion for consistent datetime handling
|
|
154
155
|
- **📋 Configuration**: Define and validate application configuration schemas
|
|
155
156
|
- **🔄 Data Transformation**: Convert between different schema formats
|
|
156
157
|
|
|
@@ -175,6 +176,12 @@ print(user_dict) # {"name": "John Doe", "email": "john@example.com", "age": 25}
|
|
|
175
176
|
user_model = validate_to_model(raw_data, "name:string, email:email, age:int?")
|
|
176
177
|
print(user_model.name) # "John Doe" - Full type safety
|
|
177
178
|
print(user_model.age) # 25 - Converted to int
|
|
179
|
+
|
|
180
|
+
# 🌍 Automatic timezone handling for datetime fields
|
|
181
|
+
from datetime import datetime
|
|
182
|
+
event_data = {"name": "Meeting", "start_time": datetime(2025, 8, 13, 14, 30)}
|
|
183
|
+
event_dict = validate_to_dict(event_data, "name:string, start_time:datetime")
|
|
184
|
+
print(event_dict) # {"name": "Meeting", "start_time": "2025-08-13T14:30:00+00:00"}
|
|
178
185
|
```
|
|
179
186
|
|
|
180
187
|
### 🎨 Function Decorators
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
string_schema/__init__.py,sha256=J0_B0TNO0AK_piEcT5gFFHllywjx16DTP59ps_Fp-WU,4052
|
|
2
2
|
string_schema/py.typed,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
|
3
|
-
string_schema/utilities.py,sha256=
|
|
3
|
+
string_schema/utilities.py,sha256=FjWKNHPVMFxUc04ITtt2eC4bI6ayLDYwr44fnBgN0-o,22351
|
|
4
4
|
string_schema/core/__init__.py,sha256=jeukkZ1WoCSXrBafumHVH2GkCJ6QjnkH_jAr3DESFio,481
|
|
5
5
|
string_schema/core/builders.py,sha256=AHDTqtCnSe5ZN-DwedisqXqktjgl6nypd-mebucjI3k,7809
|
|
6
6
|
string_schema/core/fields.py,sha256=iLUR-w3pZCr7OkQHhb2DFkVLtObnpyJ_mEUdc0qAqXY,5534
|
|
@@ -17,8 +17,8 @@ string_schema/parsing/__init__.py,sha256=dFW68DqJIwP4w_aYaZMjjVK15X7tCv8A0SPqmIg
|
|
|
17
17
|
string_schema/parsing/optimizer.py,sha256=Ofte8Tb7sKmdEv7RrVIEBQ4Qqr-Whanp1vh8BakcOgw,8479
|
|
18
18
|
string_schema/parsing/string_parser.py,sha256=-a_143fjNkxcRu24JdpqA6GltR7a_2AUXPNgHsbwYv4,24989
|
|
19
19
|
string_schema/parsing/syntax.py,sha256=RO3BIAnWfDBupowOnoJocHtAe-kwE-SgRWXKknVwGdg,8900
|
|
20
|
-
string_schema-0.1.
|
|
21
|
-
string_schema-0.1.
|
|
22
|
-
string_schema-0.1.
|
|
23
|
-
string_schema-0.1.
|
|
24
|
-
string_schema-0.1.
|
|
20
|
+
string_schema-0.1.6.dist-info/licenses/LICENSE,sha256=wCD2KBeSlVSkJy0apl6zmVj04uw97UJhRRi-en_3Qfk,1065
|
|
21
|
+
string_schema-0.1.6.dist-info/METADATA,sha256=L96Jgf9qVZ2K2LwLb5H7stwh684wy5vYFR2bze1yQII,18662
|
|
22
|
+
string_schema-0.1.6.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
23
|
+
string_schema-0.1.6.dist-info/top_level.txt,sha256=1uTmLPYIRrCDVxUW1fDFRMaWvGO48NRcGmbW4oq89I0,14
|
|
24
|
+
string_schema-0.1.6.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|