string-schema 0.1.4__tar.gz → 0.1.6__tar.gz

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 (42) hide show
  1. {string_schema-0.1.4/string_schema.egg-info → string_schema-0.1.6}/PKG-INFO +8 -1
  2. {string_schema-0.1.4 → string_schema-0.1.6}/README.md +7 -0
  3. {string_schema-0.1.4 → string_schema-0.1.6}/docs/pydantic-utilities.md +60 -0
  4. {string_schema-0.1.4 → string_schema-0.1.6}/pyproject.toml +7 -1
  5. {string_schema-0.1.4 → string_schema-0.1.6}/setup.py +1 -1
  6. {string_schema-0.1.4 → string_schema-0.1.6}/string_schema/utilities.py +61 -7
  7. {string_schema-0.1.4 → string_schema-0.1.6/string_schema.egg-info}/PKG-INFO +8 -1
  8. {string_schema-0.1.4 → string_schema-0.1.6}/string_schema.egg-info/SOURCES.txt +19 -0
  9. {string_schema-0.1.4 → string_schema-0.1.6}/LICENSE +0 -0
  10. {string_schema-0.1.4 → string_schema-0.1.6}/MANIFEST.in +0 -0
  11. {string_schema-0.1.4 → string_schema-0.1.6}/docs/README.md +0 -0
  12. {string_schema-0.1.4 → string_schema-0.1.6}/docs/advanced-usage.md +0 -0
  13. {string_schema-0.1.4 → string_schema-0.1.6}/docs/api-reference.md +0 -0
  14. {string_schema-0.1.4 → string_schema-0.1.6}/docs/examples.md +0 -0
  15. {string_schema-0.1.4 → string_schema-0.1.6}/docs/faq.md +0 -0
  16. {string_schema-0.1.4 → string_schema-0.1.6}/docs/getting-started.md +0 -0
  17. {string_schema-0.1.4 → string_schema-0.1.6}/docs/string-syntax.md +0 -0
  18. {string_schema-0.1.4 → string_schema-0.1.6}/docs/troubleshooting.md +0 -0
  19. {string_schema-0.1.4 → string_schema-0.1.6}/examples/demo.py +0 -0
  20. {string_schema-0.1.4 → string_schema-0.1.6}/examples/pydantic_utility_demo.py +0 -0
  21. {string_schema-0.1.4 → string_schema-0.1.6}/setup.cfg +0 -0
  22. {string_schema-0.1.4 → string_schema-0.1.6}/string_schema/__init__.py +0 -0
  23. {string_schema-0.1.4 → string_schema-0.1.6}/string_schema/core/__init__.py +0 -0
  24. {string_schema-0.1.4 → string_schema-0.1.6}/string_schema/core/builders.py +0 -0
  25. {string_schema-0.1.4 → string_schema-0.1.6}/string_schema/core/fields.py +0 -0
  26. {string_schema-0.1.4 → string_schema-0.1.6}/string_schema/core/validators.py +0 -0
  27. {string_schema-0.1.4 → string_schema-0.1.6}/string_schema/examples/__init__.py +0 -0
  28. {string_schema-0.1.4 → string_schema-0.1.6}/string_schema/examples/presets.py +0 -0
  29. {string_schema-0.1.4 → string_schema-0.1.6}/string_schema/examples/recipes.py +0 -0
  30. {string_schema-0.1.4 → string_schema-0.1.6}/string_schema/integrations/__init__.py +0 -0
  31. {string_schema-0.1.4 → string_schema-0.1.6}/string_schema/integrations/json_schema.py +0 -0
  32. {string_schema-0.1.4 → string_schema-0.1.6}/string_schema/integrations/openapi.py +0 -0
  33. {string_schema-0.1.4 → string_schema-0.1.6}/string_schema/integrations/pydantic.py +0 -0
  34. {string_schema-0.1.4 → string_schema-0.1.6}/string_schema/integrations/reverse.py +0 -0
  35. {string_schema-0.1.4 → string_schema-0.1.6}/string_schema/parsing/__init__.py +0 -0
  36. {string_schema-0.1.4 → string_schema-0.1.6}/string_schema/parsing/optimizer.py +0 -0
  37. {string_schema-0.1.4 → string_schema-0.1.6}/string_schema/parsing/string_parser.py +0 -0
  38. {string_schema-0.1.4 → string_schema-0.1.6}/string_schema/parsing/syntax.py +0 -0
  39. {string_schema-0.1.4 → string_schema-0.1.6}/string_schema/py.typed +0 -0
  40. {string_schema-0.1.4 → string_schema-0.1.6}/string_schema.egg-info/dependency_links.txt +0 -0
  41. {string_schema-0.1.4 → string_schema-0.1.6}/string_schema.egg-info/requires.txt +0 -0
  42. {string_schema-0.1.4 → string_schema-0.1.6}/string_schema.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: string-schema
3
- Version: 0.1.4
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
@@ -103,6 +103,7 @@ String Schema takes human-readable text descriptions and converts them into stru
103
103
  - **🤖 LLM Data Extraction**: Define extraction schemas that LLMs can easily follow
104
104
  - **🔧 API Development**: Generate Pydantic models and OpenAPI docs from simple syntax
105
105
  - **✅ Data Validation**: Create robust validation schemas with minimal code
106
+ - **🌍 Timezone-Aware APIs**: Automatic UTC conversion for consistent datetime handling
106
107
  - **📋 Configuration**: Define and validate application configuration schemas
107
108
  - **🔄 Data Transformation**: Convert between different schema formats
108
109
 
@@ -127,6 +128,12 @@ print(user_dict) # {"name": "John Doe", "email": "john@example.com", "age": 25}
127
128
  user_model = validate_to_model(raw_data, "name:string, email:email, age:int?")
128
129
  print(user_model.name) # "John Doe" - Full type safety
129
130
  print(user_model.age) # 25 - Converted to int
131
+
132
+ # 🌍 Automatic timezone handling for datetime fields
133
+ from datetime import datetime
134
+ event_data = {"name": "Meeting", "start_time": datetime(2025, 8, 13, 14, 30)}
135
+ event_dict = validate_to_dict(event_data, "name:string, start_time:datetime")
136
+ print(event_dict) # {"name": "Meeting", "start_time": "2025-08-13T14:30:00+00:00"}
130
137
  ```
131
138
 
132
139
  ### 🎨 Function Decorators
@@ -41,6 +41,7 @@ ProfileModel = string_to_model("name:string, profile:{bio:text?, avatar:url?, so
41
41
 
42
42
  - ✅ Basic types: `string`, `int`, `number`, `boolean`
43
43
  - ✅ Special types: `email`, `url`, `uuid`, `datetime`, `phone`
44
+ - ✅ **Timezone-aware datetime**: Automatic UTC conversion for consistent API responses
44
45
  - ✅ Arrays: `[string]`, `[{name:string, price:number}]`
45
46
  - ✅ Nested objects: `profile:{bio:text?, avatar:url?}`
46
47
  - ✅ Enums: `status:enum(active,inactive,pending)`
@@ -57,6 +58,11 @@ ProfileModel = string_to_model("name:string, profile:{bio:text?, avatar:url?, so
57
58
  user_dict = validate_to_dict(raw_data, "name:string, email:email, age:int?")
58
59
  # Returns: {"name": "John", "email": "john@example.com", "age": 30}
59
60
 
61
+ # Automatic timezone handling for datetime fields
62
+ event_data = {"name": "Meeting", "start_time": datetime(2025, 8, 13, 14, 30)}
63
+ event_dict = validate_to_dict(event_data, "name:string, start_time:datetime")
64
+ # Returns: {"name": "Meeting", "start_time": "2025-08-13T14:30:00+00:00"}
65
+
60
66
  # Array validation
61
67
  events = validate_to_dict(raw_events, "[{user_id:uuid, event:enum(login,logout,purchase)}]")
62
68
 
@@ -79,6 +85,60 @@ if profile.profile:
79
85
  print(profile.profile.bio)
80
86
  ```
81
87
 
88
+ ## 🌍 Timezone Handling
89
+
90
+ String Schema automatically ensures all datetime fields include timezone information for consistent, timezone-aware API responses.
91
+
92
+ ### **Automatic UTC Conversion**
93
+
94
+ ```python
95
+ from datetime import datetime
96
+ from string_schema import validate_to_dict
97
+
98
+ # Naive datetime gets UTC timezone
99
+ data = {"event": "Meeting", "time": datetime(2025, 8, 13, 14, 30)}
100
+ result = validate_to_dict(data, "event:string, time:datetime")
101
+ # Returns: {"event": "Meeting", "time": "2025-08-13T14:30:00+00:00"}
102
+
103
+ # Timezone-aware datetime preserved
104
+ from datetime import timezone
105
+ utc_time = datetime(2025, 8, 13, 14, 30, tzinfo=timezone.utc)
106
+ data = {"event": "UTC Meeting", "time": utc_time}
107
+ result = validate_to_dict(data, "event:string, time:datetime")
108
+ # Returns: {"event": "UTC Meeting", "time": "2025-08-13T14:30:00+00:00"}
109
+ ```
110
+
111
+ ### **Nested and Array Support**
112
+
113
+ ```python
114
+ # Nested datetime handling
115
+ user_data = {
116
+ "name": "John",
117
+ "profile": {
118
+ "created_at": datetime(2025, 8, 13, 10, 0),
119
+ "last_login": datetime(2025, 8, 13, 12, 0)
120
+ }
121
+ }
122
+ result = validate_to_dict(user_data, "name:string, profile:{created_at:datetime, last_login:datetime}")
123
+ # All nested datetime fields get timezone info automatically
124
+
125
+ # Array datetime handling
126
+ events = [
127
+ {"id": 1, "timestamp": datetime(2025, 8, 13, 9, 0)},
128
+ {"id": 2, "timestamp": datetime(2025, 8, 13, 10, 0)}
129
+ ]
130
+ result = validate_to_dict(events, "[{id:int, timestamp:datetime}]")
131
+ # All timestamps in array items get timezone info
132
+ ```
133
+
134
+ ### **Benefits**
135
+
136
+ - ✅ **Consistent API Responses**: All datetime fields include timezone information
137
+ - ✅ **Global Application Support**: Works correctly across all timezones
138
+ - ✅ **Frontend Compatibility**: JavaScript automatically handles timezone conversion
139
+ - ✅ **Zero Configuration**: Works automatically for all datetime fields
140
+ - ✅ **Performance Optimized**: Minimal overhead with maximum benefit
141
+
82
142
  ## 🎨 Decorators
83
143
 
84
144
  ### 4. `@returns_dict(schema_str)`
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "string-schema"
7
- version = "0.1.4"
7
+ version = "0.1.6"
8
8
  description = "A simple, LLM-friendly schema definition library for converting string syntax to structured schemas"
9
9
  readme = "README.md"
10
10
  license = "MIT"
@@ -64,6 +64,12 @@ include = ["string_schema*"]
64
64
  [tool.setuptools.package-data]
65
65
  string_schema = ["py.typed"]
66
66
 
67
+ [tool.setuptools]
68
+ include-package-data = true
69
+
70
+ [tool.setuptools.package-dir]
71
+ "" = "."
72
+
67
73
  [tool.black]
68
74
  line-length = 100
69
75
  target-version = ['py311', 'py312', 'py313']
@@ -9,7 +9,7 @@ with open("README.md", "r", encoding="utf-8") as fh:
9
9
 
10
10
  setup(
11
11
  name="string-schema",
12
- version="0.1.4",
12
+ version="0.1.6",
13
13
  author="Michael Chen",
14
14
  author_email="xychen@msn.com",
15
15
  description="A simple, LLM-friendly schema definition library for converting string syntax to structured schemas",
@@ -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
- return validated_instance.model_dump() if hasattr(validated_instance, 'model_dump') else validated_instance.dict()
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
- return validated_instance.model_dump()['__root__'] if hasattr(validated_instance, 'model_dump') else validated_instance.dict()['__root__']
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 (use model_dump for Pydantic v2, fallback to dict for v1)
290
+ # Return as dictionary with timezone-aware datetime handling
240
291
  if hasattr(validated_instance, 'model_dump'):
241
- return validated_instance.model_dump()
292
+ result_dict = validated_instance.model_dump()
242
293
  else:
243
- return validated_instance.dict()
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.4
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
@@ -3,6 +3,25 @@ MANIFEST.in
3
3
  README.md
4
4
  pyproject.toml
5
5
  setup.py
6
+ ./string_schema/__init__.py
7
+ ./string_schema/py.typed
8
+ ./string_schema/utilities.py
9
+ ./string_schema/core/__init__.py
10
+ ./string_schema/core/builders.py
11
+ ./string_schema/core/fields.py
12
+ ./string_schema/core/validators.py
13
+ ./string_schema/examples/__init__.py
14
+ ./string_schema/examples/presets.py
15
+ ./string_schema/examples/recipes.py
16
+ ./string_schema/integrations/__init__.py
17
+ ./string_schema/integrations/json_schema.py
18
+ ./string_schema/integrations/openapi.py
19
+ ./string_schema/integrations/pydantic.py
20
+ ./string_schema/integrations/reverse.py
21
+ ./string_schema/parsing/__init__.py
22
+ ./string_schema/parsing/optimizer.py
23
+ ./string_schema/parsing/string_parser.py
24
+ ./string_schema/parsing/syntax.py
6
25
  docs/README.md
7
26
  docs/advanced-usage.md
8
27
  docs/api-reference.md
File without changes
File without changes
File without changes
File without changes