jentic-openapi-datamodels 1.0.0a2__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,28 @@
1
+ """OpenAPI 3.0.x low-level models."""
2
+
3
+ from .discriminator import Discriminator
4
+ from .external_documentation import ExternalDocumentation
5
+ from .oauth_flow import OAuthFlow
6
+ from .oauth_flows import OAuthFlows
7
+ from .reference import Reference
8
+ from .schema import Schema
9
+ from .security_requirement import SecurityRequirement
10
+ from .security_scheme import SecurityScheme
11
+ from .specification_object import SpecificationObject
12
+ from .tag import Tag
13
+ from .xml import XML
14
+
15
+
16
+ __all__ = [
17
+ "Discriminator",
18
+ "ExternalDocumentation",
19
+ "OAuthFlow",
20
+ "OAuthFlows",
21
+ "Reference",
22
+ "Schema",
23
+ "SecurityRequirement",
24
+ "SecurityScheme",
25
+ "SpecificationObject",
26
+ "Tag",
27
+ "XML",
28
+ ]
@@ -0,0 +1,91 @@
1
+ """
2
+ OpenAPI 3.0.4 Discriminator Object model.
3
+
4
+ When request bodies or response payloads may be one of a number of different schemas,
5
+ a discriminator object gives a hint about the expected schema.
6
+ """
7
+
8
+ from collections.abc import Mapping
9
+
10
+ from jentic.apitools.openapi.datamodels.low.v30.specification_object import SpecificationObject
11
+
12
+
13
+ __all__ = ["Discriminator"]
14
+
15
+
16
+ class Discriminator(SpecificationObject):
17
+ """
18
+ Represents a Discriminator Object from OpenAPI 3.0.4.
19
+
20
+ Used to support polymorphism by indicating which property in a payload
21
+ is used to differentiate between schemas.
22
+
23
+ Supports specification extensions (x-* fields).
24
+
25
+ Example:
26
+ >>> # Basic discriminator
27
+ >>> disc = Discriminator({
28
+ ... "propertyName": "petType"
29
+ ... })
30
+ >>> disc.property_name
31
+ 'petType'
32
+
33
+ >>> # With mapping
34
+ >>> disc = Discriminator({
35
+ ... "propertyName": "petType",
36
+ ... "mapping": {
37
+ ... "dog": "#/components/schemas/Dog",
38
+ ... "cat": "#/components/schemas/Cat",
39
+ ... "lizard": "https://example.com/schemas/Lizard.json"
40
+ ... }
41
+ ... })
42
+ >>> disc.property_name
43
+ 'petType'
44
+ >>> disc.mapping["dog"]
45
+ '#/components/schemas/Dog'
46
+ """
47
+
48
+ _supports_extensions: bool = True
49
+ _fixed_fields: frozenset[str] = frozenset({"propertyName", "mapping"})
50
+
51
+ @property
52
+ def property_name(self) -> str | None:
53
+ """
54
+ The name of the property in the payload to discriminate schemas.
55
+
56
+ REQUIRED field.
57
+
58
+ Returns:
59
+ Property name or None if not present
60
+ """
61
+ return self.get("propertyName")
62
+
63
+ @property_name.setter
64
+ def property_name(self, value: str | None) -> None:
65
+ """Set the property name."""
66
+ if value is None:
67
+ self.pop("propertyName", None)
68
+ else:
69
+ self["propertyName"] = value
70
+
71
+ @property
72
+ def mapping(self) -> dict[str, str]:
73
+ """
74
+ Mapping between payload values and schema names/references.
75
+
76
+ Maps discriminator property values to schema names or references.
77
+ When absent, the value is expected to match a schema name.
78
+
79
+ Returns:
80
+ Dictionary mapping values to schema references (empty dict if not present)
81
+ """
82
+ return self.get("mapping", {})
83
+
84
+ @mapping.setter
85
+ def mapping(self, value: Mapping[str, str] | None) -> None:
86
+ """Set the mapping."""
87
+ if value is None:
88
+ self.pop("mapping", None)
89
+ else:
90
+ # Convert to plain dict once at storage time
91
+ self["mapping"] = dict(value) if isinstance(value, Mapping) else value
@@ -0,0 +1,79 @@
1
+ """
2
+ OpenAPI 3.0.4 External Documentation Object model.
3
+
4
+ Allows referencing an external resource for extended documentation.
5
+ """
6
+
7
+ from jentic.apitools.openapi.datamodels.low.v30.specification_object import SpecificationObject
8
+
9
+
10
+ __all__ = ["ExternalDocumentation"]
11
+
12
+
13
+ class ExternalDocumentation(SpecificationObject):
14
+ """
15
+ Represents an External Documentation Object from OpenAPI 3.0.4.
16
+
17
+ Allows referencing an external resource for extended documentation.
18
+
19
+ Supports specification extensions (x-* fields).
20
+
21
+ Example:
22
+ >>> # Basic external docs
23
+ >>> docs = ExternalDocumentation({
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'
38
+ """
39
+
40
+ _supports_extensions: bool = True
41
+ _fixed_fields: frozenset[str] = frozenset({"description", "url"})
42
+
43
+ @property
44
+ def description(self) -> str | None:
45
+ """
46
+ A description of the target documentation.
47
+
48
+ Returns:
49
+ Description or None if not present
50
+ """
51
+ return self.get("description")
52
+
53
+ @description.setter
54
+ def description(self, value: str | None) -> None:
55
+ """Set the description."""
56
+ if value is None:
57
+ self.pop("description", None)
58
+ else:
59
+ self["description"] = value
60
+
61
+ @property
62
+ def url(self) -> str | None:
63
+ """
64
+ The URL for the target documentation.
65
+
66
+ REQUIRED field.
67
+
68
+ Returns:
69
+ URL or None if not present
70
+ """
71
+ return self.get("url")
72
+
73
+ @url.setter
74
+ def url(self, value: str | None) -> None:
75
+ """Set the URL."""
76
+ if value is None:
77
+ self.pop("url", None)
78
+ else:
79
+ self["url"] = value
@@ -0,0 +1,140 @@
1
+ """
2
+ OpenAPI 3.0.4 OAuth Flow Object model.
3
+
4
+ Configuration details for a supported OAuth Flow as defined in RFC 6749.
5
+ Different OAuth flows use different combinations of the fields.
6
+ """
7
+
8
+ from collections.abc import Mapping
9
+
10
+ from jentic.apitools.openapi.datamodels.low.v30.specification_object import SpecificationObject
11
+
12
+
13
+ __all__ = ["OAuthFlow"]
14
+
15
+
16
+ class OAuthFlow(SpecificationObject):
17
+ """
18
+ Represents an OAuth Flow Object from OpenAPI 3.0.4.
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'}
40
+
41
+ >>> # Implicit flow
42
+ >>> flow = OAuthFlow({
43
+ ... "authorizationUrl": "https://example.com/oauth/authorize",
44
+ ... "scopes": {"read": "Read access"}
45
+ ... })
46
+ >>> print(flow.token_url)
47
+ None
48
+
49
+ >>> # With extensions
50
+ >>> flow = OAuthFlow({
51
+ ... "tokenUrl": "https://example.com/oauth/token",
52
+ ... "scopes": {},
53
+ ... "x-token-ttl": 3600
54
+ ... })
55
+ >>> flow.get_extensions()
56
+ {'x-token-ttl': 3600}
57
+ """
58
+
59
+ _supports_extensions: bool = True
60
+
61
+ @property
62
+ def authorization_url(self) -> str | None:
63
+ """
64
+ OAuth authorization endpoint URL.
65
+
66
+ REQUIRED for: authorizationCode, implicit flows.
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
80
+
81
+ @property
82
+ def token_url(self) -> str | None:
83
+ """
84
+ OAuth token endpoint URL.
85
+
86
+ REQUIRED for: authorizationCode, password, clientCredentials flows.
87
+
88
+ Returns:
89
+ Token URL or None if not present
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
118
+
119
+ @property
120
+ def scopes(self) -> dict[str, str]:
121
+ """
122
+ Available scopes for the OAuth2 security scheme.
123
+
124
+ Maps scope names to their descriptions. REQUIRED for all flows.
125
+
126
+ Returns:
127
+ Dictionary mapping scope names to descriptions (empty dict if not present)
128
+ """
129
+ scopes = self.get("scopes")
130
+ if scopes is None:
131
+ return {}
132
+ return dict(scopes) if isinstance(scopes, Mapping) else {}
133
+
134
+ @scopes.setter
135
+ def scopes(self, value: dict[str, str] | Mapping[str, str] | None) -> None:
136
+ """Set the scopes mapping."""
137
+ if value is None:
138
+ self.pop("scopes", None)
139
+ else:
140
+ self["scopes"] = dict(value) if isinstance(value, Mapping) else value
@@ -0,0 +1,165 @@
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
8
+ from typing import Any
9
+
10
+ from jentic.apitools.openapi.datamodels.low.v30.oauth_flow import OAuthFlow
11
+ from jentic.apitools.openapi.datamodels.low.v30.specification_object import SpecificationObject
12
+
13
+
14
+ __all__ = ["OAuthFlows"]
15
+
16
+
17
+ class OAuthFlows(SpecificationObject):
18
+ """
19
+ Represents an OAuth Flows Object from OpenAPI 3.0.4.
20
+
21
+ Allows configuration of the supported OAuth Flows. Each property corresponds
22
+ to a different OAuth 2.0 flow type as defined in RFC 6749.
23
+
24
+ Supports specification extensions (x-* fields).
25
+
26
+ Example:
27
+ >>> # Multiple flows
28
+ >>> flows = OAuthFlows({
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}
66
+ """
67
+
68
+ _supports_extensions: bool = True
69
+ _fixed_fields: frozenset[str] = frozenset(
70
+ {"implicit", "password", "clientCredentials", "authorizationCode"}
71
+ )
72
+
73
+ def __init__(self, data: Mapping[str, Any] | None = None):
74
+ """
75
+ Initialize an OAuthFlows object.
76
+
77
+ Automatically marshals nested flow data (Mappings) into OAuthFlow instances.
78
+
79
+ Args:
80
+ data: Optional mapping to initialize the object with
81
+ """
82
+ super().__init__()
83
+ if data:
84
+ for key, value in data.items():
85
+ if (
86
+ key in self._fixed_fields
87
+ and isinstance(value, Mapping)
88
+ and not isinstance(value, OAuthFlow)
89
+ ):
90
+ self[key] = OAuthFlow(value)
91
+ else:
92
+ # Store as-is (already OAuthFlow, extension, or other)
93
+ self[key] = self._copy_value(value)
94
+
95
+ @property
96
+ def implicit(self) -> OAuthFlow | None:
97
+ """
98
+ Configuration for the OAuth Implicit flow.
99
+
100
+ Returns:
101
+ OAuthFlow instance or None if not configured
102
+ """
103
+ return self.get("implicit")
104
+
105
+ @implicit.setter
106
+ def implicit(self, value: OAuthFlow | None) -> None:
107
+ """Set the implicit flow configuration."""
108
+ if value is None:
109
+ self.pop("implicit", None)
110
+ else:
111
+ self["implicit"] = value
112
+
113
+ @property
114
+ def password(self) -> OAuthFlow | None:
115
+ """
116
+ Configuration for the OAuth Resource Owner Password flow.
117
+
118
+ Returns:
119
+ OAuthFlow instance or None if not configured
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
File without changes
@@ -0,0 +1,64 @@
1
+ """
2
+ OpenAPI 3.0.4 Reference Object model.
3
+
4
+ A simple object to allow referencing other components in the OpenAPI document.
5
+ """
6
+
7
+ from jentic.apitools.openapi.datamodels.low.v30.specification_object import SpecificationObject
8
+
9
+
10
+ __all__ = ["Reference"]
11
+
12
+
13
+ class Reference(SpecificationObject):
14
+ """
15
+ Represents a Reference Object from OpenAPI 3.0.4.
16
+
17
+ A simple object to allow referencing other components in the OpenAPI document,
18
+ internally and externally.
19
+
20
+ IMPORTANT: Reference Objects in OpenAPI 3.0.x do NOT support specification extensions.
21
+
22
+ Example:
23
+ >>> # Internal reference
24
+ >>> ref = Reference({"$ref": "#/components/schemas/Pet"})
25
+ >>> ref.ref
26
+ '#/components/schemas/Pet'
27
+ >>> ref["$ref"]
28
+ '#/components/schemas/Pet'
29
+
30
+ >>> # External reference
31
+ >>> ref = Reference({"$ref": "https://example.com/schemas/Pet.json"})
32
+ >>> ref.ref
33
+ 'https://example.com/schemas/Pet.json'
34
+ """
35
+
36
+ _supports_extensions: bool = False
37
+ _fixed_fields: frozenset[str] = frozenset({"$ref"})
38
+
39
+ @property
40
+ def ref(self) -> str | None:
41
+ """
42
+ The reference string identifying the location of the referenced object.
43
+
44
+ Maps to the "$ref" field in OpenAPI.
45
+
46
+ Can be:
47
+ - Internal: "#/components/schemas/Pet"
48
+ - External URL: "https://example.com/schemas/Pet.json"
49
+ - Relative file: "./schemas/Pet.yaml#/Pet"
50
+
51
+ REQUIRED field.
52
+
53
+ Returns:
54
+ Reference string or None if not present
55
+ """
56
+ return self.get("$ref")
57
+
58
+ @ref.setter
59
+ def ref(self, value: str | None) -> None:
60
+ """Set the reference string."""
61
+ if value is None:
62
+ self.pop("$ref", None)
63
+ else:
64
+ self["$ref"] = value