jentic-openapi-traverse 1.0.0a22__py3-none-any.whl → 1.0.0a24__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.
- jentic/apitools/openapi/traverse/datamodels/low/__init__.py +14 -0
- jentic/apitools/openapi/traverse/datamodels/low/introspection.py +114 -0
- jentic/apitools/openapi/traverse/datamodels/low/merge.py +111 -0
- jentic/apitools/openapi/traverse/datamodels/low/path.py +164 -0
- jentic/apitools/openapi/traverse/datamodels/low/py.typed +0 -0
- jentic/apitools/openapi/traverse/datamodels/low/traversal.py +245 -0
- jentic_openapi_traverse-1.0.0a24.dist-info/METADATA +518 -0
- jentic_openapi_traverse-1.0.0a24.dist-info/RECORD +14 -0
- jentic_openapi_traverse-1.0.0a22.dist-info/METADATA +0 -209
- jentic_openapi_traverse-1.0.0a22.dist-info/RECORD +0 -8
- {jentic_openapi_traverse-1.0.0a22.dist-info → jentic_openapi_traverse-1.0.0a24.dist-info}/WHEEL +0 -0
- {jentic_openapi_traverse-1.0.0a22.dist-info → jentic_openapi_traverse-1.0.0a24.dist-info}/licenses/LICENSE +0 -0
- {jentic_openapi_traverse-1.0.0a22.dist-info → jentic_openapi_traverse-1.0.0a24.dist-info}/licenses/NOTICE +0 -0
|
@@ -1,209 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: jentic-openapi-traverse
|
|
3
|
-
Version: 1.0.0a22
|
|
4
|
-
Summary: Jentic OpenAPI Traversal Utilities
|
|
5
|
-
Author: Jentic
|
|
6
|
-
Author-email: Jentic <hello@jentic.com>
|
|
7
|
-
License-Expression: Apache-2.0
|
|
8
|
-
License-File: LICENSE
|
|
9
|
-
License-File: NOTICE
|
|
10
|
-
Requires-Python: >=3.11
|
|
11
|
-
Project-URL: Homepage, https://github.com/jentic/jentic-openapi-tools
|
|
12
|
-
Description-Content-Type: text/markdown
|
|
13
|
-
|
|
14
|
-
# jentic-openapi-traverse
|
|
15
|
-
|
|
16
|
-
A Python library for traversing OpenAPI documents. This package is part of the Jentic OpenAPI Tools ecosystem and provides two types of traversal:
|
|
17
|
-
|
|
18
|
-
1. **JSON Traversal** (current) - Generic depth-first traversal of JSON-like structures
|
|
19
|
-
2. **Datamodel Traversal** (planned) - OpenAPI-aware semantic traversal with visitor pattern
|
|
20
|
-
|
|
21
|
-
## Installation
|
|
22
|
-
|
|
23
|
-
```bash
|
|
24
|
-
pip install jentic-openapi-traverse
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
**Prerequisites:**
|
|
28
|
-
- Python 3.11+
|
|
29
|
-
|
|
30
|
-
---
|
|
31
|
-
|
|
32
|
-
## JSON Traversal (Current Implementation)
|
|
33
|
-
|
|
34
|
-
Generic depth-first traversal of any JSON-like structure (dicts, lists, scalars).
|
|
35
|
-
Works with raw parsed OpenAPI documents or any other JSON data.
|
|
36
|
-
|
|
37
|
-
### Quick Start
|
|
38
|
-
|
|
39
|
-
```python
|
|
40
|
-
from jentic.apitools.openapi.traverse.json import traverse
|
|
41
|
-
|
|
42
|
-
# Traverse a nested structure
|
|
43
|
-
data = {
|
|
44
|
-
"openapi": "3.1.0",
|
|
45
|
-
"info": {"title": "My API", "version": "1.0.0"},
|
|
46
|
-
"paths": {
|
|
47
|
-
"/users": {
|
|
48
|
-
"get": {"summary": "List users"}
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
# Walk all nodes
|
|
54
|
-
for node in traverse(data):
|
|
55
|
-
print(f"{node.format_path()}: {node.value}")
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
Output:
|
|
59
|
-
```
|
|
60
|
-
openapi: 3.1.0
|
|
61
|
-
info: {'title': 'My API', 'version': '1.0.0'}
|
|
62
|
-
info.title: My API
|
|
63
|
-
info.version: 1.0.0
|
|
64
|
-
paths: {'/users': {'get': {'summary': 'List users'}}}
|
|
65
|
-
paths./users: {'get': {'summary': 'List users'}}
|
|
66
|
-
paths./users.get: {'summary': 'List users'}
|
|
67
|
-
paths./users.get.summary: List users
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
### Working with Paths
|
|
71
|
-
|
|
72
|
-
```python
|
|
73
|
-
from jentic.apitools.openapi.traverse.json import traverse
|
|
74
|
-
|
|
75
|
-
data = {
|
|
76
|
-
"users": [
|
|
77
|
-
{"name": "Alice", "email": "alice@example.com"},
|
|
78
|
-
{"name": "Bob", "email": "bob@example.com"}
|
|
79
|
-
]
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
for node in traverse(data):
|
|
83
|
-
# Access path information
|
|
84
|
-
print(f"Path: {node.path}")
|
|
85
|
-
print(f"Segment: {node.segment}")
|
|
86
|
-
print(f"Full path: {node.full_path}")
|
|
87
|
-
print(f"Formatted: {node.format_path()}")
|
|
88
|
-
print(f"Depth: {len(node.ancestors)}")
|
|
89
|
-
print()
|
|
90
|
-
```
|
|
91
|
-
|
|
92
|
-
### Custom Path Formatting
|
|
93
|
-
|
|
94
|
-
```python
|
|
95
|
-
for node in traverse(data):
|
|
96
|
-
# Default dot separator
|
|
97
|
-
print(node.format_path()) # e.g., "paths./users.get.summary"
|
|
98
|
-
|
|
99
|
-
# Custom separator
|
|
100
|
-
print(node.format_path(separator="/")) # e.g., "paths//users/get/summary"
|
|
101
|
-
```
|
|
102
|
-
|
|
103
|
-
### Finding Specific Nodes
|
|
104
|
-
|
|
105
|
-
```python
|
|
106
|
-
# Find all $ref references in a document
|
|
107
|
-
refs = [
|
|
108
|
-
node.value["$ref"]
|
|
109
|
-
for node in traverse(openapi_doc)
|
|
110
|
-
if isinstance(node.value, dict) and "$ref" in node.value
|
|
111
|
-
]
|
|
112
|
-
|
|
113
|
-
# Find all nodes at a specific path segment
|
|
114
|
-
schemas = [
|
|
115
|
-
node.value
|
|
116
|
-
for node in traverse(openapi_doc)
|
|
117
|
-
if node.segment == "schema"
|
|
118
|
-
]
|
|
119
|
-
|
|
120
|
-
# Find deeply nested values
|
|
121
|
-
response_descriptions = [
|
|
122
|
-
node.value
|
|
123
|
-
for node in traverse(openapi_doc)
|
|
124
|
-
if node.segment == "description" and "responses" in node.path
|
|
125
|
-
]
|
|
126
|
-
```
|
|
127
|
-
|
|
128
|
-
### API Reference
|
|
129
|
-
|
|
130
|
-
#### `traverse(root: JSONValue) -> Iterator[TraversalNode]`
|
|
131
|
-
|
|
132
|
-
Performs depth-first traversal of a JSON-like structure.
|
|
133
|
-
|
|
134
|
-
**Parameters:**
|
|
135
|
-
- `root`: The data structure to traverse (dict, list, or scalar)
|
|
136
|
-
|
|
137
|
-
**Returns:**
|
|
138
|
-
- Iterator of `TraversalNode` objects
|
|
139
|
-
|
|
140
|
-
**Yields:**
|
|
141
|
-
- For dicts: one node per key-value pair
|
|
142
|
-
- For lists: one node per index-item pair
|
|
143
|
-
- Scalars at root don't yield nodes (but are accessible via parent nodes)
|
|
144
|
-
|
|
145
|
-
#### `TraversalNode`
|
|
146
|
-
|
|
147
|
-
Immutable dataclass representing a node encountered during traversal.
|
|
148
|
-
|
|
149
|
-
**Attributes:**
|
|
150
|
-
- `path: JSONPath` - Path from root to the parent container (tuple of segments)
|
|
151
|
-
- `parent: JSONContainer` - The parent container (dict or list)
|
|
152
|
-
- `segment: PathSeg` - The key (for dicts) or index (for lists) within parent
|
|
153
|
-
- `value: JSONValue` - The actual value at `parent[segment]`
|
|
154
|
-
- `ancestors: tuple[JSONValue, ...]` - Ordered tuple of values from root down to (but not including) parent
|
|
155
|
-
|
|
156
|
-
**Properties:**
|
|
157
|
-
- `full_path: JSONPath` - Complete path from root to this value (`path + (segment,)`)
|
|
158
|
-
|
|
159
|
-
**Methods:**
|
|
160
|
-
- `format_path(separator: str = ".") -> str` - Format the full path as a human-readable string
|
|
161
|
-
|
|
162
|
-
### Usage Examples
|
|
163
|
-
|
|
164
|
-
#### Collecting All Schemas
|
|
165
|
-
|
|
166
|
-
```python
|
|
167
|
-
from jentic.apitools.openapi.traverse.json import traverse
|
|
168
|
-
|
|
169
|
-
def collect_schemas(openapi_doc):
|
|
170
|
-
"""Collect all schema objects from an OpenAPI document."""
|
|
171
|
-
schemas = []
|
|
172
|
-
|
|
173
|
-
for node in traverse(openapi_doc):
|
|
174
|
-
if node.segment == "schema" and isinstance(node.value, dict):
|
|
175
|
-
schemas.append({
|
|
176
|
-
"path": node.format_path(),
|
|
177
|
-
"schema": node.value
|
|
178
|
-
})
|
|
179
|
-
|
|
180
|
-
return schemas
|
|
181
|
-
```
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
#### Analyzing Document Structure
|
|
185
|
-
|
|
186
|
-
```python
|
|
187
|
-
def analyze_depth(data):
|
|
188
|
-
"""Analyze the depth distribution of a document."""
|
|
189
|
-
max_depth = 0
|
|
190
|
-
depth_counts = {}
|
|
191
|
-
|
|
192
|
-
for node in traverse(data):
|
|
193
|
-
depth = len(node.ancestors)
|
|
194
|
-
max_depth = max(max_depth, depth)
|
|
195
|
-
depth_counts[depth] = depth_counts.get(depth, 0) + 1
|
|
196
|
-
|
|
197
|
-
return {
|
|
198
|
-
"max_depth": max_depth,
|
|
199
|
-
"depth_distribution": depth_counts
|
|
200
|
-
}
|
|
201
|
-
```
|
|
202
|
-
|
|
203
|
-
### Testing
|
|
204
|
-
|
|
205
|
-
The package includes comprehensive test coverage for JSON traversal:
|
|
206
|
-
|
|
207
|
-
```bash
|
|
208
|
-
uv run --package jentic-openapi-traverse pytest packages/jentic-openapi-traverse/tests -v
|
|
209
|
-
```
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
jentic/apitools/openapi/traverse/json/__init__.py,sha256=1euUmpZviE_ECtpXYchpO8hZito2BINPjfSHMNqAU8k,326
|
|
2
|
-
jentic/apitools/openapi/traverse/json/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
3
|
-
jentic/apitools/openapi/traverse/json/traversal.py,sha256=1ouszn4S29X0iJaMxxb1neyClbWXqIKwFGhHROcpBSI,3524
|
|
4
|
-
jentic_openapi_traverse-1.0.0a22.dist-info/licenses/LICENSE,sha256=WNHhf_5RCaeuKWyq_K39vmp9F28LxKsB4SpomwSZ2L0,11357
|
|
5
|
-
jentic_openapi_traverse-1.0.0a22.dist-info/licenses/NOTICE,sha256=pAOGW-rGw9KNc2cuuLWZkfx0GSTV4TicbgBKZSLPMIs,168
|
|
6
|
-
jentic_openapi_traverse-1.0.0a22.dist-info/WHEEL,sha256=eh7sammvW2TypMMMGKgsM83HyA_3qQ5Lgg3ynoecH3M,79
|
|
7
|
-
jentic_openapi_traverse-1.0.0a22.dist-info/METADATA,sha256=5-XpBl4fy2yjMwJVJM6Qn0qwPzfA9wZHWuKjRkKosAY,5322
|
|
8
|
-
jentic_openapi_traverse-1.0.0a22.dist-info/RECORD,,
|
{jentic_openapi_traverse-1.0.0a22.dist-info → jentic_openapi_traverse-1.0.0a24.dist-info}/WHEEL
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|