string-schema 0.1.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.
@@ -0,0 +1,380 @@
1
+ """
2
+ Common schema patterns and recipes for Simple Schema
3
+
4
+ Contains reusable patterns and helper functions for creating complex schemas.
5
+ """
6
+
7
+ from typing import Any, Dict, List, Optional, Union
8
+ import logging
9
+
10
+ from ..core.fields import SimpleField
11
+ from ..core.builders import simple_schema, list_of_objects_schema, simple_array_schema
12
+
13
+ logger = logging.getLogger(__name__)
14
+
15
+
16
+ def create_list_schema(item_fields: Dict[str, Union[str, SimpleField]],
17
+ description: str = "List of items",
18
+ min_items: Optional[int] = None,
19
+ max_items: Optional[int] = None) -> Dict[str, Any]:
20
+ """
21
+ Create a schema for a list of objects.
22
+
23
+ Args:
24
+ item_fields: Field definitions for each item in the list
25
+ description: Description of the list
26
+ min_items: Minimum number of items
27
+ max_items: Maximum number of items
28
+
29
+ Returns:
30
+ JSON Schema for list of objects
31
+ """
32
+ return list_of_objects_schema(item_fields, description, min_items, max_items)
33
+
34
+
35
+ def create_nested_schema(base_fields: Dict[str, Union[str, SimpleField]],
36
+ nested_objects: Dict[str, Dict[str, Union[str, SimpleField]]]) -> Dict[str, Any]:
37
+ """
38
+ Create a schema with nested objects.
39
+
40
+ Args:
41
+ base_fields: Top-level field definitions
42
+ nested_objects: Dictionary of nested object definitions
43
+
44
+ Returns:
45
+ JSON Schema with nested structure
46
+ """
47
+ all_fields = base_fields.copy()
48
+
49
+ for nested_name, nested_fields in nested_objects.items():
50
+ # Create a nested object field
51
+ nested_schema = simple_schema(nested_fields)
52
+ # This is a simplified approach - in a full implementation,
53
+ # we'd need to handle this as a proper nested structure
54
+ all_fields[nested_name] = SimpleField('object', f'Nested {nested_name} object')
55
+
56
+ return simple_schema(all_fields)
57
+
58
+
59
+ def create_enum_schema(field_name: str,
60
+ values: List[str],
61
+ description: str = "",
62
+ required: bool = True) -> Dict[str, Any]:
63
+ """
64
+ Create a schema with an enum field.
65
+
66
+ Args:
67
+ field_name: Name of the enum field
68
+ values: List of allowed values
69
+ description: Field description
70
+ required: Whether the field is required
71
+
72
+ Returns:
73
+ JSON Schema with enum field
74
+ """
75
+ fields = {
76
+ field_name: SimpleField('string', description, required=required, choices=values)
77
+ }
78
+ return simple_schema(fields)
79
+
80
+
81
+ def create_union_schema(field_name: str,
82
+ types: List[str],
83
+ description: str = "",
84
+ required: bool = True) -> Dict[str, Any]:
85
+ """
86
+ Create a schema with a union type field.
87
+
88
+ Args:
89
+ field_name: Name of the union field
90
+ types: List of allowed types
91
+ description: Field description
92
+ required: Whether the field is required
93
+
94
+ Returns:
95
+ JSON Schema with union field
96
+ """
97
+ primary_type = types[0] if types else 'string'
98
+ fields = {
99
+ field_name: SimpleField(primary_type, description, required=required, union_types=types)
100
+ }
101
+ return simple_schema(fields)
102
+
103
+
104
+ def create_pagination_schema(item_fields: Dict[str, Union[str, SimpleField]],
105
+ include_metadata: bool = True) -> Dict[str, Any]:
106
+ """
107
+ Create a paginated response schema.
108
+
109
+ Args:
110
+ item_fields: Field definitions for each item
111
+ include_metadata: Whether to include pagination metadata
112
+
113
+ Returns:
114
+ JSON Schema for paginated response
115
+ """
116
+ fields = {
117
+ 'items': SimpleField('array', 'List of items')
118
+ }
119
+
120
+ if include_metadata:
121
+ fields.update({
122
+ 'total': SimpleField('integer', 'Total number of items', min_val=0),
123
+ 'page': SimpleField('integer', 'Current page number', min_val=1),
124
+ 'per_page': SimpleField('integer', 'Items per page', min_val=1),
125
+ 'has_next': SimpleField('boolean', 'Whether there are more pages'),
126
+ 'has_prev': SimpleField('boolean', 'Whether there are previous pages')
127
+ })
128
+
129
+ # Note: In a full implementation, we'd properly handle the nested array schema
130
+ return simple_schema(fields)
131
+
132
+
133
+ def create_api_response_schema(data_fields: Dict[str, Union[str, SimpleField]],
134
+ include_status: bool = True,
135
+ include_metadata: bool = False) -> Dict[str, Any]:
136
+ """
137
+ Create a standard API response schema.
138
+
139
+ Args:
140
+ data_fields: Field definitions for the data payload
141
+ include_status: Whether to include status information
142
+ include_metadata: Whether to include response metadata
143
+
144
+ Returns:
145
+ JSON Schema for API response
146
+ """
147
+ fields = {
148
+ 'data': SimpleField('object', 'Response data payload')
149
+ }
150
+
151
+ if include_status:
152
+ fields.update({
153
+ 'success': SimpleField('boolean', 'Whether the request was successful'),
154
+ 'message': SimpleField('string', 'Response message', required=False)
155
+ })
156
+
157
+ if include_metadata:
158
+ fields.update({
159
+ 'timestamp': SimpleField('string', 'Response timestamp', format_hint='datetime'),
160
+ 'request_id': SimpleField('string', 'Unique request identifier', format_hint='uuid', required=False)
161
+ })
162
+
163
+ return simple_schema(fields)
164
+
165
+
166
+ def create_error_schema(include_details: bool = True) -> Dict[str, Any]:
167
+ """
168
+ Create a standard error response schema.
169
+
170
+ Args:
171
+ include_details: Whether to include detailed error information
172
+
173
+ Returns:
174
+ JSON Schema for error response
175
+ """
176
+ fields = {
177
+ 'error': SimpleField('boolean', 'Error indicator', default=True),
178
+ 'message': SimpleField('string', 'Error message'),
179
+ 'code': SimpleField('string', 'Error code', required=False)
180
+ }
181
+
182
+ if include_details:
183
+ fields.update({
184
+ 'details': SimpleField('string', 'Detailed error information', required=False),
185
+ 'timestamp': SimpleField('string', 'Error timestamp', format_hint='datetime'),
186
+ 'path': SimpleField('string', 'Request path that caused the error', required=False)
187
+ })
188
+
189
+ return simple_schema(fields)
190
+
191
+
192
+ def create_search_schema(result_fields: Dict[str, Union[str, SimpleField]],
193
+ include_facets: bool = False) -> Dict[str, Any]:
194
+ """
195
+ Create a search results schema.
196
+
197
+ Args:
198
+ result_fields: Field definitions for each search result
199
+ include_facets: Whether to include search facets
200
+
201
+ Returns:
202
+ JSON Schema for search results
203
+ """
204
+ fields = {
205
+ 'query': SimpleField('string', 'Search query'),
206
+ 'results': SimpleField('array', 'Search results'),
207
+ 'total_results': SimpleField('integer', 'Total number of results', min_val=0),
208
+ 'took': SimpleField('number', 'Search time in milliseconds', min_val=0, required=False)
209
+ }
210
+
211
+ if include_facets:
212
+ fields['facets'] = SimpleField('object', 'Search facets', required=False)
213
+
214
+ return simple_schema(fields)
215
+
216
+
217
+ def create_audit_schema(entity_fields: Dict[str, Union[str, SimpleField]]) -> Dict[str, Any]:
218
+ """
219
+ Create an audit log schema.
220
+
221
+ Args:
222
+ entity_fields: Field definitions for the audited entity
223
+
224
+ Returns:
225
+ JSON Schema for audit log entry
226
+ """
227
+ fields = {
228
+ 'id': SimpleField('string', 'Audit log entry ID', format_hint='uuid'),
229
+ 'entity_type': SimpleField('string', 'Type of entity being audited'),
230
+ 'entity_id': SimpleField('string', 'ID of the audited entity'),
231
+ 'action': SimpleField('string', 'Action performed',
232
+ choices=['create', 'update', 'delete', 'view']),
233
+ 'user_id': SimpleField('string', 'ID of user who performed the action'),
234
+ 'timestamp': SimpleField('string', 'When the action occurred', format_hint='datetime'),
235
+ 'changes': SimpleField('object', 'What changed', required=False),
236
+ 'metadata': SimpleField('object', 'Additional metadata', required=False)
237
+ }
238
+
239
+ return simple_schema(fields)
240
+
241
+
242
+ def create_notification_schema(include_delivery: bool = True) -> Dict[str, Any]:
243
+ """
244
+ Create a notification schema.
245
+
246
+ Args:
247
+ include_delivery: Whether to include delivery information
248
+
249
+ Returns:
250
+ JSON Schema for notification
251
+ """
252
+ fields = {
253
+ 'id': SimpleField('string', 'Notification ID', format_hint='uuid'),
254
+ 'type': SimpleField('string', 'Notification type',
255
+ choices=['info', 'warning', 'error', 'success']),
256
+ 'title': SimpleField('string', 'Notification title', max_length=200),
257
+ 'message': SimpleField('string', 'Notification message', max_length=1000),
258
+ 'recipient_id': SimpleField('string', 'Recipient user ID'),
259
+ 'created_at': SimpleField('string', 'Creation timestamp', format_hint='datetime'),
260
+ 'read': SimpleField('boolean', 'Whether notification has been read', default=False)
261
+ }
262
+
263
+ if include_delivery:
264
+ fields.update({
265
+ 'delivery_method': SimpleField('string', 'How notification was delivered',
266
+ choices=['email', 'sms', 'push', 'in_app'], required=False),
267
+ 'delivered_at': SimpleField('string', 'Delivery timestamp',
268
+ format_hint='datetime', required=False)
269
+ })
270
+
271
+ return simple_schema(fields)
272
+
273
+
274
+ def create_file_metadata_schema(include_content_info: bool = True) -> Dict[str, Any]:
275
+ """
276
+ Create a file metadata schema.
277
+
278
+ Args:
279
+ include_content_info: Whether to include content analysis information
280
+
281
+ Returns:
282
+ JSON Schema for file metadata
283
+ """
284
+ fields = {
285
+ 'filename': SimpleField('string', 'Original filename', max_length=255),
286
+ 'size': SimpleField('integer', 'File size in bytes', min_val=0),
287
+ 'mime_type': SimpleField('string', 'MIME type', max_length=100),
288
+ 'uploaded_at': SimpleField('string', 'Upload timestamp', format_hint='datetime'),
289
+ 'uploaded_by': SimpleField('string', 'User who uploaded the file'),
290
+ 'checksum': SimpleField('string', 'File checksum (MD5/SHA256)', required=False)
291
+ }
292
+
293
+ if include_content_info:
294
+ fields.update({
295
+ 'width': SimpleField('integer', 'Image width in pixels', min_val=0, required=False),
296
+ 'height': SimpleField('integer', 'Image height in pixels', min_val=0, required=False),
297
+ 'duration': SimpleField('number', 'Media duration in seconds', min_val=0, required=False),
298
+ 'encoding': SimpleField('string', 'File encoding', required=False)
299
+ })
300
+
301
+ return simple_schema(fields)
302
+
303
+
304
+ def create_settings_schema(setting_groups: Dict[str, List[str]]) -> Dict[str, Any]:
305
+ """
306
+ Create a user settings schema.
307
+
308
+ Args:
309
+ setting_groups: Dictionary mapping group names to setting names
310
+
311
+ Returns:
312
+ JSON Schema for user settings
313
+ """
314
+ fields = {}
315
+
316
+ for group_name, setting_names in setting_groups.items():
317
+ for setting_name in setting_names:
318
+ # Create flexible setting fields that can hold various types
319
+ fields[f"{group_name}_{setting_name}"] = SimpleField(
320
+ 'string', f'{group_name} {setting_name} setting', required=False
321
+ )
322
+
323
+ # Add common settings metadata
324
+ fields.update({
325
+ 'user_id': SimpleField('string', 'User ID'),
326
+ 'updated_at': SimpleField('string', 'Last update timestamp', format_hint='datetime'),
327
+ 'version': SimpleField('integer', 'Settings version', min_val=1, default=1)
328
+ })
329
+
330
+ return simple_schema(fields)
331
+
332
+
333
+ # Recipe combinations for common use cases
334
+ def create_ecommerce_product_schema() -> Dict[str, Any]:
335
+ """Create a comprehensive e-commerce product schema"""
336
+ fields = {
337
+ 'id': SimpleField('string', 'Product ID', format_hint='uuid'),
338
+ 'sku': SimpleField('string', 'Stock keeping unit', max_length=50),
339
+ 'name': SimpleField('string', 'Product name', min_length=1, max_length=200),
340
+ 'description': SimpleField('string', 'Product description', max_length=2000, required=False),
341
+ 'category': SimpleField('string', 'Product category',
342
+ choices=['electronics', 'clothing', 'books', 'home', 'sports']),
343
+ 'price': SimpleField('number', 'Product price', min_val=0),
344
+ 'currency': SimpleField('string', 'Price currency', choices=['USD', 'EUR', 'GBP'], default='USD'),
345
+ 'in_stock': SimpleField('boolean', 'Whether product is in stock', default=True),
346
+ 'stock_quantity': SimpleField('integer', 'Available quantity', min_val=0, required=False),
347
+ 'weight': SimpleField('number', 'Product weight in kg', min_val=0, required=False),
348
+ 'dimensions': SimpleField('string', 'Product dimensions', required=False),
349
+ 'brand': SimpleField('string', 'Product brand', max_length=100, required=False),
350
+ 'tags': SimpleField('string', 'Comma-separated tags', required=False),
351
+ 'created_at': SimpleField('string', 'Creation timestamp', format_hint='datetime'),
352
+ 'updated_at': SimpleField('string', 'Last update timestamp', format_hint='datetime')
353
+ }
354
+
355
+ return simple_schema(fields)
356
+
357
+
358
+ def create_blog_post_schema() -> Dict[str, Any]:
359
+ """Create a comprehensive blog post schema"""
360
+ fields = {
361
+ 'id': SimpleField('string', 'Post ID', format_hint='uuid'),
362
+ 'title': SimpleField('string', 'Post title', min_length=1, max_length=200),
363
+ 'slug': SimpleField('string', 'URL slug', max_length=200),
364
+ 'content': SimpleField('string', 'Post content', min_length=10),
365
+ 'excerpt': SimpleField('string', 'Post excerpt', max_length=500, required=False),
366
+ 'author_id': SimpleField('string', 'Author ID'),
367
+ 'author_name': SimpleField('string', 'Author name', max_length=100),
368
+ 'status': SimpleField('string', 'Post status',
369
+ choices=['draft', 'published', 'archived'], default='draft'),
370
+ 'category': SimpleField('string', 'Post category', max_length=100, required=False),
371
+ 'tags': SimpleField('string', 'Comma-separated tags', required=False),
372
+ 'featured_image': SimpleField('string', 'Featured image URL', format_hint='url', required=False),
373
+ 'published_at': SimpleField('string', 'Publication timestamp', format_hint='datetime', required=False),
374
+ 'created_at': SimpleField('string', 'Creation timestamp', format_hint='datetime'),
375
+ 'updated_at': SimpleField('string', 'Last update timestamp', format_hint='datetime'),
376
+ 'view_count': SimpleField('integer', 'Number of views', min_val=0, default=0),
377
+ 'comment_count': SimpleField('integer', 'Number of comments', min_val=0, default=0)
378
+ }
379
+
380
+ return simple_schema(fields)
@@ -0,0 +1,15 @@
1
+ """
2
+ Integrations module for Simple Schema
3
+
4
+ Contains integrations with external libraries and standards.
5
+ """
6
+
7
+ from .pydantic import create_pydantic_model
8
+ from .json_schema import to_json_schema
9
+ from .openapi import to_openapi_schema
10
+
11
+ __all__ = [
12
+ "create_pydantic_model",
13
+ "to_json_schema",
14
+ "to_openapi_schema"
15
+ ]