jentic-openapi-parser 1.0.0a19__py3-none-any.whl → 1.0.0a20__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.
@@ -0,0 +1,56 @@
1
+ import logging
2
+ from collections.abc import Sequence
3
+ from typing import Literal
4
+
5
+ from ruamel.yaml import MappingNode, ScalarNode, SequenceNode
6
+
7
+ from jentic.apitools.openapi.common.uri import is_uri_like
8
+ from jentic.apitools.openapi.parser.backends.ruamel_roundtrip import RuamelRoundTripParserBackend
9
+ from jentic.apitools.openapi.parser.core.loader import load_uri
10
+
11
+
12
+ __all__ = [
13
+ "RuamelASTParserBackend",
14
+ # Re-export common YAML node types for convenience
15
+ "MappingNode",
16
+ "ScalarNode",
17
+ "SequenceNode",
18
+ ]
19
+
20
+
21
+ class RuamelASTParserBackend(RuamelRoundTripParserBackend):
22
+ def parse(self, document: str, *, logger: logging.Logger | None = None) -> MappingNode: # type: ignore[override]
23
+ logger = logger or logging.getLogger(__name__)
24
+ if is_uri_like(document):
25
+ return self._parse_uri(document, logger)
26
+ return self._parse_text(document, logger)
27
+
28
+ @staticmethod
29
+ def accepts() -> Sequence[Literal["uri", "text"]]:
30
+ """Return supported input formats.
31
+
32
+ Returns:
33
+ Sequence of supported document format identifiers:
34
+ - "uri": File path or URI pointing to OpenAPI Document
35
+ - "text": String (JSON/YAML) representation
36
+ """
37
+ return ["uri", "text"]
38
+
39
+ def _parse_uri(self, uri: str, logger: logging.Logger) -> MappingNode: # type: ignore[override]
40
+ logger.debug("Starting download of %s", uri)
41
+ return self._parse_text(load_uri(uri, 5, 10, logger), logger)
42
+
43
+ def _parse_text(self, text: str, logger: logging.Logger) -> MappingNode: # type: ignore[override]
44
+ if not isinstance(text, (bytes, str)):
45
+ raise TypeError(f"Unsupported document type: {type(text)!r}")
46
+
47
+ if isinstance(text, bytes):
48
+ text = text.decode()
49
+
50
+ node: MappingNode = self.yaml.compose(text)
51
+ logger.debug("YAML document successfully parsed")
52
+
53
+ if not isinstance(node, MappingNode):
54
+ raise TypeError(f"Parsed YAML document is not a mapping: {type(node)!r}")
55
+
56
+ return node
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: jentic-openapi-parser
3
- Version: 1.0.0a19
3
+ Version: 1.0.0a20
4
4
  Summary: Jentic OpenAPI Parser
5
5
  Author: Jentic
6
6
  Author-email: Jentic <hello@jentic.com>
@@ -8,7 +8,7 @@ License-Expression: Apache-2.0
8
8
  License-File: LICENSE
9
9
  License-File: NOTICE
10
10
  Requires-Dist: attrs~=25.4.0
11
- Requires-Dist: jentic-openapi-common~=1.0.0a19
11
+ Requires-Dist: jentic-openapi-common~=1.0.0a20
12
12
  Requires-Dist: pyyaml~=6.0.3
13
13
  Requires-Dist: requests~=2.32.5
14
14
  Requires-Dist: ruamel-yaml~=0.18.15
@@ -24,7 +24,7 @@ A Python library for parsing OpenAPI documents using pluggable parser backends.
24
24
 
25
25
  - **Pluggable Backend Architecture**: Support for multiple parsing strategies via entry points
26
26
  - **Multiple Input Formats**: Parse OpenAPI documents from file URIs or text strings (JSON/YAML)
27
- - **Multiple Parser Backends**: Choose from PyYAML, ruamel.yaml, or ruamel.yaml roundtrip modes
27
+ - **Multiple Parser Backends**: Choose from PyYAML, ruamel.yaml (safe/roundtrip/AST modes)
28
28
  - **Enhanced JSON Serialization**: Built-in support for datetime, UUID, Path, Decimal, Enum, and attrs classes
29
29
  - **Type Safety**: Full type hints with overloaded methods for precise return types
30
30
  - **Extensible Design**: Easy integration of third-party parser backends
@@ -53,12 +53,12 @@ doc = parser.parse("file:///path/to/openapi.yaml")
53
53
  print(doc["info"]["title"])
54
54
 
55
55
  # Parse from JSON string
56
- json_doc = '{"openapi":"3.1.0","info":{"title":"My API","version":"1.0.0"}}'
56
+ json_doc = '{"openapi":"3.1.2","info":{"title":"My API","version":"1.0.0"}}'
57
57
  doc = parser.parse(json_doc)
58
58
 
59
59
  # Parse from YAML string
60
60
  yaml_doc = """
61
- openapi: 3.1.0
61
+ openapi: 3.1.2
62
62
  info:
63
63
  title: My API
64
64
  version: 1.0.0
@@ -95,6 +95,14 @@ parser = OpenAPIParser("ruamel-roundtrip")
95
95
  doc = parser.parse("file:///path/to/openapi.yaml", return_type=CommentedMap)
96
96
  # Access line/column information
97
97
  print(doc.lc.line, doc.lc.col)
98
+
99
+ # Use ruamel.yaml AST mode (returns YAML nodes with source tracking)
100
+ from jentic.apitools.openapi.parser.backends.ruamel_ast import MappingNode
101
+ parser = OpenAPIParser("ruamel-ast")
102
+ node = parser.parse("file:///path/to/openapi.yaml", return_type=MappingNode)
103
+ # Access precise line/column for any node
104
+ for key_node, value_node in node.value:
105
+ print(f"{key_node.value} at line {key_node.start_mark.line}")
98
106
  ```
99
107
 
100
108
  ## Configuration Options
@@ -171,7 +179,7 @@ class OpenAPIParser:
171
179
 
172
180
  **Parameters:**
173
181
  - `backend`: Parser backend to use. Can be:
174
- - `str`: Name of a backend registered via entry points (e.g., "pyyaml", "ruamel-safe", "ruamel-roundtrip")
182
+ - `str`: Name of a backend registered via entry points (e.g., "pyyaml", "ruamel-safe", "ruamel-roundtrip", "ruamel-ast")
175
183
  - `BaseParserBackend`: Instance of a parser backend
176
184
  - `Type[BaseParserBackend]`: Class of a parser backend (will be instantiated)
177
185
  - Defaults to `"pyyaml"` if `None`
@@ -282,6 +290,42 @@ doc = parser.parse(content, return_type=CommentedMap)
282
290
  print(f"Line: {doc.lc.line}, Column: {doc.lc.col}")
283
291
  ```
284
292
 
293
+ ### ruamel-ast
294
+ ruamel.yaml AST mode that returns YAML nodes with complete source location tracking. Ideal for building low-level data models with precise error reporting.
295
+
296
+ **Accepts:** `text` (JSON/YAML strings), `uri` (file paths/URLs)
297
+
298
+ **Returns:** `yaml.MappingNode` (YAML AST) instead of dictionaries
299
+
300
+ ```python
301
+ from jentic.apitools.openapi.parser.backends.ruamel_ast import MappingNode
302
+
303
+ parser = OpenAPIParser("ruamel-ast")
304
+ node = parser.parse(content, return_type=MappingNode)
305
+
306
+ # Access YAML nodes with source information
307
+ assert isinstance(node, MappingNode)
308
+
309
+ # Get precise line/column information for any node
310
+ for key_node, value_node in node.value:
311
+ print(f"Key: {key_node.value}")
312
+ print(f" Line: {key_node.start_mark.line}, Column: {key_node.start_mark.column}")
313
+
314
+ # Perfect for building low-level datamodels with source tracking
315
+ # Works seamlessly with jentic-openapi-datamodels
316
+ ```
317
+
318
+ **Note:** You can also import directly from `ruamel.yaml` if preferred:
319
+ ```python
320
+ from ruamel.yaml import MappingNode # Alternative import
321
+ ```
322
+
323
+ **Use Cases:**
324
+ - Building low-level data models that preserve source locations
325
+ - Implementing precise error reporting with line/column numbers
326
+ - AST-based transformations and analysis
327
+ - Integration with validation tools that need exact source positions
328
+
285
329
  ## Testing
286
330
 
287
331
  Run the test suite:
@@ -1,6 +1,7 @@
1
1
  jentic/apitools/openapi/parser/backends/base.py,sha256=0lh1z_Y0J-76PUayajiC1kD36xyl71ekFBBEbZlEM5g,825
2
2
  jentic/apitools/openapi/parser/backends/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
3
  jentic/apitools/openapi/parser/backends/pyyaml.py,sha256=jwWwYtJNWhvfzRKMC1Zcu_HeanuPs_r-1WCdKi4skSU,1720
4
+ jentic/apitools/openapi/parser/backends/ruamel_ast.py,sha256=tloUVBGgIvhByDw6kg3vLyagE1WXsbIPnlV5dn51irU,2043
4
5
  jentic/apitools/openapi/parser/backends/ruamel_roundtrip.py,sha256=03DJgkbf_NOBON0PnokOAG1HBATaLkHxdZtT0M9M66U,285
5
6
  jentic/apitools/openapi/parser/backends/ruamel_safe.py,sha256=0s8R9VU9kTnzUoo6ash8x7JOAyl7Z8-VNi-hvcskPnY,1954
6
7
  jentic/apitools/openapi/parser/core/__init__.py,sha256=FChrSb22a7m9LOku4KG0_Vsm4ConyEAlrFW3qLXjMAY,578
@@ -9,9 +10,9 @@ jentic/apitools/openapi/parser/core/loader.py,sha256=Q57UiWiJACeuxMdroHAAEcoU-lw
9
10
  jentic/apitools/openapi/parser/core/openapi_parser.py,sha256=GCFEZZ6g4CrqJauz7AilEAxT-v31D8TP6zsIms9jLl8,7551
10
11
  jentic/apitools/openapi/parser/core/py.typed,sha256=uEf7mrkecd7wYBi4Jxa95cHb65ZSz_tMK6UDi55KymA,33
11
12
  jentic/apitools/openapi/parser/core/serialization.py,sha256=qr9CBgZzb9GKRPTwOb_MmS0-GdHpVZLmXiHiX1n1cIM,2810
12
- jentic_openapi_parser-1.0.0a19.dist-info/licenses/LICENSE,sha256=WNHhf_5RCaeuKWyq_K39vmp9F28LxKsB4SpomwSZ2L0,11357
13
- jentic_openapi_parser-1.0.0a19.dist-info/licenses/NOTICE,sha256=pAOGW-rGw9KNc2cuuLWZkfx0GSTV4TicbgBKZSLPMIs,168
14
- jentic_openapi_parser-1.0.0a19.dist-info/WHEEL,sha256=eh7sammvW2TypMMMGKgsM83HyA_3qQ5Lgg3ynoecH3M,79
15
- jentic_openapi_parser-1.0.0a19.dist-info/entry_points.txt,sha256=60Bv8jx6Jhx_ccq1jt8DBsAv94nmri8UdjLyENAksXg,314
16
- jentic_openapi_parser-1.0.0a19.dist-info/METADATA,sha256=Wjf-KrAYBwf2Q_Td09b9X75C6ozjdXG_1h230Z6rXM8,8038
17
- jentic_openapi_parser-1.0.0a19.dist-info/RECORD,,
13
+ jentic_openapi_parser-1.0.0a20.dist-info/licenses/LICENSE,sha256=WNHhf_5RCaeuKWyq_K39vmp9F28LxKsB4SpomwSZ2L0,11357
14
+ jentic_openapi_parser-1.0.0a20.dist-info/licenses/NOTICE,sha256=pAOGW-rGw9KNc2cuuLWZkfx0GSTV4TicbgBKZSLPMIs,168
15
+ jentic_openapi_parser-1.0.0a20.dist-info/WHEEL,sha256=eh7sammvW2TypMMMGKgsM83HyA_3qQ5Lgg3ynoecH3M,79
16
+ jentic_openapi_parser-1.0.0a20.dist-info/entry_points.txt,sha256=YwgHz_vdkRaY3DQeMjiEBH_b2mBXwTfQ0H7CvdAZwpY,401
17
+ jentic_openapi_parser-1.0.0a20.dist-info/METADATA,sha256=F61QXve_1a6ZtFePGyb2Le3L0LuGWIrUMQIVXMcRaDM,9754
18
+ jentic_openapi_parser-1.0.0a20.dist-info/RECORD,,
@@ -1,5 +1,6 @@
1
1
  [jentic.apitools.openapi.parser.backends]
2
2
  pyyaml = jentic.apitools.openapi.parser.backends.pyyaml:PyYAMLParserBackend
3
+ ruamel-ast = jentic.apitools.openapi.parser.backends.ruamel_ast:RuamelASTParserBackend
3
4
  ruamel-roundtrip = jentic.apitools.openapi.parser.backends.ruamel_roundtrip:RuamelRoundTripParserBackend
4
5
  ruamel-safe = jentic.apitools.openapi.parser.backends.ruamel_safe:RuamelSafeParserBackend
5
6