Skip to content

Commit a675fd3

Browse files
Merge pull request #11 from abhaykatheria/feat/library-optimizations-v0.2.0
Feat/library optimizations v0.2.0
2 parents 7673d8a + c431444 commit a675fd3

File tree

9 files changed

+725
-219
lines changed

9 files changed

+725
-219
lines changed

CHANGELOG.txt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
11
Change Log
22
============
3+
0.2.0(Current Date - Replace with Actual)
4+
-----------------------------------------
5+
- Added `convert()` function for library usage (supports JSON string, dict, or file path as input; can return HTML string or write to file).
6+
- Refactored HTML generation logic into a base module (`html_base.py`) for improved maintainability and theme structure.
7+
- Optimized HTML string building processes in handlers for better performance.
8+
- Updated CLI (`__main__.py`) to use the new `convert()` library function.
9+
- Updated README with library usage instructions and development notes.
10+
- Updated `setup.py` to use `README.md` for long description and set version to 0.2.0.
11+
312
0.0.1(23/09/2021)
413
-----------------
514
- First Release

README.md

Lines changed: 64 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,11 @@ This can also be used as a command line tool for the same purpose.
1111

1212
* [Getting Started](#getting-started)
1313
* [Installation](#installation)
14-
* [Usage](#usage)
14+
* [Usage (CLI)](#usage-cli)
1515
* [Sample command](#sample-command)
16+
* [Using as a Library](#using-as-a-library)
1617
* [Themes](#themes)
18+
* [Development Notes](#development-notes)
1719
* [Contributors](#contributors)
1820
[](/mdtoc)
1921

@@ -26,7 +28,7 @@ This can also be used as a command line tool for the same purpose.
2628
- CD into the cloned repo
2729
- Install using following command ``` pip install . ```
2830

29-
## Usage
31+
## Usage (CLI)
3032
You can invoke the cli with typing json2tree command.
3133
There are 2 necessary arguments -
3234
- -j : this flag will take the input json file.
@@ -38,13 +40,73 @@ There is a third theme flag
3840
### Sample command
3941
``` json2tree -j example.json -o output.html -t 1 ```
4042

43+
# Using as a Library
44+
45+
You can use `json2tree` as a Python library to convert JSON data into HTML. The primary function for this is `convert` from the `json2tree` package.
46+
47+
```python
48+
from json2tree import convert
49+
import json
50+
51+
# Example 1: Convert JSON file to HTML file, specifying theme 2
52+
# Ensure 'input.json' exists or provide a valid path.
53+
# convert('input.json', theme='2', output_file='output_theme2.html')
54+
55+
# Example 2: Convert a JSON string to an HTML string (theme 1 default)
56+
json_string = '{"name": "Test User", "details": {"age": 30, "isStudent": false, "courses": ["Math", "Science"]}}'
57+
html_output_string = convert(json_string)
58+
# print(html_output_string) # Or save it to a file:
59+
# with open('output_from_string.html', 'w', encoding='utf-8') as f:
60+
# f.write(html_output_string)
61+
62+
# Example 3: Convert a Python dictionary to HTML and save to a file
63+
my_dict = {
64+
"project": "json2tree",
65+
"version": "0.2.0",
66+
"data": {
67+
"items": [
68+
{"id": 1, "value": "apple"},
69+
{"id": 2, "value": "banana"}
70+
],
71+
"status": "ok",
72+
"nested_data": {
73+
"key1": "value1",
74+
"key2": [10, 20, 30]
75+
}
76+
}
77+
}
78+
convert(my_dict, theme='1', output_file='output_from_dict.html')
79+
80+
# Example 4: Convert a Python dictionary to an HTML string with theme 2
81+
another_dict = {"message": "Hello, World!", "code": 200}
82+
html_string_theme2 = convert(another_dict, theme='2')
83+
# print(html_string_theme2)
84+
```
85+
86+
**`convert` function parameters:**
87+
88+
* `json_input`: The JSON data to convert. Can be:
89+
* A file path (string) to a JSON file.
90+
* A JSON formatted string.
91+
* A Python dictionary.
92+
* `theme`: Theme identifier string ('1' or '2'). Defaults to '1'.
93+
* `output_file`: Optional. File path to save the HTML output. If `None` (default), the HTML string is returned.
94+
4195
# Themes
4296
Currently there are only 2 themes.
4397
- ### Theme 1
4498
![image](https://user-images.githubusercontent.com/40055274/134461395-f738857d-a543-4a1b-8ab6-71d02e7c5e92.png)
4599
- ### Theme 2
46100
![image](https://user-images.githubusercontent.com/40055274/134461586-f5b071af-64d5-46e9-ba4d-946936ce34f7.png)
47101

102+
# Development Notes
103+
Recent versions (v0.2.0) include significant refactoring for:
104+
- Improved maintainability by centralizing HTML generation logic.
105+
- Enhanced theme structure.
106+
- Performance optimizations in HTML string building processes.
107+
- Introduction of the `convert()` function for more flexible library usage.
108+
48109
# Contributors
49110
@abhaykatheria
50111
@m1-key
112+
AI Contributor via Google-ChatTool

README.txt

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,111 @@
1+
# JSON 2 Tree [![Downloads](https://pepy.tech/badge/json2tree)](https://pepy.tech/project/json2tree)
12
A python library to create HTML tree view from JSON files.
23
This can also be used as a command line tool for the same purpose.
34

5+
6+
<img src="J2T.jpg" height=400px />
7+
8+
[](mdtoc)
9+
# Table of Contents
10+
11+
* [Getting Started](#getting-started)
12+
* [Installation](#installation)
13+
* [Usage (CLI)](#usage-cli)
14+
* [Sample command](#sample-command)
15+
* [Using as a Library](#using-as-a-library)
16+
* [Themes](#themes)
17+
* [Development Notes](#development-notes)
18+
* [Contributors](#contributors)
19+
[](/mdtoc)
20+
21+
# Getting Started
22+
## Installation
23+
- Install usig pip `pip install json2tree`
24+
### or
25+
- Clone this repo by running following command
26+
``` git clone https://github.com/abhaykatheria/json2tree ```
27+
- CD into the cloned repo
28+
- Install using following command ``` pip install . ```
29+
30+
## Usage (CLI)
31+
You can invoke the cli with typing json2tree command.
32+
There are 2 necessary arguments -
33+
- -j : this flag will take the input json file.
34+
- -o : this flag will set up the output file.
35+
36+
There is a third theme flag
37+
- -t : this can be used to set the theme of html output.
38+
39+
### Sample command
40+
``` json2tree -j example.json -o output.html -t 1 ```
41+
42+
# Using as a Library
43+
44+
You can use `json2tree` as a Python library to convert JSON data into HTML. The primary function for this is `convert` from the `json2tree` package.
45+
46+
```python
47+
from json2tree import convert
48+
import json
49+
50+
# Example 1: Convert JSON file to HTML file, specifying theme 2
51+
# Ensure 'input.json' exists or provide a valid path.
52+
# convert('input.json', theme='2', output_file='output_theme2.html')
53+
54+
# Example 2: Convert a JSON string to an HTML string (theme 1 default)
55+
json_string = '{"name": "Test User", "details": {"age": 30, "isStudent": false, "courses": ["Math", "Science"]}}'
56+
html_output_string = convert(json_string)
57+
# print(html_output_string) # Or save it to a file:
58+
# with open('output_from_string.html', 'w', encoding='utf-8') as f:
59+
# f.write(html_output_string)
60+
61+
# Example 3: Convert a Python dictionary to HTML and save to a file
62+
my_dict = {
63+
"project": "json2tree",
64+
"version": "0.2.0",
65+
"data": {
66+
"items": [
67+
{"id": 1, "value": "apple"},
68+
{"id": 2, "value": "banana"}
69+
],
70+
"status": "ok",
71+
"nested_data": {
72+
"key1": "value1",
73+
"key2": [10, 20, 30]
74+
}
75+
}
76+
}
77+
convert(my_dict, theme='1', output_file='output_from_dict.html')
78+
79+
# Example 4: Convert a Python dictionary to an HTML string with theme 2
80+
another_dict = {"message": "Hello, World!", "code": 200}
81+
html_string_theme2 = convert(another_dict, theme='2')
82+
# print(html_string_theme2)
83+
```
84+
85+
**`convert` function parameters:**
86+
87+
* `json_input`: The JSON data to convert. Can be:
88+
* A file path (string) to a JSON file.
89+
* A JSON formatted string.
90+
* A Python dictionary.
91+
* `theme`: Theme identifier string ('1' or '2'). Defaults to '1'.
92+
* `output_file`: Optional. File path to save the HTML output. If `None` (default), the HTML string is returned.
93+
94+
# Themes
95+
Currently there are only 2 themes.
96+
- ### Theme 1
97+
![image](https://user-images.githubusercontent.com/40055274/134461395-f738857d-a543-4a1b-8ab6-71d02e7c5e92.png)
98+
- ### Theme 2
99+
![image](https://user-images.githubusercontent.com/40055274/134461586-f5b071af-64d5-46e9-ba4d-946936ce34f7.png)
100+
101+
# Development Notes
102+
Recent versions (v0.2.0) include significant refactoring for:
103+
- Improved maintainability by centralizing HTML generation logic.
104+
- Enhanced theme structure.
105+
- Performance optimizations in HTML string building processes.
106+
- Introduction of the `convert()` function for more flexible library usage.
107+
108+
# Contributors
109+
@abhaykatheria
110+
@m1-key
111+
AI Contributor via Google-ChatTool

json2tree/__init__.py

Lines changed: 98 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,99 @@
1+
import json
2+
import os
13

2-
__version__ = "0.1.0"
3-
__author__ = 'Abhay Katheria and Mithilesh Tiwari'
4+
# Attempt to import from __main__ first for the generate_from_file functionality
5+
# and create_output_file. If __main__ is not available (e.g. during package import by setup.py),
6+
# these will be handled by direct calls later if possible.
7+
try:
8+
from .__main__ import generate as generate_from_file_path
9+
from .__main__ import create_output_file
10+
except ImportError:
11+
# This might happen if setup.py imports __init__.py before __main__.py is in sys.path in a structured way
12+
# Or if used in a context where __main__ is not directly runnable as a module entry.
13+
# We will define fallbacks or ensure direct calls for core logic.
14+
generate_from_file_path = None # Placeholder, direct file handling will be in convert
15+
create_output_file = None # Placeholder, direct file writing will be in convert
16+
17+
18+
from .theme_1 import html as html_1
19+
from .theme_2 import html as html_2
20+
21+
__version__ = "0.2.0" # Updated version
22+
__author__ = 'Abhay Katheria, Mithilesh Tiwari, and AI Contributor'
23+
__all__ = ['convert']
24+
25+
26+
def convert(json_input, theme='1', output_file=None):
27+
"""
28+
Converts JSON input to an HTML tree representation.
29+
30+
:param json_input: JSON data to convert. Can be:
31+
- A file path (string) to a JSON file.
32+
- A JSON formatted string.
33+
- A Python dictionary.
34+
:param theme: Theme identifier string ('1' or '2'). Defaults to '1'.
35+
:param output_file: Optional. File path to save the HTML output.
36+
If None, the HTML string is returned.
37+
:return: HTML string if output_file is None, otherwise None.
38+
:raises TypeError: If json_input is not a str, dict.
39+
:raises ValueError: If json_input string is not a valid JSON or file path.
40+
"""
41+
html_string = ''
42+
json_data = None
43+
44+
if isinstance(json_input, str):
45+
# Heuristic: if it starts with { or [, it's likely a JSON string. Otherwise, could be a path.
46+
# This isn't foolproof but covers many common cases.
47+
is_likely_json_payload = json_input.strip().startswith(("{", "["))
48+
49+
if os.path.exists(json_input):
50+
try:
51+
with open(json_input, 'r', encoding='utf-8') as f:
52+
json_data = json.load(f)
53+
except json.JSONDecodeError: # File exists but is not valid JSON
54+
raise ValueError(f"Invalid JSON in file: {json_input}")
55+
# FileNotFoundError here would be a race condition if os.path.exists was true moments before.
56+
# Python's default FileNotFoundError would propagate.
57+
elif is_likely_json_payload: # Not a file path, but looks like a JSON string
58+
try:
59+
json_data = json.loads(json_input)
60+
except json.JSONDecodeError as e: # Does look like JSON but is malformed
61+
raise ValueError(f"Malformed JSON string provided: {e}")
62+
else: # Not an existing file path, and not starting like a JSON payload.
63+
# Treat as a non-existent file path or invalid input.
64+
raise ValueError(f"Input string '{json_input}' is not an existing file path and not a recognizable JSON string.")
65+
elif isinstance(json_input, dict):
66+
json_data = json_input
67+
else:
68+
raise TypeError("json_input must be a file path (str), a JSON string (str), or a dictionary.")
69+
70+
if json_data is None: # Should have been caught by now, but as a safeguard
71+
raise ValueError("Failed to parse or load JSON input.")
72+
73+
if theme == '1':
74+
html_string = html_1.create_html_report(json_data)
75+
elif theme == '2':
76+
html_string = html_2.create_html_report(json_data)
77+
else: # Default to theme 1 if an invalid theme is chosen
78+
html_string = html_1.create_html_report(json_data)
79+
80+
if output_file:
81+
# Debug prints
82+
print(f"DEBUG: Attempting to write to output_file: {output_file}")
83+
print(f"DEBUG: Length of html_string: {len(html_string)}")
84+
if len(html_string) < 200: # Print a snippet if short
85+
print(f"DEBUG: HTML_STRING (snippet): {html_string[:100]}...{html_string[-50:]}")
86+
else:
87+
print(f"DEBUG: HTML_STRING (snippet): {html_string[:100]}...{html_string[-100:]}")
88+
89+
try:
90+
with open(output_file, 'w', encoding='utf-8') as f:
91+
f.write(html_string)
92+
print(f"DEBUG: Successfully wrote to {output_file}") # Confirm write
93+
return None # Function signature implies None when writing to file
94+
except IOError as e:
95+
print(f"DEBUG: IOError during write: {e}") # Debug IOError
96+
# Consider how to handle IOErrors, e.g., re-raise or log
97+
raise IOError(f"Could not write to output file: {output_file}")
98+
else:
99+
return html_string

0 commit comments

Comments
 (0)