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.
- {py_json_analyzer-0.2.0/py_json_analyzer.egg-info → py_json_analyzer-0.3.0}/PKG-INFO +96 -20
- {py_json_analyzer-0.2.0 → py_json_analyzer-0.3.0}/README.md +95 -19
- py_json_analyzer-0.3.0/json_explorer/__init__.py +1 -0
- {py_json_analyzer-0.2.0 → py_json_analyzer-0.3.0}/json_explorer/analyzer.py +45 -10
- py_json_analyzer-0.3.0/json_explorer/codegen/__init__.py +230 -0
- {py_json_analyzer-0.2.0 → py_json_analyzer-0.3.0}/json_explorer/codegen/cli_integration.py +277 -140
- py_json_analyzer-0.3.0/json_explorer/codegen/core/__init__.py +98 -0
- py_json_analyzer-0.3.0/json_explorer/codegen/core/config.py +345 -0
- py_json_analyzer-0.3.0/json_explorer/codegen/core/generator.py +378 -0
- py_json_analyzer-0.3.0/json_explorer/codegen/core/naming.py +337 -0
- py_json_analyzer-0.3.0/json_explorer/codegen/core/schema.py +582 -0
- py_json_analyzer-0.3.0/json_explorer/codegen/core/templates.py +284 -0
- {py_json_analyzer-0.2.0 → py_json_analyzer-0.3.0}/json_explorer/codegen/interactive.py +225 -156
- py_json_analyzer-0.3.0/json_explorer/codegen/languages/__init__.py +189 -0
- {py_json_analyzer-0.2.0 → py_json_analyzer-0.3.0}/json_explorer/codegen/languages/go/__init__.py +10 -15
- py_json_analyzer-0.3.0/json_explorer/codegen/languages/go/config.py +225 -0
- {py_json_analyzer-0.2.0 → py_json_analyzer-0.3.0}/json_explorer/codegen/languages/go/generator.py +137 -89
- {py_json_analyzer-0.2.0 → py_json_analyzer-0.3.0}/json_explorer/codegen/languages/go/interactive.py +114 -117
- py_json_analyzer-0.3.0/json_explorer/codegen/languages/go/naming.py +103 -0
- py_json_analyzer-0.3.0/json_explorer/codegen/languages/python/__init__.py +43 -0
- py_json_analyzer-0.3.0/json_explorer/codegen/languages/python/config.py +328 -0
- py_json_analyzer-0.3.0/json_explorer/codegen/languages/python/generator.py +422 -0
- py_json_analyzer-0.3.0/json_explorer/codegen/languages/python/interactive.py +344 -0
- py_json_analyzer-0.3.0/json_explorer/codegen/languages/python/naming.py +157 -0
- py_json_analyzer-0.3.0/json_explorer/codegen/registry.py +395 -0
- {py_json_analyzer-0.2.0 → py_json_analyzer-0.3.0}/json_explorer/main.py +1 -1
- {py_json_analyzer-0.2.0 → py_json_analyzer-0.3.0}/json_explorer/search.py +1 -1
- {py_json_analyzer-0.2.0 → py_json_analyzer-0.3.0}/json_explorer/stats.py +1 -1
- {py_json_analyzer-0.2.0 → py_json_analyzer-0.3.0/py_json_analyzer.egg-info}/PKG-INFO +96 -20
- {py_json_analyzer-0.2.0 → py_json_analyzer-0.3.0}/py_json_analyzer.egg-info/SOURCES.txt +17 -0
- {py_json_analyzer-0.2.0 → py_json_analyzer-0.3.0}/pyproject.toml +1 -1
- {py_json_analyzer-0.2.0 → py_json_analyzer-0.3.0}/setup.cfg +2 -2
- py_json_analyzer-0.3.0/tests/test_gen_conftest.py +54 -0
- py_json_analyzer-0.3.0/tests/test_gen_core_config.py +92 -0
- py_json_analyzer-0.3.0/tests/test_gen_core_naming.py +81 -0
- py_json_analyzer-0.3.0/tests/test_gen_core_schema.py +161 -0
- py_json_analyzer-0.3.0/tests/test_gen_edge.py +512 -0
- py_json_analyzer-0.3.0/tests/test_gen_error_handling.py +27 -0
- py_json_analyzer-0.3.0/tests/test_gen_integration.py +185 -0
- py_json_analyzer-0.3.0/tests/test_gen_performance.py +37 -0
- py_json_analyzer-0.3.0/tests/test_gen_registry.py +110 -0
- py_json_analyzer-0.3.0/tests/test_gen_templates.py +32 -0
- py_json_analyzer-0.3.0/tests/test_go_generator.py +187 -0
- py_json_analyzer-0.3.0/tests/test_python_generator.py +230 -0
- py_json_analyzer-0.2.0/json_explorer/__init__.py +0 -1
- py_json_analyzer-0.2.0/json_explorer/codegen/__init__.py +0 -178
- py_json_analyzer-0.2.0/json_explorer/codegen/core/__init__.py +0 -41
- py_json_analyzer-0.2.0/json_explorer/codegen/core/config.py +0 -170
- py_json_analyzer-0.2.0/json_explorer/codegen/core/generator.py +0 -212
- py_json_analyzer-0.2.0/json_explorer/codegen/core/naming.py +0 -175
- py_json_analyzer-0.2.0/json_explorer/codegen/core/schema.py +0 -483
- py_json_analyzer-0.2.0/json_explorer/codegen/core/templates.py +0 -174
- py_json_analyzer-0.2.0/json_explorer/codegen/languages/__init__.py +0 -35
- py_json_analyzer-0.2.0/json_explorer/codegen/languages/go/config.py +0 -115
- py_json_analyzer-0.2.0/json_explorer/codegen/languages/go/naming.py +0 -81
- py_json_analyzer-0.2.0/json_explorer/codegen/registry.py +0 -355
- {py_json_analyzer-0.2.0 → py_json_analyzer-0.3.0}/LICENSE +0 -0
- {py_json_analyzer-0.2.0 → py_json_analyzer-0.3.0}/json_explorer/__main__.py +0 -0
- {py_json_analyzer-0.2.0 → py_json_analyzer-0.3.0}/json_explorer/cli.py +0 -0
- {py_json_analyzer-0.2.0 → py_json_analyzer-0.3.0}/json_explorer/filter_parser.py +0 -0
- {py_json_analyzer-0.2.0 → py_json_analyzer-0.3.0}/json_explorer/interactive.py +0 -0
- {py_json_analyzer-0.2.0 → py_json_analyzer-0.3.0}/json_explorer/tree_view.py +0 -0
- {py_json_analyzer-0.2.0 → py_json_analyzer-0.3.0}/json_explorer/utils.py +0 -0
- {py_json_analyzer-0.2.0 → py_json_analyzer-0.3.0}/json_explorer/visualizer.py +0 -0
- {py_json_analyzer-0.2.0 → py_json_analyzer-0.3.0}/py_json_analyzer.egg-info/dependency_links.txt +0 -0
- {py_json_analyzer-0.2.0 → py_json_analyzer-0.3.0}/py_json_analyzer.egg-info/entry_points.txt +0 -0
- {py_json_analyzer-0.2.0 → py_json_analyzer-0.3.0}/py_json_analyzer.egg-info/requires.txt +0 -0
- {py_json_analyzer-0.2.0 → py_json_analyzer-0.3.0}/py_json_analyzer.egg-info/top_level.txt +0 -0
- {py_json_analyzer-0.2.0 → py_json_analyzer-0.3.0}/setup.py +0 -0
- {py_json_analyzer-0.2.0 → py_json_analyzer-0.3.0}/tests/__init__.py +0 -0
- {py_json_analyzer-0.2.0 → py_json_analyzer-0.3.0}/tests/test_analyzer.py +0 -0
- {py_json_analyzer-0.2.0 → py_json_analyzer-0.3.0}/tests/test_search.py +0 -0
- {py_json_analyzer-0.2.0 → py_json_analyzer-0.3.0}/tests/test_stats.py +0 -0
- {py_json_analyzer-0.2.0 → py_json_analyzer-0.3.0}/tests/test_tree_view.py +0 -0
- {py_json_analyzer-0.2.0 → py_json_analyzer-0.3.0}/tests/test_utils.py +0 -0
- {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.
|
|
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
|
[](https://pypi.org/project/py-json-analyzer/)
|
|
21
|
-
[](https://www.python.org/downloads/)
|
|
22
22
|
[](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,
|
|
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.
|
|
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 --
|
|
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
|
|
381
|
+
from json_explorer.codegen.interactive import CodegenInteractiveHandler
|
|
331
382
|
|
|
332
|
-
handler =
|
|
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** |
|
|
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
|
-
###
|
|
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
|
-
"
|
|
369
|
-
|
|
370
|
-
|
|
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
|
|
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
|
[](https://pypi.org/project/py-json-analyzer/)
|
|
2
|
-
[](https://www.python.org/downloads/)
|
|
3
3
|
[](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,
|
|
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.
|
|
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 --
|
|
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
|
|
362
|
+
from json_explorer.codegen.interactive import CodegenInteractiveHandler
|
|
312
363
|
|
|
313
|
-
handler =
|
|
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** |
|
|
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
|
-
###
|
|
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
|
-
"
|
|
350
|
-
|
|
351
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
#
|
|
99
|
-
|
|
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
|
-
#
|
|
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
|
-
|
|
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(
|
|
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
|
-
|
|
131
|
-
|
|
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):
|