jsonobjectify 0.0.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.
File without changes
@@ -0,0 +1,40 @@
1
+ from json import dumps
2
+
3
+
4
+ class JsonObject:
5
+ """Represent a JSON object as a Python object."""
6
+ def __init__(self, info):
7
+ self._info = info
8
+
9
+ def __getattr__(self, name):
10
+ """Return a value from the underlying JSON data using dot notation."""
11
+ try:
12
+ return self._info[name]
13
+ except KeyError:
14
+ raise AttributeError(f"{type(self).__name__} has no attribute {name!r}") from None
15
+
16
+ def __setattr__(self, name, value):
17
+ """Set an attribute (_info) or update the underlying JSON data."""
18
+ if name == "_info":
19
+ super().__setattr__(name, value)
20
+ else:
21
+ self._info[name] = value
22
+
23
+ def to_dict(self):
24
+ """Convert a JsonObject to dictionary."""
25
+ out_dict = {}
26
+ for key, value in self._info.items():
27
+ if isinstance(value, JsonObject):
28
+ out_dict[key] = value.to_dict()
29
+ elif isinstance(value, list):
30
+ out_dict[key] = [
31
+ item.to_dict() if isinstance(item, JsonObject) else item
32
+ for item in value
33
+ ]
34
+ else:
35
+ out_dict[key] = value
36
+ return out_dict
37
+
38
+ def to_json(self):
39
+ """Convert JsonObject to a JSON string."""
40
+ return dumps(self.to_dict())
@@ -0,0 +1,100 @@
1
+ from json import load, loads
2
+ from pathlib import Path
3
+ from .json_object import JsonObject
4
+
5
+
6
+ class JsonPath:
7
+ def __init__(self):
8
+ """Initialize an empty JSON parser."""
9
+ self._root_json_object = None
10
+
11
+ def __getattr__(self, name):
12
+ """Delegate attribute access to the json object."""
13
+ return getattr(self._root_json_object, name)
14
+
15
+ def __getitem__(self, index):
16
+ """Return an item from the root JSON array."""
17
+ return self._root_json_object[index]
18
+
19
+ def __len__(self):
20
+ """Return the length of root JSON array/object"""
21
+ if isinstance(self._root_json_object, JsonObject):
22
+ return len(self._root_json_object.to_dict())
23
+ return len(self._root_json_object)
24
+
25
+ def __setattr__(self, name, value):
26
+ if name == "_root_json_object":
27
+ super().__setattr__(name, value)
28
+ else:
29
+ setattr(self._root_json_object, name, value)
30
+
31
+ def __str__(self):
32
+ if isinstance(self._root_json_object, JsonObject):
33
+ return self._root_json_object.to_json()
34
+ return f"{self._root_json_object}"
35
+
36
+ def __repr__(self):
37
+ if isinstance(self._root_json_object, JsonObject):
38
+ return f"{type(self).__name__}({self._root_json_object.to_dict()})"
39
+ return f"{type(self).__name__}({self._root_json_object})"
40
+
41
+ def _wrap_dict(self, data):
42
+ """Wrap a dictionary in a JsonObject."""
43
+ return JsonObject(data)
44
+
45
+ def _is_valid_json_key(self, key):
46
+ """Check whether a JSON key can be used as a Python attribute."""
47
+ if key.isidentifier():
48
+ return True
49
+ else:
50
+ print(f"Skipping invalid JSON key {key!r}")
51
+ return False
52
+
53
+ def _process_list(self, data: list):
54
+ """Recursively process items in a list."""
55
+ return [self._process_object(item) for item in data]
56
+
57
+ def _process_dict(self, data: dict):
58
+ """Recursively process values in a dictionary."""
59
+ _data = {
60
+ key: self._process_object(value)
61
+ for key, value in data.items()
62
+ if self._is_valid_json_key(key)
63
+ }
64
+ return self._wrap_dict(_data)
65
+
66
+ def _process_object(self, value):
67
+ """Process a JSON object based on its Python type."""
68
+ if isinstance(value, dict):
69
+ return self._process_dict(value)
70
+ elif isinstance(value, list):
71
+ return self._process_list(value)
72
+ return value
73
+
74
+ def _build_root_object(self, py_object):
75
+ """Build the root object from the deserialized JSON."""
76
+ return self._process_object(py_object)
77
+
78
+ @classmethod
79
+ def _from_py_object(cls, py_object):
80
+ obj = cls()
81
+ obj._root_json_object = obj._build_root_object(py_object)
82
+ return obj
83
+
84
+ @classmethod
85
+ def from_json_string(cls, json_string):
86
+ """Create a JsonPath instance from a JSON string."""
87
+ if not isinstance(json_string, str):
88
+ raise TypeError("json_string must be a string")
89
+ if not json_string.strip():
90
+ raise ValueError("JSON string cannot be empty")
91
+ return cls._from_py_object(loads(json_string))
92
+
93
+ @classmethod
94
+ def from_json_file(cls, filename: str):
95
+ """Create a JsonPath instance from a JSON file."""
96
+ path = Path(filename)
97
+ if not path.is_file():
98
+ raise FileNotFoundError(f"File not found {filename}")
99
+ with open(path, mode="r", encoding="utf-8") as json_file:
100
+ return cls._from_py_object(load(json_file))
@@ -0,0 +1,115 @@
1
+ Metadata-Version: 2.3
2
+ Name: jsonobjectify
3
+ Version: 0.0.0
4
+ Summary: A lightweight Python library for converting JSON data into Python objects, simplifying access to nested structures through intuitive dot notation.
5
+ Author: Sandeep Suryaprasad
6
+ Requires-Python: >=3.9
7
+ Project-URL: Homepage, https://github.com/sandeepsuryaprasad/jsonobjectify
8
+ Project-URL: Repository, https://github.com/sandeepsuryaprasad/jsonobjectify
9
+ Project-URL: Issues, https://github.com/sandeepsuryaprasad/jsonobjectify/issues
10
+ Description-Content-Type: text/markdown
11
+
12
+ # jsonobjectify
13
+
14
+ A lightweight Python library for converting JSON data into Python objects,
15
+ simplifying access to nested structures through intuitive dot notation.
16
+
17
+ ## Overview
18
+ Working with complex JSON data often involves repetitive dictionary lookups, especially
19
+ when accessing deeply nested structures. `jsonobjectify` simplifies this process by
20
+ converting JSON data into Python objects, allowing you to access JSON properties using
21
+ familiar attribute notation.
22
+
23
+ Instead of writing chained dictionary lookups, you can navigate nested JSON structures
24
+ using a clean, readable, object-oriented interface.
25
+
26
+ ## Features
27
+
28
+ * **Dot-notation access:** Access JSON properties using Python attributes.
29
+ * **Nested object support:** Navigate deeply nested JSON structures naturally.
30
+ * **List support:** Work with collections of JSON objects.
31
+ * **Dictionary conversion:** Convert mapped objects back into standard Python dictionaries.
32
+ * **JSON serialization:** Serialize objects back into JSON.
33
+ * **Simple API:** Keep your code readable when working with complex JSON responses.
34
+
35
+ ## Installation
36
+
37
+ ```bash
38
+ pip install jsonobjectify
39
+ ```
40
+
41
+ ## Usage
42
+
43
+ Consider the following JSON data representing an employee and their department:
44
+
45
+ ```python
46
+ response = """{
47
+ "id": 1,
48
+ "name": "Michael Anderson",
49
+ "email": "michael.anderson@example.com",
50
+ "website": "www.example.dev",
51
+ "address": {
52
+ "city": "Austin",
53
+ "state": "TX",
54
+ "country": "United States",
55
+ "geo_location": {"lat": "30.2672", "lng": "-97.7431"}
56
+ },
57
+ "skills": [
58
+ {"name": "Python", "level": "Advanced"},
59
+ {"name": "C", "level": "Advanced"},
60
+ {"name": "C++", "level": "Intermediate"}
61
+ ]
62
+ }"""
63
+ ```
64
+
65
+ With `jsonobjectify`, you can access the data through object attributes rather than
66
+ repeated dictionary lookups.
67
+
68
+ ```python
69
+ from jsonobjectify import JsonPath
70
+
71
+ employee = JsonPath.from_json_string(response)
72
+
73
+ print(employee.name)
74
+ print(employee.address.city)
75
+ print(employee.skills[0].name)
76
+ print(employee.skills[1].level)
77
+ ```
78
+
79
+ **Output**
80
+
81
+ ```text
82
+ 'Michael Anderson'
83
+ 'Austin'
84
+ 'Python'
85
+ 'Advanced'
86
+ ```
87
+
88
+ The example above illustrates the intended API. Adjust the import and construction methods
89
+ to match the implementation in your repository.
90
+
91
+ ## Converting Objects Back to JSON
92
+
93
+ `jsonobjectify` is intended to support conversion back to standard Python dictionaries and
94
+ JSON strings, making it convenient to work with transformed data.
95
+
96
+ ```python
97
+ # Convert the object to a Python dictionary
98
+ data = employee.to_dict()
99
+
100
+ # Serialize the object to a JSON string
101
+ json_data = employee.to_json()
102
+ ```
103
+
104
+ ## Requirements
105
+
106
+ * Python 3.9 or later
107
+
108
+ ## Contributing
109
+
110
+ Contributions, bug reports, and feature suggestions are welcome. Please open an issue to
111
+ discuss a proposed change before submitting a pull request.
112
+
113
+ ## License
114
+
115
+ This project is licensed under the MIT License. See the `LICENSE` file for details.
@@ -0,0 +1,6 @@
1
+ jsonobjectify/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ jsonobjectify/json_object.py,sha256=t-tflGSwGG2zqDlK6Iv6f7IEFB78GPl5Zlx9aR3YReg,1311
3
+ jsonobjectify/json_path.py,sha256=tA1qsD7ZtySb1t50z1ZMEo6gh_cUSFKzh3q0MbWoc5I,3531
4
+ jsonobjectify-0.0.0.dist-info/WHEEL,sha256=xTCBFIZIIyRSxyowOv5Wqg_jFU6KsdIffuulBB09Ph8,80
5
+ jsonobjectify-0.0.0.dist-info/METADATA,sha256=KVCmFJMtnFQvXoG0F61CAKHp2h_qCdU8V-S8WoC5zvQ,3436
6
+ jsonobjectify-0.0.0.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: uv 0.13.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any