py-json-analyzer 0.2.0__tar.gz → 0.3.0__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 (76) hide show
  1. {py_json_analyzer-0.2.0/py_json_analyzer.egg-info → py_json_analyzer-0.3.0}/PKG-INFO +96 -20
  2. {py_json_analyzer-0.2.0 → py_json_analyzer-0.3.0}/README.md +95 -19
  3. py_json_analyzer-0.3.0/json_explorer/__init__.py +1 -0
  4. {py_json_analyzer-0.2.0 → py_json_analyzer-0.3.0}/json_explorer/analyzer.py +45 -10
  5. py_json_analyzer-0.3.0/json_explorer/codegen/__init__.py +230 -0
  6. {py_json_analyzer-0.2.0 → py_json_analyzer-0.3.0}/json_explorer/codegen/cli_integration.py +277 -140
  7. py_json_analyzer-0.3.0/json_explorer/codegen/core/__init__.py +98 -0
  8. py_json_analyzer-0.3.0/json_explorer/codegen/core/config.py +345 -0
  9. py_json_analyzer-0.3.0/json_explorer/codegen/core/generator.py +378 -0
  10. py_json_analyzer-0.3.0/json_explorer/codegen/core/naming.py +337 -0
  11. py_json_analyzer-0.3.0/json_explorer/codegen/core/schema.py +582 -0
  12. py_json_analyzer-0.3.0/json_explorer/codegen/core/templates.py +284 -0
  13. {py_json_analyzer-0.2.0 → py_json_analyzer-0.3.0}/json_explorer/codegen/interactive.py +225 -156
  14. py_json_analyzer-0.3.0/json_explorer/codegen/languages/__init__.py +189 -0
  15. {py_json_analyzer-0.2.0 → py_json_analyzer-0.3.0}/json_explorer/codegen/languages/go/__init__.py +10 -15
  16. py_json_analyzer-0.3.0/json_explorer/codegen/languages/go/config.py +225 -0
  17. {py_json_analyzer-0.2.0 → py_json_analyzer-0.3.0}/json_explorer/codegen/languages/go/generator.py +137 -89
  18. {py_json_analyzer-0.2.0 → py_json_analyzer-0.3.0}/json_explorer/codegen/languages/go/interactive.py +114 -117
  19. py_json_analyzer-0.3.0/json_explorer/codegen/languages/go/naming.py +103 -0
  20. py_json_analyzer-0.3.0/json_explorer/codegen/languages/python/__init__.py +43 -0
  21. py_json_analyzer-0.3.0/json_explorer/codegen/languages/python/config.py +328 -0
  22. py_json_analyzer-0.3.0/json_explorer/codegen/languages/python/generator.py +422 -0
  23. py_json_analyzer-0.3.0/json_explorer/codegen/languages/python/interactive.py +344 -0
  24. py_json_analyzer-0.3.0/json_explorer/codegen/languages/python/naming.py +157 -0
  25. py_json_analyzer-0.3.0/json_explorer/codegen/registry.py +395 -0
  26. {py_json_analyzer-0.2.0 → py_json_analyzer-0.3.0}/json_explorer/main.py +1 -1
  27. {py_json_analyzer-0.2.0 → py_json_analyzer-0.3.0}/json_explorer/search.py +1 -1
  28. {py_json_analyzer-0.2.0 → py_json_analyzer-0.3.0}/json_explorer/stats.py +1 -1
  29. {py_json_analyzer-0.2.0 → py_json_analyzer-0.3.0/py_json_analyzer.egg-info}/PKG-INFO +96 -20
  30. {py_json_analyzer-0.2.0 → py_json_analyzer-0.3.0}/py_json_analyzer.egg-info/SOURCES.txt +17 -0
  31. {py_json_analyzer-0.2.0 → py_json_analyzer-0.3.0}/pyproject.toml +1 -1
  32. {py_json_analyzer-0.2.0 → py_json_analyzer-0.3.0}/setup.cfg +2 -2
  33. py_json_analyzer-0.3.0/tests/test_gen_conftest.py +54 -0
  34. py_json_analyzer-0.3.0/tests/test_gen_core_config.py +92 -0
  35. py_json_analyzer-0.3.0/tests/test_gen_core_naming.py +81 -0
  36. py_json_analyzer-0.3.0/tests/test_gen_core_schema.py +161 -0
  37. py_json_analyzer-0.3.0/tests/test_gen_edge.py +512 -0
  38. py_json_analyzer-0.3.0/tests/test_gen_error_handling.py +27 -0
  39. py_json_analyzer-0.3.0/tests/test_gen_integration.py +185 -0
  40. py_json_analyzer-0.3.0/tests/test_gen_performance.py +37 -0
  41. py_json_analyzer-0.3.0/tests/test_gen_registry.py +110 -0
  42. py_json_analyzer-0.3.0/tests/test_gen_templates.py +32 -0
  43. py_json_analyzer-0.3.0/tests/test_go_generator.py +187 -0
  44. py_json_analyzer-0.3.0/tests/test_python_generator.py +230 -0
  45. py_json_analyzer-0.2.0/json_explorer/__init__.py +0 -1
  46. py_json_analyzer-0.2.0/json_explorer/codegen/__init__.py +0 -178
  47. py_json_analyzer-0.2.0/json_explorer/codegen/core/__init__.py +0 -41
  48. py_json_analyzer-0.2.0/json_explorer/codegen/core/config.py +0 -170
  49. py_json_analyzer-0.2.0/json_explorer/codegen/core/generator.py +0 -212
  50. py_json_analyzer-0.2.0/json_explorer/codegen/core/naming.py +0 -175
  51. py_json_analyzer-0.2.0/json_explorer/codegen/core/schema.py +0 -483
  52. py_json_analyzer-0.2.0/json_explorer/codegen/core/templates.py +0 -174
  53. py_json_analyzer-0.2.0/json_explorer/codegen/languages/__init__.py +0 -35
  54. py_json_analyzer-0.2.0/json_explorer/codegen/languages/go/config.py +0 -115
  55. py_json_analyzer-0.2.0/json_explorer/codegen/languages/go/naming.py +0 -81
  56. py_json_analyzer-0.2.0/json_explorer/codegen/registry.py +0 -355
  57. {py_json_analyzer-0.2.0 → py_json_analyzer-0.3.0}/LICENSE +0 -0
  58. {py_json_analyzer-0.2.0 → py_json_analyzer-0.3.0}/json_explorer/__main__.py +0 -0
  59. {py_json_analyzer-0.2.0 → py_json_analyzer-0.3.0}/json_explorer/cli.py +0 -0
  60. {py_json_analyzer-0.2.0 → py_json_analyzer-0.3.0}/json_explorer/filter_parser.py +0 -0
  61. {py_json_analyzer-0.2.0 → py_json_analyzer-0.3.0}/json_explorer/interactive.py +0 -0
  62. {py_json_analyzer-0.2.0 → py_json_analyzer-0.3.0}/json_explorer/tree_view.py +0 -0
  63. {py_json_analyzer-0.2.0 → py_json_analyzer-0.3.0}/json_explorer/utils.py +0 -0
  64. {py_json_analyzer-0.2.0 → py_json_analyzer-0.3.0}/json_explorer/visualizer.py +0 -0
  65. {py_json_analyzer-0.2.0 → py_json_analyzer-0.3.0}/py_json_analyzer.egg-info/dependency_links.txt +0 -0
  66. {py_json_analyzer-0.2.0 → py_json_analyzer-0.3.0}/py_json_analyzer.egg-info/entry_points.txt +0 -0
  67. {py_json_analyzer-0.2.0 → py_json_analyzer-0.3.0}/py_json_analyzer.egg-info/requires.txt +0 -0
  68. {py_json_analyzer-0.2.0 → py_json_analyzer-0.3.0}/py_json_analyzer.egg-info/top_level.txt +0 -0
  69. {py_json_analyzer-0.2.0 → py_json_analyzer-0.3.0}/setup.py +0 -0
  70. {py_json_analyzer-0.2.0 → py_json_analyzer-0.3.0}/tests/__init__.py +0 -0
  71. {py_json_analyzer-0.2.0 → py_json_analyzer-0.3.0}/tests/test_analyzer.py +0 -0
  72. {py_json_analyzer-0.2.0 → py_json_analyzer-0.3.0}/tests/test_search.py +0 -0
  73. {py_json_analyzer-0.2.0 → py_json_analyzer-0.3.0}/tests/test_stats.py +0 -0
  74. {py_json_analyzer-0.2.0 → py_json_analyzer-0.3.0}/tests/test_tree_view.py +0 -0
  75. {py_json_analyzer-0.2.0 → py_json_analyzer-0.3.0}/tests/test_utils.py +0 -0
  76. {py_json_analyzer-0.2.0 → py_json_analyzer-0.3.0}/tests/test_visualizer.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: py-json-analyzer
3
- Version: 0.2.0
3
+ Version: 0.3.0
4
4
  Summary: A powerful CLI and Python library for analyzing, visualizing, exploring, and generating code from JSON data
5
5
  Author: MS-32154
6
6
  Author-email: MS-32154 <msttoffg@gmail.com>
@@ -18,7 +18,7 @@ Requires-Dist: windows-curses; sys_platform == "win32"
18
18
  Dynamic: license-file
19
19
 
20
20
  [![PyPI version](https://img.shields.io/pypi/v/py-json-analyzer.svg)](https://pypi.org/project/py-json-analyzer/)
21
- [![Python 3.9+](https://img.shields.io/badge/python-3.8+-blue.svg)](https://www.python.org/downloads/)
21
+ [![Python 3.11+](https://img.shields.io/badge/python-3.11+-blue.svg)](https://www.python.org/downloads/)
22
22
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
23
23
 
24
24
  # JSON Explorer
@@ -40,7 +40,7 @@ Dynamic: license-file
40
40
  ### Code Generation
41
41
 
42
42
  - Generate strongly-typed data structures from JSON
43
- - Multiple language support (Go, with Python, TypeScript, Rust coming soon)
43
+ - Multiple language support (Go, Python, with TypeScript and Rust coming soon)
44
44
  - Smart type detection and conflict resolution
45
45
  - Configurable naming conventions and templates
46
46
  - JSON serialization tags and annotations
@@ -57,7 +57,7 @@ Dynamic: license-file
57
57
 
58
58
  ## Requirements
59
59
 
60
- - Python >= 3.9
60
+ - Python >= 3.11
61
61
 
62
62
  Required packages:
63
63
 
@@ -111,6 +111,30 @@ pip install -e .
111
111
  pytest
112
112
  ```
113
113
 
114
+ ### Test Coverage
115
+
116
+ The project includes comprehensive tests for:
117
+
118
+ - **Core modules**: Analysis, search, statistics, tree view, plotting
119
+ - **Codegen core modules**: Naming, schema, configuration, templates
120
+ - **Generators**: Go and Python with all styles
121
+ - **Codegen registry**: Language registration and lookup
122
+ - **Codegen integration**: End-to-end workflows
123
+ - **Edge cases**: None handling, conflicts, deep nesting
124
+
125
+ Run specific test suites:
126
+
127
+ ```bash
128
+ # Core functionality
129
+ pytest tests/test_core.py -v
130
+
131
+ # Go generator
132
+ pytest tests/test_go_generator.py -v
133
+
134
+ # Python generator
135
+ pytest tests/test_python_generator.py -v
136
+ ```
137
+
114
138
  ---
115
139
 
116
140
  ## CLI Usage
@@ -185,6 +209,16 @@ Go-specific options:
185
209
  --no-omitempty Don't add omitempty to JSON tags in Go
186
210
  --json-tag-case {original,snake,camel}
187
211
  Case style for JSON tag names in Go
212
+
213
+ Python-specific options:
214
+ --python-style {dataclass,pydantic,typeddict}
215
+ Python code style (default: dataclass)
216
+ --no-slots Don't use __slots__ in dataclasses
217
+ --frozen Make dataclasses frozen (immutable)
218
+ --kw-only Make dataclass fields keyword-only
219
+ --no-pydantic-field Don't use Field() in Pydantic models
220
+ --pydantic-forbid-extra
221
+ Forbid extra fields in Pydantic models
188
222
  ```
189
223
 
190
224
  ### Examples
@@ -211,10 +245,16 @@ json_explorer data.json --search "isinstance(value, int) and value > 10" --searc
211
245
  json_explorer --list-languages
212
246
 
213
247
  # Generate Go structs
214
- json_explorer data.json --generate go
248
+ json_explorer data.json --generate go --output models.go
249
+
250
+ # Generate Python dataclasses
251
+ json_explorer data.json --generate python --output models.py
252
+
253
+ # Generate Pydantic models
254
+ json_explorer data.json --generate python --python-style pydantic --output models.py
215
255
 
216
256
  # Generate with custom configuration
217
- json_explorer data.json --generate go --output models.go --package-name models
257
+ json_explorer data.json --generate go --package-name models --root-name User
218
258
 
219
259
  # Interactive code generation
220
260
  json_explorer data.json --interactive # Then select code generation menu
@@ -301,10 +341,18 @@ from json_explorer.codegen import (
301
341
  )
302
342
  from json_explorer.analyzer import analyze_json
303
343
 
304
- # Quick generation
344
+ # Quick generation - Go
305
345
  go_code = quick_generate(test_data, language="go")
306
346
  print(go_code)
307
347
 
348
+ # Quick generation - Python dataclass
349
+ python_code = quick_generate(test_data, language="python", style="dataclass")
350
+ print(python_code)
351
+
352
+ # Quick generation - Pydantic model
353
+ pydantic_code = quick_generate(test_data, language="python", style="pydantic")
354
+ print(pydantic_code)
355
+
308
356
  # Detailed generation workflow
309
357
  analysis = analyze_json(test_data)
310
358
  config = create_config(
@@ -326,21 +374,24 @@ print("Supported languages:", languages)
326
374
  go_info = get_language_info("go")
327
375
  print("Go generator info:", go_info)
328
376
 
377
+ python_info = get_language_info("python")
378
+ print("Python generator info:", python_info)
379
+
329
380
  # Interactive code generation
330
- from json_explorer.codegen import create_interactive_handler
381
+ from json_explorer.codegen.interactive import CodegenInteractiveHandler
331
382
 
332
- handler = create_interactive_handler(test_data)
383
+ handler = CodegenInteractiveHandler(test_data)
333
384
  handler.run_interactive() # Launches interactive interface
334
385
  ```
335
386
 
336
387
  ### Supported Languages
337
388
 
338
- | Language | Status | Features |
339
- | -------------- | --------------- | ------------------------------------------------ |
340
- | **Go** | ✅ Full Support | Structs, JSON tags, pointers, configurable types |
341
- | **Python** | 🚧 Coming Soon | Dataclasses, Pydantic models, type hints |
342
- | **TypeScript** | 🚧 Coming Soon | Interfaces, types, optional properties |
343
- | **Rust** | 🚧 Coming Soon | Structs, Serde annotations, Option types |
389
+ | Language | Status | Features |
390
+ | -------------- | --------------- | --------------------------------------------------- |
391
+ | **Go** | ✅ Full Support | Structs, JSON tags, pointers, configurable types |
392
+ | **Python** | ✅ Full Support | Dataclasses, Pydantic models, TypedDict, type hints |
393
+ | **TypeScript** | 🚧 Coming Soon | Interfaces, types, optional properties |
394
+ | **Rust** | 🚧 Coming Soon | Structs, Serde annotations, Option types |
344
395
 
345
396
  ### Code Generation Features
346
397
 
@@ -355,7 +406,7 @@ handler.run_interactive() # Launches interactive interface
355
406
 
356
407
  ## Configuration
357
408
 
358
- ### Code Generation Config Example
409
+ ### Go Configuration Example
359
410
 
360
411
  ```json
361
412
  {
@@ -365,9 +416,29 @@ handler.run_interactive() # Launches interactive interface
365
416
  "json_tag_omitempty": true,
366
417
  "struct_case": "pascal",
367
418
  "field_case": "pascal",
368
- "use_pointers_for_optional": true,
369
- "int_type": "int64",
370
- "float_type": "float64"
419
+ "language_config": {
420
+ "use_pointers_for_optional": true,
421
+ "int_type": "int64",
422
+ "float_type": "float64"
423
+ }
424
+ }
425
+ ```
426
+
427
+ ### Python Configuration Example
428
+
429
+ ```json
430
+ {
431
+ "package_name": "models",
432
+ "add_comments": true,
433
+ "struct_case": "pascal",
434
+ "field_case": "snake",
435
+ "language_config": {
436
+ "style": "pydantic",
437
+ "use_optional": true,
438
+ "pydantic_use_field": true,
439
+ "pydantic_use_alias": true,
440
+ "pydantic_config_dict": true
441
+ }
371
442
  }
372
443
  ```
373
444
 
@@ -375,13 +446,14 @@ Load configuration:
375
446
 
376
447
  ```bash
377
448
  json_explorer data.json --generate go --config config.json
449
+ json_explorer data.json --generate python --config config.json
378
450
  ```
379
451
 
380
452
  ---
381
453
 
382
454
  ## API Reference
383
455
 
384
- For the complete API reference got to [JSON Explorer API Documentation](https://ms-32154.github.io/py-json-analyzer/) or see the source code.
456
+ For the complete API reference go to [JSON Explorer API Documentation](https://ms-32154.github.io/py-json-analyzer/) or see the source code.
385
457
 
386
458
  ---
387
459
 
@@ -389,6 +461,8 @@ For the complete API reference got to [JSON Explorer API Documentation](https://
389
461
 
390
462
  This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
391
463
 
464
+ ---
465
+
392
466
  ## Contributing
393
467
 
394
468
  Contributions are welcome! Please feel free to submit a Pull Request.
@@ -399,6 +473,8 @@ Contributions are welcome! Please feel free to submit a Pull Request.
399
473
  4. Push to the branch (`git push origin feature/AmazingFeature`)
400
474
  5. Open a Pull Request
401
475
 
476
+ ---
477
+
402
478
  ## Support
403
479
 
404
480
  If you encounter any issues or have questions, please:
@@ -1,5 +1,5 @@
1
1
  [![PyPI version](https://img.shields.io/pypi/v/py-json-analyzer.svg)](https://pypi.org/project/py-json-analyzer/)
2
- [![Python 3.9+](https://img.shields.io/badge/python-3.8+-blue.svg)](https://www.python.org/downloads/)
2
+ [![Python 3.11+](https://img.shields.io/badge/python-3.11+-blue.svg)](https://www.python.org/downloads/)
3
3
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
4
4
 
5
5
  # JSON Explorer
@@ -21,7 +21,7 @@
21
21
  ### Code Generation
22
22
 
23
23
  - Generate strongly-typed data structures from JSON
24
- - Multiple language support (Go, with Python, TypeScript, Rust coming soon)
24
+ - Multiple language support (Go, Python, with TypeScript and Rust coming soon)
25
25
  - Smart type detection and conflict resolution
26
26
  - Configurable naming conventions and templates
27
27
  - JSON serialization tags and annotations
@@ -38,7 +38,7 @@
38
38
 
39
39
  ## Requirements
40
40
 
41
- - Python >= 3.9
41
+ - Python >= 3.11
42
42
 
43
43
  Required packages:
44
44
 
@@ -92,6 +92,30 @@ pip install -e .
92
92
  pytest
93
93
  ```
94
94
 
95
+ ### Test Coverage
96
+
97
+ The project includes comprehensive tests for:
98
+
99
+ - **Core modules**: Analysis, search, statistics, tree view, plotting
100
+ - **Codegen core modules**: Naming, schema, configuration, templates
101
+ - **Generators**: Go and Python with all styles
102
+ - **Codegen registry**: Language registration and lookup
103
+ - **Codegen integration**: End-to-end workflows
104
+ - **Edge cases**: None handling, conflicts, deep nesting
105
+
106
+ Run specific test suites:
107
+
108
+ ```bash
109
+ # Core functionality
110
+ pytest tests/test_core.py -v
111
+
112
+ # Go generator
113
+ pytest tests/test_go_generator.py -v
114
+
115
+ # Python generator
116
+ pytest tests/test_python_generator.py -v
117
+ ```
118
+
95
119
  ---
96
120
 
97
121
  ## CLI Usage
@@ -166,6 +190,16 @@ Go-specific options:
166
190
  --no-omitempty Don't add omitempty to JSON tags in Go
167
191
  --json-tag-case {original,snake,camel}
168
192
  Case style for JSON tag names in Go
193
+
194
+ Python-specific options:
195
+ --python-style {dataclass,pydantic,typeddict}
196
+ Python code style (default: dataclass)
197
+ --no-slots Don't use __slots__ in dataclasses
198
+ --frozen Make dataclasses frozen (immutable)
199
+ --kw-only Make dataclass fields keyword-only
200
+ --no-pydantic-field Don't use Field() in Pydantic models
201
+ --pydantic-forbid-extra
202
+ Forbid extra fields in Pydantic models
169
203
  ```
170
204
 
171
205
  ### Examples
@@ -192,10 +226,16 @@ json_explorer data.json --search "isinstance(value, int) and value > 10" --searc
192
226
  json_explorer --list-languages
193
227
 
194
228
  # Generate Go structs
195
- json_explorer data.json --generate go
229
+ json_explorer data.json --generate go --output models.go
230
+
231
+ # Generate Python dataclasses
232
+ json_explorer data.json --generate python --output models.py
233
+
234
+ # Generate Pydantic models
235
+ json_explorer data.json --generate python --python-style pydantic --output models.py
196
236
 
197
237
  # Generate with custom configuration
198
- json_explorer data.json --generate go --output models.go --package-name models
238
+ json_explorer data.json --generate go --package-name models --root-name User
199
239
 
200
240
  # Interactive code generation
201
241
  json_explorer data.json --interactive # Then select code generation menu
@@ -282,10 +322,18 @@ from json_explorer.codegen import (
282
322
  )
283
323
  from json_explorer.analyzer import analyze_json
284
324
 
285
- # Quick generation
325
+ # Quick generation - Go
286
326
  go_code = quick_generate(test_data, language="go")
287
327
  print(go_code)
288
328
 
329
+ # Quick generation - Python dataclass
330
+ python_code = quick_generate(test_data, language="python", style="dataclass")
331
+ print(python_code)
332
+
333
+ # Quick generation - Pydantic model
334
+ pydantic_code = quick_generate(test_data, language="python", style="pydantic")
335
+ print(pydantic_code)
336
+
289
337
  # Detailed generation workflow
290
338
  analysis = analyze_json(test_data)
291
339
  config = create_config(
@@ -307,21 +355,24 @@ print("Supported languages:", languages)
307
355
  go_info = get_language_info("go")
308
356
  print("Go generator info:", go_info)
309
357
 
358
+ python_info = get_language_info("python")
359
+ print("Python generator info:", python_info)
360
+
310
361
  # Interactive code generation
311
- from json_explorer.codegen import create_interactive_handler
362
+ from json_explorer.codegen.interactive import CodegenInteractiveHandler
312
363
 
313
- handler = create_interactive_handler(test_data)
364
+ handler = CodegenInteractiveHandler(test_data)
314
365
  handler.run_interactive() # Launches interactive interface
315
366
  ```
316
367
 
317
368
  ### Supported Languages
318
369
 
319
- | Language | Status | Features |
320
- | -------------- | --------------- | ------------------------------------------------ |
321
- | **Go** | ✅ Full Support | Structs, JSON tags, pointers, configurable types |
322
- | **Python** | 🚧 Coming Soon | Dataclasses, Pydantic models, type hints |
323
- | **TypeScript** | 🚧 Coming Soon | Interfaces, types, optional properties |
324
- | **Rust** | 🚧 Coming Soon | Structs, Serde annotations, Option types |
370
+ | Language | Status | Features |
371
+ | -------------- | --------------- | --------------------------------------------------- |
372
+ | **Go** | ✅ Full Support | Structs, JSON tags, pointers, configurable types |
373
+ | **Python** | ✅ Full Support | Dataclasses, Pydantic models, TypedDict, type hints |
374
+ | **TypeScript** | 🚧 Coming Soon | Interfaces, types, optional properties |
375
+ | **Rust** | 🚧 Coming Soon | Structs, Serde annotations, Option types |
325
376
 
326
377
  ### Code Generation Features
327
378
 
@@ -336,7 +387,7 @@ handler.run_interactive() # Launches interactive interface
336
387
 
337
388
  ## Configuration
338
389
 
339
- ### Code Generation Config Example
390
+ ### Go Configuration Example
340
391
 
341
392
  ```json
342
393
  {
@@ -346,9 +397,29 @@ handler.run_interactive() # Launches interactive interface
346
397
  "json_tag_omitempty": true,
347
398
  "struct_case": "pascal",
348
399
  "field_case": "pascal",
349
- "use_pointers_for_optional": true,
350
- "int_type": "int64",
351
- "float_type": "float64"
400
+ "language_config": {
401
+ "use_pointers_for_optional": true,
402
+ "int_type": "int64",
403
+ "float_type": "float64"
404
+ }
405
+ }
406
+ ```
407
+
408
+ ### Python Configuration Example
409
+
410
+ ```json
411
+ {
412
+ "package_name": "models",
413
+ "add_comments": true,
414
+ "struct_case": "pascal",
415
+ "field_case": "snake",
416
+ "language_config": {
417
+ "style": "pydantic",
418
+ "use_optional": true,
419
+ "pydantic_use_field": true,
420
+ "pydantic_use_alias": true,
421
+ "pydantic_config_dict": true
422
+ }
352
423
  }
353
424
  ```
354
425
 
@@ -356,13 +427,14 @@ Load configuration:
356
427
 
357
428
  ```bash
358
429
  json_explorer data.json --generate go --config config.json
430
+ json_explorer data.json --generate python --config config.json
359
431
  ```
360
432
 
361
433
  ---
362
434
 
363
435
  ## API Reference
364
436
 
365
- For the complete API reference got to [JSON Explorer API Documentation](https://ms-32154.github.io/py-json-analyzer/) or see the source code.
437
+ For the complete API reference go to [JSON Explorer API Documentation](https://ms-32154.github.io/py-json-analyzer/) or see the source code.
366
438
 
367
439
  ---
368
440
 
@@ -370,6 +442,8 @@ For the complete API reference got to [JSON Explorer API Documentation](https://
370
442
 
371
443
  This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
372
444
 
445
+ ---
446
+
373
447
  ## Contributing
374
448
 
375
449
  Contributions are welcome! Please feel free to submit a Pull Request.
@@ -380,6 +454,8 @@ Contributions are welcome! Please feel free to submit a Pull Request.
380
454
  4. Push to the branch (`git push origin feature/AmazingFeature`)
381
455
  5. Open a Pull Request
382
456
 
457
+ ---
458
+
383
459
  ## Support
384
460
 
385
461
  If you encounter any issues or have questions, please:
@@ -0,0 +1 @@
1
+ __version__ = "0.3.0"
@@ -4,7 +4,7 @@ from rich.progress import Progress, SpinnerColumn, TextColumn
4
4
 
5
5
 
6
6
  def detect_timestamp(value):
7
- if not isinstance(value, str):
7
+ if not isinstance(value, str) or len(value) < 4:
8
8
  return False
9
9
  parsed = dateparser.parse(value)
10
10
  return parsed is not None
@@ -27,6 +27,7 @@ def analyze_json(data):
27
27
  progress.update(task, advance=1)
28
28
  children[key] = analyze_node(val)
29
29
  return {"type": "object", "children": children}
30
+
30
31
  elif isinstance(node, list):
31
32
  # Skip empty or null-only lists
32
33
  non_empty_items = [
@@ -67,6 +68,11 @@ def analyze_json(data):
67
68
  }
68
69
 
69
70
  return {"type": "list", "child_type": "mixed"}
71
+
72
+ elif node is None:
73
+ # Explicitly handle None - mark as unknown but with a flag
74
+ return {"type": "unknown", "is_none": True}
75
+
70
76
  else:
71
77
  if isinstance(node, str):
72
78
  if detect_timestamp(node):
@@ -79,11 +85,20 @@ def analyze_json(data):
79
85
  def merge_object_summaries(summaries):
80
86
  key_structures = {}
81
87
  key_counts = Counter()
88
+ key_none_counts = Counter()
82
89
  total = len(summaries)
83
90
 
84
91
  for summary in summaries:
92
+ seen_keys = set()
93
+
85
94
  for key, val in summary.get("children", {}).items():
86
95
  key_counts[key] += 1
96
+ seen_keys.add(key)
97
+
98
+ # Track if this value is None/unknown
99
+ if val.get("type") == "unknown":
100
+ key_none_counts[key] += 1
101
+
87
102
  if key not in key_structures:
88
103
  key_structures[key] = []
89
104
  key_structures[key].append(val)
@@ -93,19 +108,34 @@ def analyze_json(data):
93
108
 
94
109
  for key, structures in key_structures.items():
95
110
  count = key_counts[key]
96
- optional = count < total
111
+ none_count = key_none_counts[key]
112
+
113
+ # Field is optional if:
114
+ # 1. Missing from some objects (count < total)
115
+ # 2. Has None in some objects (none_count > 0)
116
+ optional = (count < total) or (none_count > 0)
97
117
 
98
- # Get unique types for this key
99
- types = {s["type"] for s in structures}
118
+ # Filter out None/unknown types to find concrete types
119
+ concrete_structures = [
120
+ s for s in structures if s.get("type") != "unknown"
121
+ ]
122
+
123
+ # If we have concrete types, use those; otherwise use all structures
124
+ working_structures = (
125
+ concrete_structures if concrete_structures else structures
126
+ )
127
+
128
+ # Get unique types from working structures
129
+ types = {s["type"] for s in working_structures}
100
130
 
101
131
  if len(types) == 1:
102
- # All structures have the same type
132
+ # Single type (possibly with None values)
103
133
  structure_type = list(types)[0]
104
134
 
105
135
  if structure_type == "object":
106
136
  # Recursively merge object structures
107
137
  merged_children, child_conflicts = merge_object_summaries(
108
- structures
138
+ working_structures
109
139
  )
110
140
  merged[key] = {
111
141
  "type": "object",
@@ -117,7 +147,7 @@ def analyze_json(data):
117
147
 
118
148
  elif structure_type == "list":
119
149
  # Merge list structures
120
- merged_list = merge_list_summaries(structures)
150
+ merged_list = merge_list_summaries(working_structures)
121
151
  merged[key] = {
122
152
  "type": "list",
123
153
  "optional": optional,
@@ -125,13 +155,18 @@ def analyze_json(data):
125
155
  }
126
156
 
127
157
  else:
128
- # Primitive type
158
+ # Primitive type (possibly with None)
129
159
  merged[key] = {"type": structure_type, "optional": optional}
130
- else:
131
- # Type conflict
160
+
161
+ elif len(types) > 1:
162
+ # Multiple different types = real conflict
132
163
  merged[key] = {"type": "conflict", "optional": optional}
133
164
  conflicts[key] = list(types)
134
165
 
166
+ else:
167
+ # Should not happen, but handle gracefully
168
+ merged[key] = {"type": "unknown", "optional": optional}
169
+
135
170
  return merged, conflicts
136
171
 
137
172
  def merge_list_summaries(summaries):