Skip to content

Commit a0c8375

Browse files
committed
OpenAPI app and high level integration
1 parent 46639b5 commit a0c8375

File tree

3 files changed

+95
-0
lines changed

3 files changed

+95
-0
lines changed

openapi_core/app.py

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
from pathlib import Path
2+
3+
from jsonschema_path import SchemaPath
4+
from jsonschema_path.handlers.protocols import SupportsRead
5+
from jsonschema_path.typing import Schema
6+
from openapi_spec_validator.validation.types import SpecValidatorType
7+
8+
from openapi_core.protocols import Integration
9+
from openapi_core.shortcuts import unmarshal_request
10+
from openapi_core.shortcuts import unmarshal_response
11+
from openapi_core.shortcuts import validate_request
12+
from openapi_core.shortcuts import validate_response
13+
from openapi_core.typing import RequestType
14+
from openapi_core.typing import ResponseType
15+
from openapi_core.unmarshalling.request.datatypes import RequestUnmarshalResult
16+
from openapi_core.unmarshalling.response.datatypes import ResponseUnmarshalResult
17+
18+
19+
class OpenAPI:
20+
21+
def __init__(self, spec: SchemaPath, integration: Integration, spec_validator_cls: SpecValidatorType):
22+
if spec_validator_cls is not None:
23+
spec_validator = spec_validator_cls(spec)
24+
spec_validator.validate()
25+
26+
self.spec = spec
27+
self.integration = integration
28+
29+
@classmethod
30+
def from_dict(cls, data: Schema, integration: Integration, spec_validator_cls: SpecValidatorType) -> "OpenAPI":
31+
spec = SchemaPath.from_dict(data)
32+
return cls(spec, integration, spec_validator_cls=spec_validator_cls)
33+
34+
@classmethod
35+
def from_path(cls, path: Path, integration: Integration, spec_validator_cls: SpecValidatorType) -> "OpenAPI":
36+
spec = SchemaPath.from_path(path)
37+
return cls(spec, integration, spec_validator_cls=spec_validator_cls)
38+
39+
@classmethod
40+
def from_file_path(cls, file_path: str, integration: Integration, spec_validator_cls: SpecValidatorType) -> "OpenAPI":
41+
spec = SchemaPath.from_file_path(file_path)
42+
return cls(spec, integration, spec_validator_cls=spec_validator_cls)
43+
44+
@classmethod
45+
def from_file(cls, fileobj: SupportsRead, integration: Integration, spec_validator_cls: SpecValidatorType) -> "OpenAPI":
46+
spec = SchemaPath.from_file(fileobj)
47+
return cls(spec, integration, spec_validator_cls=spec_validator_cls)
48+
49+
def validate_request(self, request: RequestType) -> None:
50+
openapi_request = self.integration.get_openapi_request(request)
51+
validate_request(openapi_request, spec=self.spec)
52+
53+
def validate_response(self, request: RequestType, response: ResponseType) -> None:
54+
openapi_request = self.integration.get_openapi_request(request)
55+
openapi_response = self.integration.get_openapi_response(response)
56+
validate_response(openapi_request, openapi_response, spec=self.spec)
57+
58+
def unmarshal_request(self, request: RequestType) -> RequestUnmarshalResult:
59+
openapi_request = self.integration.get_openapi_request(request)
60+
return unmarshal_request(openapi_request, spec=self.spec)
61+
62+
def unmarshal_response(self, request: RequestType, response: ResponseType) -> ResponseUnmarshalResult:
63+
openapi_request = self.integration.get_openapi_request(request)
64+
openapi_response = self.integration.get_openapi_response(response)
65+
return unmarshal_response(openapi_request, openapi_response, spec=self.spec)
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
from flask.wrappers import Request
2+
from flask.wrappers import Response
3+
4+
from openapi_core.contrib.flask.requests import FlaskOpenAPIRequest
5+
from openapi_core.contrib.flask.responses import FlaskOpenAPIResponse
6+
7+
8+
class FlaskIntegration:
9+
request_cls = FlaskOpenAPIRequest
10+
response_cls = FlaskOpenAPIResponse
11+
12+
def get_openapi_request(self, request: Request) -> FlaskOpenAPIRequest:
13+
return self.request_cls(request)
14+
15+
def get_openapi_response(self, response: Response) -> FlaskOpenAPIResponse:
16+
assert self.response_cls is not None
17+
return self.response_cls(response)

openapi_core/protocols.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
from typing import runtime_checkable
77

88
from openapi_core.datatypes import RequestParameters
9+
from openapi_core.typing import RequestType
10+
from openapi_core.typing import ResponseType
911

1012

1113
@runtime_checkable
@@ -134,3 +136,14 @@ def content_type(self) -> str:
134136
@property
135137
def headers(self) -> Mapping[str, Any]:
136138
...
139+
140+
141+
@runtime_checkable
142+
class Integration(Protocol):
143+
"""Integration protocol."""
144+
145+
def get_openapi_request(self, request: RequestType) -> Request:
146+
...
147+
148+
def get_openapi_response(self, response: ResponseType) -> Response:
149+
...

0 commit comments

Comments
 (0)