Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit621be8d

Browse files
committed
AWS API Gateway with Amazon Lambda integrations support
1 parent0898d87 commit621be8d

File tree

18 files changed

+976
-165
lines changed

18 files changed

+976
-165
lines changed

‎docs/integrations.rst‎

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,59 @@ Integrations
33

44
Openapi-core integrates with your popular libraries and frameworks. Each integration offers different levels of integration that help validate and unmarshal your request and response data.
55

6+
Amazon API Gateway
7+
------------------
8+
9+
This section describes integration with `Amazon API Gateway<https://aws.amazon.com/api-gateway/>`__.
10+
11+
It is useful for:
12+
* `AWS Lambda integrations<https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-develop-integrations-lambda.html>`__ where Lambda functions handle events from API Gateway (Amazon API Gateway event format version 1.0 and 2.0).
13+
* `AWS Lambda function URLs <https://docs.aws.amazon.com/lambda/latest/dg/lambda-urls.html>` where Lambda functions handle events from dedicated HTTP(S) endpoint (Amazon API Gateway event format version 2.0).
14+
15+
Low level
16+
~~~~~~~~~
17+
18+
You can use ``APIGatewayEventV2OpenAPIRequest`` as an API Gateway event (format version 2.0) request factory:
19+
20+
..code-block::python
21+
22+
from openapi_coreimport unmarshal_request
23+
from openapi_core.contrib.awsimport APIGatewayEventV2OpenAPIRequest
24+
25+
openapi_request= APIGatewayEventV2OpenAPIRequest(event)
26+
result= unmarshal_request(openapi_request,spec=spec)
27+
28+
If you use format version 1.0, then import and use ``APIGatewayEventOpenAPIRequest`` as an API Gateway event (format version 1.0) request factory.
29+
30+
You can use ``APIGatewayEventV2ResponseOpenAPIResponse`` as an API Gateway event (format version 2.0) response factory:
31+
32+
..code-block::python
33+
34+
from openapi_coreimport unmarshal_response
35+
from openapi_core.contrib.awsimport APIGatewayEventV2ResponseOpenAPIResponse
36+
37+
openapi_response= APIGatewayEventV2ResponseOpenAPIResponse(response)
38+
result= unmarshal_response(openapi_request, openapi_response,spec=spec)
39+
40+
If you use format version 1.0, then import and use ``APIGatewayEventResponseOpenAPIResponse`` as an API Gateway event (format version 1.0) response factory.
41+
42+
ANY method
43+
~~~~~~~~~~
44+
45+
API Gateway have special ``ANY`` method that catches all HTTP methods. It's specified as `x-amazon-apigateway-any-method<https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-swagger-extensions-any-method.html>`__ OpenAPI extension. If you use the extension, you want to define ``path_finder_cls`` to be ``APIGatewayPathFinder``:
46+
47+
..code-block::python
48+
49+
from openapi_core.contrib.awsimport APIGatewayPathFinder
50+
51+
result= unmarshal_response(
52+
openapi_request,
53+
openapi_response,
54+
spec=spec,
55+
path_finder_cls=APIGatewayPathFinder,
56+
)
57+
58+
659
Bottle
760
------
861

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
"""OpenAPI core contrib aws module"""
2+
fromopenapi_core.contrib.aws.findersimportAPIGatewayPathFinder
3+
fromopenapi_core.contrib.aws.requestsimportAPIGatewayEventOpenAPIRequest
4+
fromopenapi_core.contrib.aws.requestsimportAPIGatewayEventV2OpenAPIRequest
5+
fromopenapi_core.contrib.aws.responsesimport (
6+
APIGatewayEventResponseOpenAPIResponse,
7+
)
8+
fromopenapi_core.contrib.aws.responsesimport (
9+
APIGatewayEventV2ResponseOpenAPIResponse,
10+
)
11+
12+
__all__= [
13+
"APIGatewayEventOpenAPIRequest",
14+
"APIGatewayEventV2OpenAPIRequest",
15+
"APIGatewayEventResponseOpenAPIResponse",
16+
"APIGatewayEventV2ResponseOpenAPIResponse",
17+
"APIGatewayPathFinder",
18+
]
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
fromtypingimportDict
2+
fromtypingimportList
3+
fromtypingimportOptional
4+
5+
frompydanticimportField
6+
frompydantic.dataclassesimportdataclass
7+
8+
9+
classAPIGatewayEventConfig:
10+
extra="allow"
11+
12+
13+
@dataclass(config=APIGatewayEventConfig,frozen=True)
14+
classAPIGatewayEvent:
15+
"""AWS API Gateway event"""
16+
17+
headers:Dict[str,str]
18+
19+
path:str
20+
httpMethod:str
21+
resource:str
22+
23+
queryStringParameters:Optional[Dict[str,str]]=None
24+
isBase64Encoded:Optional[bool]=None
25+
body:Optional[str]=None
26+
pathParameters:Optional[Dict[str,str]]=None
27+
stageVariables:Optional[Dict[str,str]]=None
28+
29+
multiValueHeaders:Optional[Dict[str,List[str]]]=None
30+
version:Optional[str]="1.0"
31+
multiValueQueryStringParameters:Optional[Dict[str,List[str]]]=None
32+
33+
34+
@dataclass(config=APIGatewayEventConfig,frozen=True)
35+
classAPIGatewayEventV2:
36+
"""AWS API Gateway event v2"""
37+
38+
headers:Dict[str,str]
39+
40+
version:str
41+
routeKey:str
42+
rawPath:str
43+
rawQueryString:str
44+
45+
queryStringParameters:Optional[Dict[str,str]]=None
46+
isBase64Encoded:Optional[bool]=None
47+
body:Optional[str]=None
48+
pathParameters:Optional[Dict[str,str]]=None
49+
stageVariables:Optional[Dict[str,str]]=None
50+
51+
cookies:Optional[List[str]]=None
52+
53+
54+
@dataclass(config=APIGatewayEventConfig,frozen=True)
55+
classAPIGatewayEventResponse:
56+
"""AWS API Gateway event response"""
57+
58+
body:str
59+
isBase64Encoded:bool
60+
statusCode:int
61+
headers:Dict[str,str]
62+
multiValueHeaders:Dict[str,List[str]]
63+
64+
65+
@dataclass(config=APIGatewayEventConfig,frozen=True)
66+
classAPIGatewayEventV2Response:
67+
"""AWS API Gateway event v2 response"""
68+
69+
body:str
70+
isBase64Encoded:bool=False
71+
statusCode:int=200
72+
headers:Dict[str,str]=Field(
73+
default_factory=lambda: {"content-type":"application/json"}
74+
)
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
fromopenapi_core.templating.paths.findersimportAPICallPathFinder
2+
fromopenapi_core.templating.paths.iteratorsimportAnyMethodOperationsIterator
3+
4+
5+
classAPIGatewayPathFinder(APICallPathFinder):
6+
operations_iterator=AnyMethodOperationsIterator(
7+
any_method="x-amazon-apigateway-any-method",
8+
)
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
fromtypingimportDict
2+
fromtypingimportOptional
3+
4+
fromwerkzeug.datastructuresimportHeaders
5+
fromwerkzeug.datastructuresimportImmutableMultiDict
6+
7+
fromopenapi_core.contrib.aws.datatypesimportAPIGatewayEvent
8+
fromopenapi_core.contrib.aws.datatypesimportAPIGatewayEventV2
9+
fromopenapi_core.contrib.aws.typesimportAPIGatewayEventPayload
10+
fromopenapi_core.datatypesimportRequestParameters
11+
12+
13+
classAPIGatewayEventOpenAPIRequest:
14+
"""
15+
Converts an API Gateway event payload to an OpenAPI request
16+
"""
17+
18+
def__init__(self,payload:APIGatewayEventPayload):
19+
self.event=APIGatewayEvent(**payload)
20+
21+
self.parameters=RequestParameters(
22+
query=ImmutableMultiDict(self.query_params),
23+
header=Headers(self.event.headers),
24+
cookie=ImmutableMultiDict(),
25+
)
26+
27+
@property
28+
defquery_params(self)->Dict[str,str]:
29+
params=self.event.queryStringParameters
30+
ifparamsisNone:
31+
return {}
32+
returnparams
33+
34+
@property
35+
defproto(self)->str:
36+
returnself.event.headers.get("X-Forwarded-Proto","https")
37+
38+
@property
39+
defhost(self)->str:
40+
returnself.event.headers["Host"]
41+
42+
@property
43+
defhost_url(self)->str:
44+
return"://".join([self.proto,self.host])
45+
46+
@property
47+
defpath(self)->str:
48+
returnself.event.resource
49+
50+
@property
51+
defmethod(self)->str:
52+
returnself.event.httpMethod.lower()
53+
54+
@property
55+
defbody(self)->Optional[str]:
56+
returnself.event.body
57+
58+
@property
59+
defmimetype(self)->str:
60+
returnself.event.headers.get("Content-Type","")
61+
62+
63+
classAPIGatewayEventV2OpenAPIRequest:
64+
"""
65+
Converts an API Gateway event v2 payload to an OpenAPI request
66+
"""
67+
68+
def__init__(self,payload:APIGatewayEventPayload):
69+
self.event=APIGatewayEventV2(**payload)
70+
71+
self.parameters=RequestParameters(
72+
query=ImmutableMultiDict(self.query_params),
73+
header=Headers(self.event.headers),
74+
cookie=ImmutableMultiDict(),
75+
)
76+
77+
@property
78+
defquery_params(self)->Dict[str,str]:
79+
ifself.event.queryStringParametersisNone:
80+
return {}
81+
returnself.event.queryStringParameters
82+
83+
@property
84+
defproto(self)->str:
85+
returnself.event.headers.get("x-forwarded-proto","https")
86+
87+
@property
88+
defhost(self)->str:
89+
returnself.event.headers["host"]
90+
91+
@property
92+
defhost_url(self)->str:
93+
return"://".join([self.proto,self.host])
94+
95+
@property
96+
defpath(self)->str:
97+
returnself.event.rawPath
98+
99+
@property
100+
defmethod(self)->str:
101+
returnself.event.routeKey.lower()
102+
103+
@property
104+
defbody(self)->Optional[str]:
105+
returnself.event.body
106+
107+
@property
108+
defmimetype(self)->str:
109+
returnself.event.headers.get("content-type","")
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
fromjsonimportdumps
2+
fromtypingimportUnion
3+
4+
fromwerkzeug.datastructuresimportHeaders
5+
6+
fromopenapi_core.contrib.aws.datatypesimportAPIGatewayEventResponse
7+
fromopenapi_core.contrib.aws.datatypesimportAPIGatewayEventV2Response
8+
fromopenapi_core.contrib.aws.typesimportAPIGatewayEventResponsePayload
9+
10+
APIGatewayEventV2ResponseType=Union[APIGatewayEventV2Response,dict,str]
11+
12+
13+
classAPIGatewayEventResponseOpenAPIResponse:
14+
"""
15+
Converts an API Gateway event response payload to an OpenAPI request
16+
"""
17+
18+
def__init__(self,payload:APIGatewayEventResponsePayload):
19+
self.response=APIGatewayEventResponse(**payload)
20+
21+
@property
22+
defdata(self)->str:
23+
returnself.response.body
24+
25+
@property
26+
defstatus_code(self)->int:
27+
returnself.response.statusCode
28+
29+
@property
30+
defheaders(self)->Headers:
31+
returnHeaders(self.response.headers)
32+
33+
@property
34+
defmimetype(self)->str:
35+
content_type=self.response.headers.get("Content-Type","")
36+
assertisinstance(content_type,str)
37+
returncontent_type
38+
39+
40+
classAPIGatewayEventV2ResponseOpenAPIResponse:
41+
"""
42+
Converts an API Gateway event v2 response payload to an OpenAPI request
43+
"""
44+
45+
def__init__(self,payload:Union[APIGatewayEventResponsePayload,str]):
46+
ifnotisinstance(payload,dict):
47+
payload=self._construct_payload(payload)
48+
elif"statusCode"notinpayload:
49+
body=dumps(payload)
50+
payload=self._construct_payload(body)
51+
52+
self.response=APIGatewayEventV2Response(**payload)
53+
54+
@staticmethod
55+
def_construct_payload(body:str)->APIGatewayEventResponsePayload:
56+
return {
57+
"isBase64Encoded":False,
58+
"statusCode":200,
59+
"headers": {
60+
"content-type":"application/json",
61+
},
62+
"body":body,
63+
}
64+
65+
@property
66+
defdata(self)->str:
67+
returnself.response.body
68+
69+
@property
70+
defstatus_code(self)->int:
71+
returnself.response.statusCode
72+
73+
@property
74+
defheaders(self)->Headers:
75+
returnHeaders(self.response.headers)
76+
77+
@property
78+
defmimetype(self)->str:
79+
content_type=self.response.headers.get(
80+
"content-type","application/json"
81+
)
82+
assertisinstance(content_type,str)
83+
returncontent_type

‎openapi_core/contrib/aws/types.py‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
fromtypingimportAny
2+
fromtypingimportDict
3+
4+
APIGatewayEventPayload=Dict[str,Any]
5+
APIGatewayEventResponsePayload=Dict[str,Any]
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
fromopenapi_core.templating.paths.findersimportAPICallPathFinder
2+
fromopenapi_core.templating.paths.findersimportWebhookPathFinder
3+
4+
__all__= [
5+
"APICallPathFinder",
6+
"WebhookPathFinder",
7+
]

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp