jentic-openapi-datamodels 1.0.0a20__tar.gz → 1.0.0a22__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.
Files changed (75) hide show
  1. {jentic_openapi_datamodels-1.0.0a20 → jentic_openapi_datamodels-1.0.0a22}/PKG-INFO +59 -4
  2. {jentic_openapi_datamodels-1.0.0a20 → jentic_openapi_datamodels-1.0.0a22}/README.md +58 -3
  3. {jentic_openapi_datamodels-1.0.0a20 → jentic_openapi_datamodels-1.0.0a22}/pyproject.toml +1 -1
  4. {jentic_openapi_datamodels-1.0.0a20 → jentic_openapi_datamodels-1.0.0a22}/src/jentic/apitools/openapi/datamodels/low/fields.py +18 -6
  5. {jentic_openapi_datamodels-1.0.0a20 → jentic_openapi_datamodels-1.0.0a22}/src/jentic/apitools/openapi/datamodels/low/v30/callback.py +4 -3
  6. {jentic_openapi_datamodels-1.0.0a20 → jentic_openapi_datamodels-1.0.0a22}/src/jentic/apitools/openapi/datamodels/low/v30/paths.py +2 -1
  7. {jentic_openapi_datamodels-1.0.0a20 → jentic_openapi_datamodels-1.0.0a22}/src/jentic/apitools/openapi/datamodels/low/v30/responses.py +2 -2
  8. {jentic_openapi_datamodels-1.0.0a20 → jentic_openapi_datamodels-1.0.0a22}/src/jentic/apitools/openapi/datamodels/low/v30/security_requirement.py +7 -9
  9. {jentic_openapi_datamodels-1.0.0a20 → jentic_openapi_datamodels-1.0.0a22}/src/jentic/apitools/openapi/datamodels/low/v31/callback.py +4 -3
  10. {jentic_openapi_datamodels-1.0.0a20 → jentic_openapi_datamodels-1.0.0a22}/src/jentic/apitools/openapi/datamodels/low/v31/paths.py +2 -1
  11. {jentic_openapi_datamodels-1.0.0a20 → jentic_openapi_datamodels-1.0.0a22}/src/jentic/apitools/openapi/datamodels/low/v31/responses.py +2 -2
  12. {jentic_openapi_datamodels-1.0.0a20 → jentic_openapi_datamodels-1.0.0a22}/src/jentic/apitools/openapi/datamodels/low/v31/security_requirement.py +7 -9
  13. {jentic_openapi_datamodels-1.0.0a20 → jentic_openapi_datamodels-1.0.0a22}/LICENSE +0 -0
  14. {jentic_openapi_datamodels-1.0.0a20 → jentic_openapi_datamodels-1.0.0a22}/NOTICE +0 -0
  15. {jentic_openapi_datamodels-1.0.0a20 → jentic_openapi_datamodels-1.0.0a22}/src/jentic/apitools/openapi/datamodels/low/__init__.py +0 -0
  16. {jentic_openapi_datamodels-1.0.0a20 → jentic_openapi_datamodels-1.0.0a22}/src/jentic/apitools/openapi/datamodels/low/context.py +0 -0
  17. {jentic_openapi_datamodels-1.0.0a20 → jentic_openapi_datamodels-1.0.0a22}/src/jentic/apitools/openapi/datamodels/low/extractors.py +0 -0
  18. {jentic_openapi_datamodels-1.0.0a20 → jentic_openapi_datamodels-1.0.0a22}/src/jentic/apitools/openapi/datamodels/low/py.typed +0 -0
  19. {jentic_openapi_datamodels-1.0.0a20 → jentic_openapi_datamodels-1.0.0a22}/src/jentic/apitools/openapi/datamodels/low/sources.py +0 -0
  20. {jentic_openapi_datamodels-1.0.0a20 → jentic_openapi_datamodels-1.0.0a22}/src/jentic/apitools/openapi/datamodels/low/v30/__init__.py +0 -0
  21. {jentic_openapi_datamodels-1.0.0a20 → jentic_openapi_datamodels-1.0.0a22}/src/jentic/apitools/openapi/datamodels/low/v30/builders/__init__.py +0 -0
  22. {jentic_openapi_datamodels-1.0.0a20 → jentic_openapi_datamodels-1.0.0a22}/src/jentic/apitools/openapi/datamodels/low/v30/components.py +0 -0
  23. {jentic_openapi_datamodels-1.0.0a20 → jentic_openapi_datamodels-1.0.0a22}/src/jentic/apitools/openapi/datamodels/low/v30/contact.py +0 -0
  24. {jentic_openapi_datamodels-1.0.0a20 → jentic_openapi_datamodels-1.0.0a22}/src/jentic/apitools/openapi/datamodels/low/v30/discriminator.py +0 -0
  25. {jentic_openapi_datamodels-1.0.0a20 → jentic_openapi_datamodels-1.0.0a22}/src/jentic/apitools/openapi/datamodels/low/v30/encoding.py +0 -0
  26. {jentic_openapi_datamodels-1.0.0a20 → jentic_openapi_datamodels-1.0.0a22}/src/jentic/apitools/openapi/datamodels/low/v30/example.py +0 -0
  27. {jentic_openapi_datamodels-1.0.0a20 → jentic_openapi_datamodels-1.0.0a22}/src/jentic/apitools/openapi/datamodels/low/v30/external_documentation.py +0 -0
  28. {jentic_openapi_datamodels-1.0.0a20 → jentic_openapi_datamodels-1.0.0a22}/src/jentic/apitools/openapi/datamodels/low/v30/header.py +0 -0
  29. {jentic_openapi_datamodels-1.0.0a20 → jentic_openapi_datamodels-1.0.0a22}/src/jentic/apitools/openapi/datamodels/low/v30/info.py +0 -0
  30. {jentic_openapi_datamodels-1.0.0a20 → jentic_openapi_datamodels-1.0.0a22}/src/jentic/apitools/openapi/datamodels/low/v30/license.py +0 -0
  31. {jentic_openapi_datamodels-1.0.0a20 → jentic_openapi_datamodels-1.0.0a22}/src/jentic/apitools/openapi/datamodels/low/v30/link.py +0 -0
  32. {jentic_openapi_datamodels-1.0.0a20 → jentic_openapi_datamodels-1.0.0a22}/src/jentic/apitools/openapi/datamodels/low/v30/media_type.py +0 -0
  33. {jentic_openapi_datamodels-1.0.0a20 → jentic_openapi_datamodels-1.0.0a22}/src/jentic/apitools/openapi/datamodels/low/v30/oauth_flow.py +0 -0
  34. {jentic_openapi_datamodels-1.0.0a20 → jentic_openapi_datamodels-1.0.0a22}/src/jentic/apitools/openapi/datamodels/low/v30/oauth_flows.py +0 -0
  35. {jentic_openapi_datamodels-1.0.0a20 → jentic_openapi_datamodels-1.0.0a22}/src/jentic/apitools/openapi/datamodels/low/v30/openapi.py +0 -0
  36. {jentic_openapi_datamodels-1.0.0a20 → jentic_openapi_datamodels-1.0.0a22}/src/jentic/apitools/openapi/datamodels/low/v30/operation.py +0 -0
  37. {jentic_openapi_datamodels-1.0.0a20 → jentic_openapi_datamodels-1.0.0a22}/src/jentic/apitools/openapi/datamodels/low/v30/parameter.py +0 -0
  38. {jentic_openapi_datamodels-1.0.0a20 → jentic_openapi_datamodels-1.0.0a22}/src/jentic/apitools/openapi/datamodels/low/v30/path_item.py +0 -0
  39. {jentic_openapi_datamodels-1.0.0a20 → jentic_openapi_datamodels-1.0.0a22}/src/jentic/apitools/openapi/datamodels/low/v30/reference.py +0 -0
  40. {jentic_openapi_datamodels-1.0.0a20 → jentic_openapi_datamodels-1.0.0a22}/src/jentic/apitools/openapi/datamodels/low/v30/request_body.py +0 -0
  41. {jentic_openapi_datamodels-1.0.0a20 → jentic_openapi_datamodels-1.0.0a22}/src/jentic/apitools/openapi/datamodels/low/v30/response.py +0 -0
  42. {jentic_openapi_datamodels-1.0.0a20 → jentic_openapi_datamodels-1.0.0a22}/src/jentic/apitools/openapi/datamodels/low/v30/schema.py +0 -0
  43. {jentic_openapi_datamodels-1.0.0a20 → jentic_openapi_datamodels-1.0.0a22}/src/jentic/apitools/openapi/datamodels/low/v30/security_scheme.py +0 -0
  44. {jentic_openapi_datamodels-1.0.0a20 → jentic_openapi_datamodels-1.0.0a22}/src/jentic/apitools/openapi/datamodels/low/v30/server.py +0 -0
  45. {jentic_openapi_datamodels-1.0.0a20 → jentic_openapi_datamodels-1.0.0a22}/src/jentic/apitools/openapi/datamodels/low/v30/server_variable.py +0 -0
  46. {jentic_openapi_datamodels-1.0.0a20 → jentic_openapi_datamodels-1.0.0a22}/src/jentic/apitools/openapi/datamodels/low/v30/tag.py +0 -0
  47. {jentic_openapi_datamodels-1.0.0a20 → jentic_openapi_datamodels-1.0.0a22}/src/jentic/apitools/openapi/datamodels/low/v30/xml.py +0 -0
  48. {jentic_openapi_datamodels-1.0.0a20 → jentic_openapi_datamodels-1.0.0a22}/src/jentic/apitools/openapi/datamodels/low/v31/__init__.py +0 -0
  49. {jentic_openapi_datamodels-1.0.0a20 → jentic_openapi_datamodels-1.0.0a22}/src/jentic/apitools/openapi/datamodels/low/v31/builders/__init__.py +0 -0
  50. {jentic_openapi_datamodels-1.0.0a20 → jentic_openapi_datamodels-1.0.0a22}/src/jentic/apitools/openapi/datamodels/low/v31/components.py +0 -0
  51. {jentic_openapi_datamodels-1.0.0a20 → jentic_openapi_datamodels-1.0.0a22}/src/jentic/apitools/openapi/datamodels/low/v31/contact.py +0 -0
  52. {jentic_openapi_datamodels-1.0.0a20 → jentic_openapi_datamodels-1.0.0a22}/src/jentic/apitools/openapi/datamodels/low/v31/discriminator.py +0 -0
  53. {jentic_openapi_datamodels-1.0.0a20 → jentic_openapi_datamodels-1.0.0a22}/src/jentic/apitools/openapi/datamodels/low/v31/encoding.py +0 -0
  54. {jentic_openapi_datamodels-1.0.0a20 → jentic_openapi_datamodels-1.0.0a22}/src/jentic/apitools/openapi/datamodels/low/v31/example.py +0 -0
  55. {jentic_openapi_datamodels-1.0.0a20 → jentic_openapi_datamodels-1.0.0a22}/src/jentic/apitools/openapi/datamodels/low/v31/external_documentation.py +0 -0
  56. {jentic_openapi_datamodels-1.0.0a20 → jentic_openapi_datamodels-1.0.0a22}/src/jentic/apitools/openapi/datamodels/low/v31/header.py +0 -0
  57. {jentic_openapi_datamodels-1.0.0a20 → jentic_openapi_datamodels-1.0.0a22}/src/jentic/apitools/openapi/datamodels/low/v31/info.py +0 -0
  58. {jentic_openapi_datamodels-1.0.0a20 → jentic_openapi_datamodels-1.0.0a22}/src/jentic/apitools/openapi/datamodels/low/v31/license.py +0 -0
  59. {jentic_openapi_datamodels-1.0.0a20 → jentic_openapi_datamodels-1.0.0a22}/src/jentic/apitools/openapi/datamodels/low/v31/link.py +0 -0
  60. {jentic_openapi_datamodels-1.0.0a20 → jentic_openapi_datamodels-1.0.0a22}/src/jentic/apitools/openapi/datamodels/low/v31/media_type.py +0 -0
  61. {jentic_openapi_datamodels-1.0.0a20 → jentic_openapi_datamodels-1.0.0a22}/src/jentic/apitools/openapi/datamodels/low/v31/oauth_flow.py +0 -0
  62. {jentic_openapi_datamodels-1.0.0a20 → jentic_openapi_datamodels-1.0.0a22}/src/jentic/apitools/openapi/datamodels/low/v31/oauth_flows.py +0 -0
  63. {jentic_openapi_datamodels-1.0.0a20 → jentic_openapi_datamodels-1.0.0a22}/src/jentic/apitools/openapi/datamodels/low/v31/openapi.py +0 -0
  64. {jentic_openapi_datamodels-1.0.0a20 → jentic_openapi_datamodels-1.0.0a22}/src/jentic/apitools/openapi/datamodels/low/v31/operation.py +0 -0
  65. {jentic_openapi_datamodels-1.0.0a20 → jentic_openapi_datamodels-1.0.0a22}/src/jentic/apitools/openapi/datamodels/low/v31/parameter.py +0 -0
  66. {jentic_openapi_datamodels-1.0.0a20 → jentic_openapi_datamodels-1.0.0a22}/src/jentic/apitools/openapi/datamodels/low/v31/path_item.py +0 -0
  67. {jentic_openapi_datamodels-1.0.0a20 → jentic_openapi_datamodels-1.0.0a22}/src/jentic/apitools/openapi/datamodels/low/v31/reference.py +0 -0
  68. {jentic_openapi_datamodels-1.0.0a20 → jentic_openapi_datamodels-1.0.0a22}/src/jentic/apitools/openapi/datamodels/low/v31/request_body.py +0 -0
  69. {jentic_openapi_datamodels-1.0.0a20 → jentic_openapi_datamodels-1.0.0a22}/src/jentic/apitools/openapi/datamodels/low/v31/response.py +0 -0
  70. {jentic_openapi_datamodels-1.0.0a20 → jentic_openapi_datamodels-1.0.0a22}/src/jentic/apitools/openapi/datamodels/low/v31/schema.py +0 -0
  71. {jentic_openapi_datamodels-1.0.0a20 → jentic_openapi_datamodels-1.0.0a22}/src/jentic/apitools/openapi/datamodels/low/v31/security_scheme.py +0 -0
  72. {jentic_openapi_datamodels-1.0.0a20 → jentic_openapi_datamodels-1.0.0a22}/src/jentic/apitools/openapi/datamodels/low/v31/server.py +0 -0
  73. {jentic_openapi_datamodels-1.0.0a20 → jentic_openapi_datamodels-1.0.0a22}/src/jentic/apitools/openapi/datamodels/low/v31/server_variable.py +0 -0
  74. {jentic_openapi_datamodels-1.0.0a20 → jentic_openapi_datamodels-1.0.0a22}/src/jentic/apitools/openapi/datamodels/low/v31/tag.py +0 -0
  75. {jentic_openapi_datamodels-1.0.0a20 → jentic_openapi_datamodels-1.0.0a22}/src/jentic/apitools/openapi/datamodels/low/v31/xml.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: jentic-openapi-datamodels
3
- Version: 1.0.0a20
3
+ Version: 1.0.0a22
4
4
  Summary: Jentic OpenAPI Data Models
5
5
  Author: Jentic
6
6
  Author-email: Jentic <hello@jentic.com>
@@ -61,9 +61,64 @@ pip install jentic-openapi-datamodels
61
61
 
62
62
  ## Quick Start
63
63
 
64
- ### Parsing OpenAPI 3.0 Documents
64
+ ### Parsing with the `datamodel-low` Parser Backend (Recommended)
65
65
 
66
- The main use case is parsing complete OpenAPI Documents:
66
+ The easiest way to parse OpenAPI documents into datamodels is using the `datamodel-low` backend from `jentic-openapi-parser`. This backend automatically detects the OpenAPI version and returns the appropriate typed datamodel:
67
+
68
+ ```python
69
+ from jentic.apitools.openapi.parser.core import OpenAPIParser
70
+ from jentic.apitools.openapi.parser.backends.datamodel_low import DataModelLow
71
+ from jentic.apitools.openapi.datamodels.low.v30.openapi import OpenAPI30
72
+ from jentic.apitools.openapi.datamodels.low.v31.openapi import OpenAPI31
73
+
74
+ # Create parser with datamodel-low backend
75
+ parser = OpenAPIParser("datamodel-low")
76
+
77
+ # Parse OpenAPI 3.0 document - automatically returns OpenAPI30
78
+ doc = parser.parse("""
79
+ openapi: 3.0.4
80
+ info:
81
+ title: Pet Store API
82
+ version: 1.0.0
83
+ paths:
84
+ /pets:
85
+ get:
86
+ summary: List all pets
87
+ responses:
88
+ '200':
89
+ description: A list of pets
90
+ """, return_type=DataModelLow)
91
+
92
+ assert isinstance(doc, OpenAPI30)
93
+ print(doc.openapi.value) # "3.0.4"
94
+ print(doc.info.value.title.value) # "Pet Store API"
95
+
96
+ # Parse OpenAPI 3.1 document - automatically returns OpenAPI31
97
+ doc = parser.parse("""
98
+ openapi: 3.1.2
99
+ info:
100
+ title: Pet Store API
101
+ version: 1.0.0
102
+ paths: {}
103
+ """, return_type=DataModelLow)
104
+
105
+ assert isinstance(doc, OpenAPI31)
106
+ print(doc.openapi.value) # "3.1.2"
107
+ ```
108
+
109
+ **Benefits of `datamodel-low` backend:**
110
+ - Automatic version detection (no manual version checking)
111
+ - Returns strongly-typed `OpenAPI30` or `OpenAPI31` objects
112
+ - Complete source tracking preserved
113
+ - Single-step parsing (no need to manually call `build()`)
114
+
115
+ ### Manual Parsing with Builder Functions
116
+
117
+ For advanced use cases or custom workflows, you can manually parse and build datamodels:
118
+
119
+ #### Parsing OpenAPI 3.0 Documents
120
+
121
+ The manual approach uses the `ruamel-ast` backend followed by calling the builder function:
67
122
 
68
123
  ```python
69
124
  from jentic.apitools.openapi.parser.core import OpenAPIParser
@@ -102,7 +157,7 @@ for path_key, path_item in openapi_doc.paths.value.path_items.items():
102
157
  print(f" Summary: {operation.summary.value}") # "List all pets"
103
158
  ```
104
159
 
105
- ### Parsing OpenAPI 3.1 Documents with JSON Schema 2020-12
160
+ #### Parsing OpenAPI 3.1 Documents with JSON Schema 2020-12
106
161
 
107
162
  OpenAPI 3.1 fully supports JSON Schema 2020-12, including advanced features like boolean schemas, conditional validation and vocabulary declarations:
108
163
 
@@ -47,9 +47,64 @@ pip install jentic-openapi-datamodels
47
47
 
48
48
  ## Quick Start
49
49
 
50
- ### Parsing OpenAPI 3.0 Documents
50
+ ### Parsing with the `datamodel-low` Parser Backend (Recommended)
51
51
 
52
- The main use case is parsing complete OpenAPI Documents:
52
+ The easiest way to parse OpenAPI documents into datamodels is using the `datamodel-low` backend from `jentic-openapi-parser`. This backend automatically detects the OpenAPI version and returns the appropriate typed datamodel:
53
+
54
+ ```python
55
+ from jentic.apitools.openapi.parser.core import OpenAPIParser
56
+ from jentic.apitools.openapi.parser.backends.datamodel_low import DataModelLow
57
+ from jentic.apitools.openapi.datamodels.low.v30.openapi import OpenAPI30
58
+ from jentic.apitools.openapi.datamodels.low.v31.openapi import OpenAPI31
59
+
60
+ # Create parser with datamodel-low backend
61
+ parser = OpenAPIParser("datamodel-low")
62
+
63
+ # Parse OpenAPI 3.0 document - automatically returns OpenAPI30
64
+ doc = parser.parse("""
65
+ openapi: 3.0.4
66
+ info:
67
+ title: Pet Store API
68
+ version: 1.0.0
69
+ paths:
70
+ /pets:
71
+ get:
72
+ summary: List all pets
73
+ responses:
74
+ '200':
75
+ description: A list of pets
76
+ """, return_type=DataModelLow)
77
+
78
+ assert isinstance(doc, OpenAPI30)
79
+ print(doc.openapi.value) # "3.0.4"
80
+ print(doc.info.value.title.value) # "Pet Store API"
81
+
82
+ # Parse OpenAPI 3.1 document - automatically returns OpenAPI31
83
+ doc = parser.parse("""
84
+ openapi: 3.1.2
85
+ info:
86
+ title: Pet Store API
87
+ version: 1.0.0
88
+ paths: {}
89
+ """, return_type=DataModelLow)
90
+
91
+ assert isinstance(doc, OpenAPI31)
92
+ print(doc.openapi.value) # "3.1.2"
93
+ ```
94
+
95
+ **Benefits of `datamodel-low` backend:**
96
+ - Automatic version detection (no manual version checking)
97
+ - Returns strongly-typed `OpenAPI30` or `OpenAPI31` objects
98
+ - Complete source tracking preserved
99
+ - Single-step parsing (no need to manually call `build()`)
100
+
101
+ ### Manual Parsing with Builder Functions
102
+
103
+ For advanced use cases or custom workflows, you can manually parse and build datamodels:
104
+
105
+ #### Parsing OpenAPI 3.0 Documents
106
+
107
+ The manual approach uses the `ruamel-ast` backend followed by calling the builder function:
53
108
 
54
109
  ```python
55
110
  from jentic.apitools.openapi.parser.core import OpenAPIParser
@@ -88,7 +143,7 @@ for path_key, path_item in openapi_doc.paths.value.path_items.items():
88
143
  print(f" Summary: {operation.summary.value}") # "List all pets"
89
144
  ```
90
145
 
91
- ### Parsing OpenAPI 3.1 Documents with JSON Schema 2020-12
146
+ #### Parsing OpenAPI 3.1 Documents with JSON Schema 2020-12
92
147
 
93
148
  OpenAPI 3.1 fully supports JSON Schema 2020-12, including advanced features like boolean schemas, conditional validation and vocabulary declarations:
94
149
 
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "jentic-openapi-datamodels"
3
- version = "1.0.0-alpha.20"
3
+ version = "1.0.0-alpha.22"
4
4
  description = "Jentic OpenAPI Data Models"
5
5
  readme = "README.md"
6
6
  authors = [{ name = "Jentic", email = "hello@jentic.com" }]
@@ -1,15 +1,16 @@
1
- from dataclasses import field, fields
1
+ from dataclasses import MISSING, field, fields
2
+ from typing import Any
2
3
 
3
4
 
4
5
  __all__ = ["fixed_field", "fixed_fields", "patterned_field", "patterned_fields"]
5
6
 
6
7
 
7
- def fixed_field(default=None, metadata=None):
8
+ def fixed_field(*, default: Any = None, metadata: dict[str, Any] | None = None) -> Any:
8
9
  """Mark a field as a fixed OpenAPI specification field."""
9
10
  return field(default=default, metadata={**(metadata or {}), "fixed_field": True})
10
11
 
11
12
 
12
- def fixed_fields(dataclass_type):
13
+ def fixed_fields(dataclass_type: type) -> dict[str, Any]:
13
14
  """
14
15
  Get all fixed specification fields from a dataclass.
15
16
 
@@ -22,17 +23,28 @@ def fixed_fields(dataclass_type):
22
23
  return {f.name: f for f in fields(dataclass_type) if f.metadata.get("fixed_field")}
23
24
 
24
25
 
25
- def patterned_field(default=None, metadata=None):
26
+ def patterned_field(
27
+ *, default=MISSING, default_factory=MISSING, metadata: dict[str, Any] | None = None
28
+ ) -> Any:
26
29
  """
27
30
  Mark a field as containing OpenAPI patterned fields.
28
31
 
29
32
  Patterned fields have dynamic names that follow a specific pattern (e.g., security scheme names,
30
33
  path patterns, callback expressions, HTTP status codes).
34
+
35
+ Args:
36
+ default: Default value for the field
37
+ default_factory: Callable that returns default value
38
+ metadata: Additional metadata for the field
31
39
  """
32
- return field(default=default, metadata={**(metadata or {}), "patterned_field": True})
40
+ merged_metadata = {**(metadata or {}), "patterned_field": True}
41
+ if default_factory is not MISSING:
42
+ return field(default_factory=default_factory, metadata=merged_metadata)
43
+ else:
44
+ return field(default=default, metadata=merged_metadata)
33
45
 
34
46
 
35
- def patterned_fields(dataclass_type):
47
+ def patterned_fields(dataclass_type: type) -> dict[str, Any]:
36
48
  """
37
49
  Get all patterned fields from a dataclass.
38
50
 
@@ -4,6 +4,7 @@ from ruamel import yaml
4
4
 
5
5
  from ..context import Context
6
6
  from ..extractors import extract_extension_fields
7
+ from ..fields import patterned_field
7
8
  from ..sources import KeySource, ValueSource, YAMLInvalidValue, YAMLValue
8
9
  from .path_item import PathItem
9
10
  from .path_item import build as build_path_item
@@ -33,7 +34,7 @@ class Callback:
33
34
  """
34
35
 
35
36
  root_node: yaml.Node
36
- path_items: dict[KeySource[str], PathItem] = field(default_factory=dict)
37
+ path_items: dict[KeySource[str], PathItem] = patterned_field(default_factory=dict)
37
38
  extensions: dict[KeySource[str], ValueSource[YAMLValue]] = field(default_factory=dict)
38
39
 
39
40
 
@@ -86,7 +87,7 @@ def build(
86
87
  extension_properties = {k.value for k in extensions.keys()}
87
88
 
88
89
  # Process each field to determine if it's an expression (not an extension)
89
- path_items: dict[KeySource[str], PathItem | ValueSource[YAMLInvalidValue]] = {}
90
+ path_items = {}
90
91
 
91
92
  for key_node, value_node in root.value:
92
93
  expression = context.yaml_constructor.construct_yaml_str(key_node)
@@ -99,7 +100,7 @@ def build(
99
100
  # Create and return the Callback object with collected data
100
101
  return Callback(
101
102
  root_node=root,
102
- path_items=path_items, # type: ignore[arg-type]
103
+ path_items=path_items,
103
104
  extensions=extensions,
104
105
  )
105
106
 
@@ -4,6 +4,7 @@ from ruamel import yaml
4
4
 
5
5
  from ..context import Context
6
6
  from ..extractors import extract_extension_fields
7
+ from ..fields import patterned_field
7
8
  from ..sources import KeySource, ValueSource, YAMLInvalidValue, YAMLValue
8
9
  from .path_item import PathItem
9
10
  from .path_item import build as build_path_item
@@ -33,7 +34,7 @@ class Paths:
33
34
  """
34
35
 
35
36
  root_node: yaml.Node
36
- paths: dict[KeySource[str], PathItem] = field(default_factory=dict)
37
+ paths: dict[KeySource[str], PathItem] = patterned_field(default_factory=dict)
37
38
  extensions: dict[KeySource[str], ValueSource[YAMLValue]] = field(default_factory=dict)
38
39
 
39
40
 
@@ -6,7 +6,7 @@ from ruamel import yaml
6
6
 
7
7
  from ..context import Context
8
8
  from ..extractors import extract_extension_fields
9
- from ..fields import fixed_field
9
+ from ..fields import fixed_field, patterned_field
10
10
  from ..sources import FieldSource, KeySource, ValueSource, YAMLInvalidValue, YAMLValue
11
11
  from .reference import Reference
12
12
  from .response import Response, build_response_or_reference
@@ -34,7 +34,7 @@ class Responses:
34
34
 
35
35
  root_node: yaml.Node
36
36
  default: FieldSource[Response | Reference] | None = fixed_field()
37
- responses: dict[KeySource[str], Response | Reference] = field(default_factory=dict)
37
+ responses: dict[KeySource[str], Response | Reference] = patterned_field(default_factory=dict)
38
38
  extensions: dict[KeySource[str], ValueSource[YAMLValue]] = field(default_factory=dict)
39
39
 
40
40
 
@@ -33,8 +33,8 @@ class SecurityRequirement:
33
33
  """
34
34
 
35
35
  root_node: yaml.Node
36
- requirements: ValueSource[dict[KeySource[str], ValueSource[list[ValueSource[str]]]]] | None = (
37
- patterned_field()
36
+ requirements: dict[KeySource[str], ValueSource[list[ValueSource[str]]]] = patterned_field(
37
+ default_factory=dict
38
38
  )
39
39
 
40
40
 
@@ -61,7 +61,7 @@ def build(
61
61
  yaml = YAML()
62
62
  root = yaml.compose("api_key: []")
63
63
  security_req = build(root)
64
- assert security_req.requirements is not None
64
+ assert len(security_req.requirements) > 0
65
65
  """
66
66
  context = context or Context()
67
67
 
@@ -70,7 +70,7 @@ def build(
70
70
  value = context.yaml_constructor.construct_object(root, deep=True)
71
71
  return ValueSource(value=value, value_node=root)
72
72
 
73
- requirements_dict: dict[KeySource[str], ValueSource[list[ValueSource[str]]]] = {}
73
+ requirements = {}
74
74
 
75
75
  for key_node, value_node in root.value:
76
76
  key = context.yaml_constructor.construct_yaml_str(key_node)
@@ -88,19 +88,17 @@ def build(
88
88
  item_value = context.yaml_constructor.construct_object(item_node, deep=True)
89
89
  scope_list.append(ValueSource(value=item_value, value_node=item_node))
90
90
 
91
- requirements_dict[KeySource(value=key, key_node=key_node)] = ValueSource(
91
+ requirements[KeySource(value=key, key_node=key_node)] = ValueSource(
92
92
  value=scope_list, value_node=value_node
93
93
  )
94
94
  else:
95
95
  # Not a sequence - preserve as-is for validation to catch
96
96
  value = context.yaml_constructor.construct_object(value_node, deep=True)
97
- requirements_dict[KeySource(value=key, key_node=key_node)] = ValueSource(
97
+ requirements[KeySource(value=key, key_node=key_node)] = ValueSource(
98
98
  value=value, value_node=value_node
99
99
  )
100
100
 
101
101
  return SecurityRequirement(
102
102
  root_node=root,
103
- requirements=(
104
- ValueSource(value=requirements_dict, value_node=root) if requirements_dict else None
105
- ),
103
+ requirements=requirements,
106
104
  )
@@ -4,6 +4,7 @@ from ruamel import yaml
4
4
 
5
5
  from ..context import Context
6
6
  from ..extractors import extract_extension_fields
7
+ from ..fields import patterned_field
7
8
  from ..sources import KeySource, ValueSource, YAMLInvalidValue, YAMLValue
8
9
  from .path_item import PathItem
9
10
  from .path_item import build as build_path_item
@@ -33,7 +34,7 @@ class Callback:
33
34
  """
34
35
 
35
36
  root_node: yaml.Node
36
- path_items: dict[KeySource[str], PathItem] = field(default_factory=dict)
37
+ path_items: dict[KeySource[str], PathItem] = patterned_field(default_factory=dict)
37
38
  extensions: dict[KeySource[str], ValueSource[YAMLValue]] = field(default_factory=dict)
38
39
 
39
40
 
@@ -86,7 +87,7 @@ def build(
86
87
  extension_properties = {k.value for k in extensions.keys()}
87
88
 
88
89
  # Process each field to determine if it's an expression (not an extension)
89
- path_items: dict[KeySource[str], PathItem | ValueSource[YAMLInvalidValue]] = {}
90
+ path_items = {}
90
91
 
91
92
  for key_node, value_node in root.value:
92
93
  expression = context.yaml_constructor.construct_yaml_str(key_node)
@@ -99,7 +100,7 @@ def build(
99
100
  # Create and return the Callback object with collected data
100
101
  return Callback(
101
102
  root_node=root,
102
- path_items=path_items, # type: ignore[arg-type]
103
+ path_items=path_items,
103
104
  extensions=extensions,
104
105
  )
105
106
 
@@ -4,6 +4,7 @@ from ruamel import yaml
4
4
 
5
5
  from ..context import Context
6
6
  from ..extractors import extract_extension_fields
7
+ from ..fields import patterned_field
7
8
  from ..sources import KeySource, ValueSource, YAMLInvalidValue, YAMLValue
8
9
  from .path_item import PathItem
9
10
  from .path_item import build as build_path_item
@@ -33,7 +34,7 @@ class Paths:
33
34
  """
34
35
 
35
36
  root_node: yaml.Node
36
- paths: dict[KeySource[str], PathItem] = field(default_factory=dict)
37
+ paths: dict[KeySource[str], PathItem] = patterned_field(default_factory=dict)
37
38
  extensions: dict[KeySource[str], ValueSource[YAMLValue]] = field(default_factory=dict)
38
39
 
39
40
 
@@ -6,7 +6,7 @@ from ruamel import yaml
6
6
 
7
7
  from ..context import Context
8
8
  from ..extractors import extract_extension_fields
9
- from ..fields import fixed_field
9
+ from ..fields import fixed_field, patterned_field
10
10
  from ..sources import FieldSource, KeySource, ValueSource, YAMLInvalidValue, YAMLValue
11
11
  from .reference import Reference
12
12
  from .response import Response, build_response_or_reference
@@ -34,7 +34,7 @@ class Responses:
34
34
 
35
35
  root_node: yaml.Node
36
36
  default: FieldSource[Response | Reference] | None = fixed_field()
37
- responses: dict[KeySource[str], Response | Reference] = field(default_factory=dict)
37
+ responses: dict[KeySource[str], Response | Reference] = patterned_field(default_factory=dict)
38
38
  extensions: dict[KeySource[str], ValueSource[YAMLValue]] = field(default_factory=dict)
39
39
 
40
40
 
@@ -33,8 +33,8 @@ class SecurityRequirement:
33
33
  """
34
34
 
35
35
  root_node: yaml.Node
36
- requirements: ValueSource[dict[KeySource[str], ValueSource[list[ValueSource[str]]]]] | None = (
37
- patterned_field()
36
+ requirements: dict[KeySource[str], ValueSource[list[ValueSource[str]]]] = patterned_field(
37
+ default_factory=dict
38
38
  )
39
39
 
40
40
 
@@ -61,7 +61,7 @@ def build(
61
61
  yaml = YAML()
62
62
  root = yaml.compose("api_key: []")
63
63
  security_req = build(root)
64
- assert security_req.requirements is not None
64
+ assert len(security_req.requirements) > 0
65
65
  """
66
66
  context = context or Context()
67
67
 
@@ -70,7 +70,7 @@ def build(
70
70
  value = context.yaml_constructor.construct_object(root, deep=True)
71
71
  return ValueSource(value=value, value_node=root)
72
72
 
73
- requirements_dict: dict[KeySource[str], ValueSource[list[ValueSource[str]]]] = {}
73
+ requirements = {}
74
74
 
75
75
  for key_node, value_node in root.value:
76
76
  key = context.yaml_constructor.construct_yaml_str(key_node)
@@ -88,19 +88,17 @@ def build(
88
88
  item_value = context.yaml_constructor.construct_object(item_node, deep=True)
89
89
  scope_list.append(ValueSource(value=item_value, value_node=item_node))
90
90
 
91
- requirements_dict[KeySource(value=key, key_node=key_node)] = ValueSource(
91
+ requirements[KeySource(value=key, key_node=key_node)] = ValueSource(
92
92
  value=scope_list, value_node=value_node
93
93
  )
94
94
  else:
95
95
  # Not a sequence - preserve as-is for validation to catch
96
96
  value = context.yaml_constructor.construct_object(value_node, deep=True)
97
- requirements_dict[KeySource(value=key, key_node=key_node)] = ValueSource(
97
+ requirements[KeySource(value=key, key_node=key_node)] = ValueSource(
98
98
  value=value, value_node=value_node
99
99
  )
100
100
 
101
101
  return SecurityRequirement(
102
102
  root_node=root,
103
- requirements=(
104
- ValueSource(value=requirements_dict, value_node=root) if requirements_dict else None
105
- ),
103
+ requirements=requirements,
106
104
  )