jentic-openapi-datamodels 1.0.0a12__py3-none-any.whl → 1.0.0a13__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/datamodels/low/context.py +21 -0
- jentic/apitools/openapi/datamodels/low/extractors.py +126 -0
- jentic/apitools/openapi/datamodels/low/fields.py +45 -0
- jentic/apitools/openapi/datamodels/low/model_builder.py +113 -0
- jentic/apitools/openapi/datamodels/low/py.typed +0 -0
- jentic/apitools/openapi/datamodels/low/sources.py +89 -0
- jentic/apitools/openapi/datamodels/low/v30/__init__.py +0 -28
- jentic/apitools/openapi/datamodels/low/v30/discriminator.py +53 -78
- jentic/apitools/openapi/datamodels/low/v30/external_documentation.py +47 -61
- jentic/apitools/openapi/datamodels/low/v30/oauth_flow.py +54 -123
- jentic/apitools/openapi/datamodels/low/v30/oauth_flows.py +102 -151
- jentic/apitools/openapi/datamodels/low/v30/reference.py +43 -44
- jentic/apitools/openapi/datamodels/low/v30/schema.py +316 -607
- jentic/apitools/openapi/datamodels/low/v30/security_requirement.py +82 -72
- jentic/apitools/openapi/datamodels/low/v30/security_scheme.py +94 -286
- jentic/apitools/openapi/datamodels/low/v30/tag.py +88 -119
- jentic/apitools/openapi/datamodels/low/v30/xml.py +46 -120
- jentic_openapi_datamodels-1.0.0a13.dist-info/METADATA +211 -0
- jentic_openapi_datamodels-1.0.0a13.dist-info/RECORD +23 -0
- jentic/apitools/openapi/datamodels/low/v30/specification_object.py +0 -217
- jentic_openapi_datamodels-1.0.0a12.dist-info/METADATA +0 -52
- jentic_openapi_datamodels-1.0.0a12.dist-info/RECORD +0 -18
- /jentic/apitools/openapi/datamodels/low/{v30/py.typed → __init__.py} +0 -0
- {jentic_openapi_datamodels-1.0.0a12.dist-info → jentic_openapi_datamodels-1.0.0a13.dist-info}/WHEEL +0 -0
- {jentic_openapi_datamodels-1.0.0a12.dist-info → jentic_openapi_datamodels-1.0.0a13.dist-info}/licenses/LICENSE +0 -0
- {jentic_openapi_datamodels-1.0.0a12.dist-info → jentic_openapi_datamodels-1.0.0a13.dist-info}/licenses/NOTICE +0 -0
|
@@ -1,79 +1,65 @@
|
|
|
1
|
-
|
|
2
|
-
OpenAPI 3.0.4 External Documentation Object model.
|
|
1
|
+
from dataclasses import dataclass, field
|
|
3
2
|
|
|
4
|
-
|
|
5
|
-
"""
|
|
3
|
+
from ruamel import yaml
|
|
6
4
|
|
|
7
|
-
from jentic.apitools.openapi.datamodels.low.
|
|
5
|
+
from jentic.apitools.openapi.datamodels.low.context import Context
|
|
6
|
+
from jentic.apitools.openapi.datamodels.low.fields import fixed_field
|
|
7
|
+
from jentic.apitools.openapi.datamodels.low.model_builder import build_model
|
|
8
|
+
from jentic.apitools.openapi.datamodels.low.sources import (
|
|
9
|
+
FieldSource,
|
|
10
|
+
KeySource,
|
|
11
|
+
ValueSource,
|
|
12
|
+
YAMLInvalidValue,
|
|
13
|
+
YAMLValue,
|
|
14
|
+
)
|
|
8
15
|
|
|
9
16
|
|
|
10
|
-
__all__ = ["ExternalDocumentation"]
|
|
17
|
+
__all__ = ["ExternalDocumentation", "build"]
|
|
11
18
|
|
|
12
19
|
|
|
13
|
-
|
|
20
|
+
@dataclass(frozen=True, slots=True)
|
|
21
|
+
class ExternalDocumentation:
|
|
14
22
|
"""
|
|
15
|
-
|
|
23
|
+
External Documentation Object representation for OpenAPI 3.0.
|
|
16
24
|
|
|
17
25
|
Allows referencing an external resource for extended documentation.
|
|
18
26
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
... "url": "https://example.com/docs"
|
|
25
|
-
... })
|
|
26
|
-
>>> docs.url
|
|
27
|
-
'https://example.com/docs'
|
|
28
|
-
|
|
29
|
-
>>> # With description
|
|
30
|
-
>>> docs = ExternalDocumentation({
|
|
31
|
-
... "description": "Find more info here",
|
|
32
|
-
... "url": "https://example.com/docs/api"
|
|
33
|
-
... })
|
|
34
|
-
>>> docs.description
|
|
35
|
-
'Find more info here'
|
|
36
|
-
>>> docs.url
|
|
37
|
-
'https://example.com/docs/api'
|
|
27
|
+
Attributes:
|
|
28
|
+
root_node: The top-level node representing the entire External Documentation object in the original source file
|
|
29
|
+
description: A short description of the target documentation. CommonMark syntax MAY be used for rich text representation.
|
|
30
|
+
url: The URL for the target documentation. REQUIRED. Value MUST be in the format of a URL.
|
|
31
|
+
extensions: Specification extensions (x-* fields)
|
|
38
32
|
"""
|
|
39
33
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
def description(self) -> str | None:
|
|
45
|
-
"""
|
|
46
|
-
A description of the target documentation.
|
|
34
|
+
root_node: yaml.Node
|
|
35
|
+
description: FieldSource[str] | None = fixed_field()
|
|
36
|
+
url: FieldSource[str] | None = fixed_field()
|
|
37
|
+
extensions: dict[KeySource[str], ValueSource[YAMLValue]] = field(default_factory=dict)
|
|
47
38
|
|
|
48
|
-
Returns:
|
|
49
|
-
Description or None if not present
|
|
50
|
-
"""
|
|
51
|
-
return self.get("description")
|
|
52
39
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
else:
|
|
59
|
-
self["description"] = value
|
|
40
|
+
def build(
|
|
41
|
+
root: yaml.Node, context: Context | None = None
|
|
42
|
+
) -> ExternalDocumentation | ValueSource[YAMLInvalidValue]:
|
|
43
|
+
"""
|
|
44
|
+
Build an ExternalDocumentation object from a YAML node.
|
|
60
45
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
"""
|
|
64
|
-
The URL for the target documentation.
|
|
46
|
+
Preserves all source data as-is, regardless of type. This is a low-level/plumbing
|
|
47
|
+
model that provides complete source fidelity for inspection and validation.
|
|
65
48
|
|
|
66
|
-
|
|
49
|
+
Args:
|
|
50
|
+
root: The YAML node to parse (should be a MappingNode)
|
|
51
|
+
context: Optional parsing context. If None, a default context will be created.
|
|
67
52
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
53
|
+
Returns:
|
|
54
|
+
An ExternalDocumentation object if the node is valid, or a ValueSource containing
|
|
55
|
+
the invalid data if the root is not a MappingNode (preserving the invalid data
|
|
56
|
+
and its source location for validation).
|
|
72
57
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
58
|
+
Example:
|
|
59
|
+
from ruamel.yaml import YAML
|
|
60
|
+
yaml = YAML()
|
|
61
|
+
root = yaml.compose("url: https://example.com\\ndescription: Find more info here")
|
|
62
|
+
external_docs = build(root)
|
|
63
|
+
assert external_docs.url.value == 'https://example.com'
|
|
64
|
+
"""
|
|
65
|
+
return build_model(root, ExternalDocumentation, context=context)
|
|
@@ -1,140 +1,71 @@
|
|
|
1
|
-
|
|
2
|
-
OpenAPI 3.0.4 OAuth Flow Object model.
|
|
1
|
+
from dataclasses import dataclass, field
|
|
3
2
|
|
|
4
|
-
|
|
5
|
-
Different OAuth flows use different combinations of the fields.
|
|
6
|
-
"""
|
|
3
|
+
from ruamel import yaml
|
|
7
4
|
|
|
8
|
-
from
|
|
5
|
+
from jentic.apitools.openapi.datamodels.low.context import Context
|
|
6
|
+
from jentic.apitools.openapi.datamodels.low.fields import fixed_field
|
|
7
|
+
from jentic.apitools.openapi.datamodels.low.model_builder import build_model
|
|
8
|
+
from jentic.apitools.openapi.datamodels.low.sources import (
|
|
9
|
+
FieldSource,
|
|
10
|
+
KeySource,
|
|
11
|
+
ValueSource,
|
|
12
|
+
YAMLInvalidValue,
|
|
13
|
+
YAMLValue,
|
|
14
|
+
)
|
|
9
15
|
|
|
10
|
-
from jentic.apitools.openapi.datamodels.low.v30.specification_object import SpecificationObject
|
|
11
16
|
|
|
17
|
+
__all__ = ["OAuthFlow", "build"]
|
|
12
18
|
|
|
13
|
-
__all__ = ["OAuthFlow"]
|
|
14
19
|
|
|
15
|
-
|
|
16
|
-
class OAuthFlow
|
|
20
|
+
@dataclass(frozen=True, slots=True)
|
|
21
|
+
class OAuthFlow:
|
|
17
22
|
"""
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
Configuration details for a supported OAuth Flow. Different flow types
|
|
21
|
-
(authorization code, implicit, password, client credentials) use different
|
|
22
|
-
combinations of these fields.
|
|
23
|
-
|
|
24
|
-
Supports specification extensions (x-* fields).
|
|
25
|
-
|
|
26
|
-
Example:
|
|
27
|
-
>>> # Authorization Code flow
|
|
28
|
-
>>> flow = OAuthFlow({
|
|
29
|
-
... "authorizationUrl": "https://example.com/oauth/authorize",
|
|
30
|
-
... "tokenUrl": "https://example.com/oauth/token",
|
|
31
|
-
... "scopes": {
|
|
32
|
-
... "read:pets": "Read access to pets",
|
|
33
|
-
... "write:pets": "Write access to pets"
|
|
34
|
-
... }
|
|
35
|
-
... })
|
|
36
|
-
>>> flow.authorization_url
|
|
37
|
-
'https://example.com/oauth/authorize'
|
|
38
|
-
>>> flow.scopes
|
|
39
|
-
{'read:pets': 'Read access to pets', 'write:pets': 'Write access to pets'}
|
|
23
|
+
OAuth Flow Object representation for OpenAPI 3.0.
|
|
40
24
|
|
|
41
|
-
|
|
42
|
-
>>> flow = OAuthFlow({
|
|
43
|
-
... "authorizationUrl": "https://example.com/oauth/authorize",
|
|
44
|
-
... "scopes": {"read": "Read access"}
|
|
45
|
-
... })
|
|
46
|
-
>>> print(flow.token_url)
|
|
47
|
-
None
|
|
25
|
+
Configuration details for a supported OAuth Flow.
|
|
48
26
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
{'x-token-ttl': 3600}
|
|
27
|
+
Attributes:
|
|
28
|
+
root_node: The top-level node representing the entire OAuth Flow object in the original source file
|
|
29
|
+
authorization_url: The authorization URL to be used for this flow. REQUIRED for implicit and authorization_code flows.
|
|
30
|
+
token_url: The token URL to be used for this flow. REQUIRED for password, client_credentials, and authorization_code flows.
|
|
31
|
+
refresh_url: The URL to be used for obtaining refresh tokens. This MUST be in the form of a URL.
|
|
32
|
+
scopes: The available scopes for the OAuth2 security scheme. A map between the scope name and a short description for it.
|
|
33
|
+
extensions: Specification extensions (x-* fields)
|
|
57
34
|
"""
|
|
58
35
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
Returns:
|
|
69
|
-
Authorization URL or None if not present
|
|
70
|
-
"""
|
|
71
|
-
return self.get("authorizationUrl")
|
|
72
|
-
|
|
73
|
-
@authorization_url.setter
|
|
74
|
-
def authorization_url(self, value: str | None) -> None:
|
|
75
|
-
"""Set the authorization URL."""
|
|
76
|
-
if value is None:
|
|
77
|
-
self.pop("authorizationUrl", None)
|
|
78
|
-
else:
|
|
79
|
-
self["authorizationUrl"] = value
|
|
36
|
+
root_node: yaml.Node
|
|
37
|
+
authorization_url: FieldSource[str] | None = fixed_field(
|
|
38
|
+
metadata={"yaml_name": "authorizationUrl"}
|
|
39
|
+
)
|
|
40
|
+
token_url: FieldSource[str] | None = fixed_field(metadata={"yaml_name": "tokenUrl"})
|
|
41
|
+
refresh_url: FieldSource[str] | None = fixed_field(metadata={"yaml_name": "refreshUrl"})
|
|
42
|
+
scopes: FieldSource[dict[KeySource[str], ValueSource[str]]] | None = fixed_field()
|
|
43
|
+
extensions: dict[KeySource[str], ValueSource[YAMLValue]] = field(default_factory=dict)
|
|
80
44
|
|
|
81
|
-
@property
|
|
82
|
-
def token_url(self) -> str | None:
|
|
83
|
-
"""
|
|
84
|
-
OAuth token endpoint URL.
|
|
85
45
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
return self.get("tokenUrl")
|
|
92
|
-
|
|
93
|
-
@token_url.setter
|
|
94
|
-
def token_url(self, value: str | None) -> None:
|
|
95
|
-
"""Set the token URL."""
|
|
96
|
-
if value is None:
|
|
97
|
-
self.pop("tokenUrl", None)
|
|
98
|
-
else:
|
|
99
|
-
self["tokenUrl"] = value
|
|
100
|
-
|
|
101
|
-
@property
|
|
102
|
-
def refresh_url(self) -> str | None:
|
|
103
|
-
"""
|
|
104
|
-
OAuth refresh token endpoint URL (optional for all flows).
|
|
105
|
-
|
|
106
|
-
Returns:
|
|
107
|
-
Refresh URL or None if not present
|
|
108
|
-
"""
|
|
109
|
-
return self.get("refreshUrl")
|
|
110
|
-
|
|
111
|
-
@refresh_url.setter
|
|
112
|
-
def refresh_url(self, value: str | None) -> None:
|
|
113
|
-
"""Set the refresh URL."""
|
|
114
|
-
if value is None:
|
|
115
|
-
self.pop("refreshUrl", None)
|
|
116
|
-
else:
|
|
117
|
-
self["refreshUrl"] = value
|
|
46
|
+
def build(
|
|
47
|
+
root: yaml.Node, context: Context | None = None
|
|
48
|
+
) -> OAuthFlow | ValueSource[YAMLInvalidValue]:
|
|
49
|
+
"""
|
|
50
|
+
Build an OAuthFlow object from a YAML node.
|
|
118
51
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
"""
|
|
122
|
-
Available scopes for the OAuth2 security scheme.
|
|
52
|
+
Preserves all source data as-is, regardless of type. This is a low-level/plumbing
|
|
53
|
+
model that provides complete source fidelity for inspection and validation.
|
|
123
54
|
|
|
124
|
-
|
|
55
|
+
Args:
|
|
56
|
+
root: The YAML node to parse (should be a MappingNode)
|
|
57
|
+
context: Optional parsing context. If None, a default context will be created.
|
|
125
58
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
if scopes is None:
|
|
131
|
-
return {}
|
|
132
|
-
return dict(scopes) if isinstance(scopes, Mapping) else {}
|
|
59
|
+
Returns:
|
|
60
|
+
An OAuthFlow object if the node is valid, or a ValueSource containing
|
|
61
|
+
the invalid data if the root is not a MappingNode (preserving the invalid data
|
|
62
|
+
and its source location for validation).
|
|
133
63
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
64
|
+
Example:
|
|
65
|
+
from ruamel.yaml import YAML
|
|
66
|
+
yaml = YAML()
|
|
67
|
+
root = yaml.compose("tokenUrl: https://example.com/oauth/token\\nscopes:\\n read: Read access")
|
|
68
|
+
oauth_flow = build(root)
|
|
69
|
+
assert oauth_flow.tokenUrl.value == 'https://example.com/oauth/token'
|
|
70
|
+
"""
|
|
71
|
+
return build_model(root, OAuthFlow, context=context)
|
|
@@ -1,165 +1,116 @@
|
|
|
1
|
-
|
|
2
|
-
OpenAPI 3.0.4 OAuth Flows Object model.
|
|
3
|
-
|
|
4
|
-
Allows configuration of the supported OAuth Flows.
|
|
5
|
-
"""
|
|
6
|
-
|
|
7
|
-
from collections.abc import Mapping
|
|
1
|
+
from dataclasses import dataclass, field
|
|
8
2
|
from typing import Any
|
|
9
3
|
|
|
4
|
+
from ruamel import yaml
|
|
5
|
+
|
|
6
|
+
from jentic.apitools.openapi.datamodels.low.context import Context
|
|
7
|
+
from jentic.apitools.openapi.datamodels.low.extractors import extract_extension_fields
|
|
8
|
+
from jentic.apitools.openapi.datamodels.low.fields import fixed_field, fixed_fields
|
|
9
|
+
from jentic.apitools.openapi.datamodels.low.sources import (
|
|
10
|
+
FieldSource,
|
|
11
|
+
KeySource,
|
|
12
|
+
ValueSource,
|
|
13
|
+
YAMLInvalidValue,
|
|
14
|
+
YAMLValue,
|
|
15
|
+
)
|
|
10
16
|
from jentic.apitools.openapi.datamodels.low.v30.oauth_flow import OAuthFlow
|
|
11
|
-
from jentic.apitools.openapi.datamodels.low.v30.
|
|
17
|
+
from jentic.apitools.openapi.datamodels.low.v30.oauth_flow import build as build_oauth_flow
|
|
12
18
|
|
|
13
19
|
|
|
14
|
-
__all__ = ["OAuthFlows"]
|
|
20
|
+
__all__ = ["OAuthFlows", "build"]
|
|
15
21
|
|
|
16
22
|
|
|
17
|
-
|
|
23
|
+
@dataclass(frozen=True, slots=True)
|
|
24
|
+
class OAuthFlows:
|
|
25
|
+
"""
|
|
26
|
+
OAuth Flows Object representation for OpenAPI 3.0.
|
|
27
|
+
|
|
28
|
+
A container for the list of possible OAuth 2.0 authorization flows.
|
|
29
|
+
Used within Security Scheme Objects when type is set to "oauth2".
|
|
30
|
+
|
|
31
|
+
Attributes:
|
|
32
|
+
root_node: The top-level node representing the entire OAuth Flows object in the original source file
|
|
33
|
+
implicit: Configuration for the OAuth Implicit flow
|
|
34
|
+
password: Configuration for the OAuth Resource Owner Password flow
|
|
35
|
+
client_credentials: Configuration for the OAuth Client Credentials flow (application flow)
|
|
36
|
+
authorization_code: Configuration for the OAuth Authorization Code flow (three-legged OAuth)
|
|
37
|
+
extensions: Specification extensions (x-* fields)
|
|
18
38
|
"""
|
|
19
|
-
Represents an OAuth Flows Object from OpenAPI 3.0.4.
|
|
20
39
|
|
|
21
|
-
|
|
22
|
-
|
|
40
|
+
root_node: yaml.Node
|
|
41
|
+
implicit: FieldSource[OAuthFlow] | None = fixed_field()
|
|
42
|
+
password: FieldSource[OAuthFlow] | None = fixed_field()
|
|
43
|
+
client_credentials: FieldSource[OAuthFlow] | None = fixed_field(
|
|
44
|
+
metadata={"yaml_name": "clientCredentials"}
|
|
45
|
+
)
|
|
46
|
+
authorization_code: FieldSource[OAuthFlow] | None = fixed_field(
|
|
47
|
+
metadata={"yaml_name": "authorizationCode"}
|
|
48
|
+
)
|
|
49
|
+
extensions: dict[KeySource[str], ValueSource[YAMLValue]] = field(default_factory=dict)
|
|
23
50
|
|
|
24
|
-
Supports specification extensions (x-* fields).
|
|
25
51
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
... "implicit": {
|
|
30
|
-
... "authorizationUrl": "https://example.com/oauth/authorize",
|
|
31
|
-
... "scopes": {"read": "Read access", "write": "Write access"}
|
|
32
|
-
... },
|
|
33
|
-
... "authorizationCode": {
|
|
34
|
-
... "authorizationUrl": "https://example.com/oauth/authorize",
|
|
35
|
-
... "tokenUrl": "https://example.com/oauth/token",
|
|
36
|
-
... "scopes": {"read": "Read access", "write": "Write access"}
|
|
37
|
-
... }
|
|
38
|
-
... })
|
|
39
|
-
>>> flows.implicit.authorization_url
|
|
40
|
-
'https://example.com/oauth/authorize'
|
|
41
|
-
>>> flows.authorization_code.token_url
|
|
42
|
-
'https://example.com/oauth/token'
|
|
43
|
-
|
|
44
|
-
>>> # Single flow
|
|
45
|
-
>>> flows = OAuthFlows({
|
|
46
|
-
... "clientCredentials": {
|
|
47
|
-
... "tokenUrl": "https://example.com/oauth/token",
|
|
48
|
-
... "scopes": {"api": "API access"}
|
|
49
|
-
... }
|
|
50
|
-
... })
|
|
51
|
-
>>> flows.client_credentials.scopes
|
|
52
|
-
{'api': 'API access'}
|
|
53
|
-
>>> print(flows.implicit)
|
|
54
|
-
None
|
|
55
|
-
|
|
56
|
-
>>> # With extensions
|
|
57
|
-
>>> flows = OAuthFlows({
|
|
58
|
-
... "password": {
|
|
59
|
-
... "tokenUrl": "https://example.com/oauth/token",
|
|
60
|
-
... "scopes": {}
|
|
61
|
-
... },
|
|
62
|
-
... "x-flow-timeout": 3600
|
|
63
|
-
... })
|
|
64
|
-
>>> flows.get_extensions()
|
|
65
|
-
{'x-flow-timeout': 3600}
|
|
52
|
+
def build(
|
|
53
|
+
root: yaml.Node, context: Context | None = None
|
|
54
|
+
) -> OAuthFlows | ValueSource[YAMLInvalidValue]:
|
|
66
55
|
"""
|
|
56
|
+
Build an OAuthFlows object from a YAML node.
|
|
67
57
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
58
|
+
Preserves all source data as-is, regardless of type. This is a low-level/plumbing
|
|
59
|
+
model that provides complete source fidelity for inspection and validation.
|
|
60
|
+
|
|
61
|
+
Args:
|
|
62
|
+
root: The YAML node to parse (should be a MappingNode)
|
|
63
|
+
context: Optional parsing context. If None, a default context will be created.
|
|
64
|
+
|
|
65
|
+
Returns:
|
|
66
|
+
An OAuthFlows object if the node is valid, or a ValueSource containing
|
|
67
|
+
the invalid data if the root is not a MappingNode (preserving the invalid data
|
|
68
|
+
and its source location for validation).
|
|
72
69
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
""
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
"""
|
|
121
|
-
return self.get("password")
|
|
122
|
-
|
|
123
|
-
@password.setter
|
|
124
|
-
def password(self, value: OAuthFlow | None) -> None:
|
|
125
|
-
"""Set the password flow configuration."""
|
|
126
|
-
if value is None:
|
|
127
|
-
self.pop("password", None)
|
|
128
|
-
else:
|
|
129
|
-
self["password"] = value
|
|
130
|
-
|
|
131
|
-
@property
|
|
132
|
-
def client_credentials(self) -> OAuthFlow | None:
|
|
133
|
-
"""
|
|
134
|
-
Configuration for the OAuth Client Credentials flow.
|
|
135
|
-
|
|
136
|
-
Returns:
|
|
137
|
-
OAuthFlow instance or None if not configured
|
|
138
|
-
"""
|
|
139
|
-
return self.get("clientCredentials")
|
|
140
|
-
|
|
141
|
-
@client_credentials.setter
|
|
142
|
-
def client_credentials(self, value: OAuthFlow | None) -> None:
|
|
143
|
-
"""Set the client credentials flow configuration."""
|
|
144
|
-
if value is None:
|
|
145
|
-
self.pop("clientCredentials", None)
|
|
146
|
-
else:
|
|
147
|
-
self["clientCredentials"] = value
|
|
148
|
-
|
|
149
|
-
@property
|
|
150
|
-
def authorization_code(self) -> OAuthFlow | None:
|
|
151
|
-
"""
|
|
152
|
-
Configuration for the OAuth Authorization Code flow.
|
|
153
|
-
|
|
154
|
-
Returns:
|
|
155
|
-
OAuthFlow instance or None if not configured
|
|
156
|
-
"""
|
|
157
|
-
return self.get("authorizationCode")
|
|
158
|
-
|
|
159
|
-
@authorization_code.setter
|
|
160
|
-
def authorization_code(self, value: OAuthFlow | None) -> None:
|
|
161
|
-
"""Set the authorization code flow configuration."""
|
|
162
|
-
if value is None:
|
|
163
|
-
self.pop("authorizationCode", None)
|
|
164
|
-
else:
|
|
165
|
-
self["authorizationCode"] = value
|
|
70
|
+
Example:
|
|
71
|
+
from ruamel.yaml import YAML
|
|
72
|
+
yaml = YAML()
|
|
73
|
+
root = yaml.compose("implicit:\\n authorizationUrl: https://example.com/auth\\n scopes: {}")
|
|
74
|
+
flows = build(root)
|
|
75
|
+
assert flows.implicit.value.authorization_url.value == 'https://example.com/auth'
|
|
76
|
+
"""
|
|
77
|
+
# Initialize context once at the beginning
|
|
78
|
+
if context is None:
|
|
79
|
+
context = Context()
|
|
80
|
+
|
|
81
|
+
if not isinstance(root, yaml.MappingNode):
|
|
82
|
+
# Preserve invalid root data instead of returning None
|
|
83
|
+
value = context.yaml_constructor.construct_object(root, deep=True)
|
|
84
|
+
return ValueSource(value=value, value_node=root)
|
|
85
|
+
|
|
86
|
+
# Get fixed specification fields for this dataclass type
|
|
87
|
+
_fixed_fields = fixed_fields(OAuthFlows)
|
|
88
|
+
|
|
89
|
+
# Build YAML name to Python field name mapping
|
|
90
|
+
yaml_to_field = {
|
|
91
|
+
field.metadata.get("yaml_name", fname): fname for fname, field in _fixed_fields.items()
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
# Extract field values in a single pass
|
|
95
|
+
field_values: dict[str, Any] = {}
|
|
96
|
+
for key_node, value_node in root.value:
|
|
97
|
+
key = context.yaml_constructor.construct_yaml_str(key_node)
|
|
98
|
+
|
|
99
|
+
# Map YAML key to Python field name
|
|
100
|
+
field_name = yaml_to_field.get(key)
|
|
101
|
+
if field_name:
|
|
102
|
+
# Build OAuthFlow for this field - child builder handles invalid nodes
|
|
103
|
+
# FieldSource will auto-unwrap ValueSource if child returns it for invalid data
|
|
104
|
+
oauth_flow = build_oauth_flow(value_node, context=context)
|
|
105
|
+
field_values[field_name] = FieldSource(
|
|
106
|
+
value=oauth_flow, key_node=key_node, value_node=value_node
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
return OAuthFlows(
|
|
110
|
+
root_node=root,
|
|
111
|
+
implicit=field_values.get("implicit"),
|
|
112
|
+
password=field_values.get("password"),
|
|
113
|
+
client_credentials=field_values.get("client_credentials"),
|
|
114
|
+
authorization_code=field_values.get("authorization_code"),
|
|
115
|
+
extensions=extract_extension_fields(root, context),
|
|
116
|
+
)
|