Skip to content
This repository was archived by the owner on Nov 19, 2023. It is now read-only.

Commit 09941a0

Browse files
committed
support binary responses
1 parent 6a61e00 commit 09941a0

8 files changed

+95
-3
lines changed

Diff for: api_gateway_v2_to_wsgi.py

+10-1
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,18 @@ def __call__(
5454
return self.body.write
5555

5656
def response(self) -> Dict[str, Any]:
57+
body_b = self.body.getvalue()
58+
try:
59+
body = body_b.decode()
60+
is_base64_encoded = False
61+
except UnicodeDecodeError:
62+
body = base64.b64encode(body_b).decode()
63+
is_base64_encoded = True
64+
5765
return {
66+
'isBase64Encoded': is_base64_encoded,
5867
'statusCode': self.status_code,
59-
'body': self.body.getvalue().decode(),
68+
'body': body,
6069
'headers': {k: ','.join(v) for k, v in self.headers.items()},
6170
}
6271

Diff for: testing/data/image.json

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
{
2+
"version": "2.0",
3+
"routeKey": "$default",
4+
"rawPath": "/image.gif",
5+
"rawQueryString": "",
6+
"headers": {
7+
"accept": "*/*",
8+
"content-length": "0",
9+
"host": "kr8spsb5ti.execute-api.us-east-1.amazonaws.com",
10+
"user-agent": "curl/7.68.0",
11+
"x-amzn-trace-id": "Root=1-5f30b572-3f87b39ad007312beebc1a92",
12+
"x-forwarded-for": "76.14.26.166",
13+
"x-forwarded-port": "443",
14+
"x-forwarded-proto": "https"
15+
},
16+
"requestContext": {
17+
"accountId": "952911408644",
18+
"apiId": "kr8spsb5ti",
19+
"domainName": "kr8spsb5ti.execute-api.us-east-1.amazonaws.com",
20+
"domainPrefix": "kr8spsb5ti",
21+
"http": {
22+
"method": "GET",
23+
"path": "/image.gif",
24+
"protocol": "HTTP/1.1",
25+
"sourceIp": "76.14.26.166",
26+
"userAgent": "curl/7.68.0"
27+
},
28+
"requestId": "RCFJ1jzyoAMEPMQ=",
29+
"routeKey": "$default",
30+
"stage": "$default",
31+
"time": "10/Aug/2020:02:48:18 +0000",
32+
"timeEpoch": 1597027698026
33+
},
34+
"isBase64Encoded": false
35+
}

Diff for: testing/example/README.md

+6-1
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,14 @@ aws_lambda_permission.sample_app_gateway: Creating...
4949
aws_lambda_permission.sample_app_gateway: Creation complete after 1s [id=terraform-20200810034859413700000003]
5050

5151
Apply complete! Resources: 6 added, 0 changed, 0 destroyed.
52+
53+
Outputs:
54+
55+
api_gateway_address = "https://l45ezct9w4.execute-api.us-east-1.amazonaws.com"
5256
```
5357

54-
the important part of this is the `id=l45ezct9w4` portion, we'll be using that later!
58+
the important part of this is the `api_gateway_address` portion, we'll be
59+
using that later!
5560

5661
### trying out the gateway
5762

Diff for: testing/example/requirements.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
api-gateway-v2-to-wsgi
1+
../..
22
flask

Diff for: testing/example/sample_app.py

+10
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,16 @@ def profile(username: str) -> str:
1515
return f'hello hello {username}'
1616

1717

18+
@app.route('/image.gif')
19+
def image_route() -> flask.Response:
20+
return flask.Response(
21+
b'GIF89a\x01\x00\x01\x00\x80\x00\x00\xff\xff\xff\x00\x00\x00!\xf9'
22+
b'\x04\x01\x00\x00\x00\x00,\x00\x00\x00\x00\x01\x00\x01\x00\x00\x02'
23+
b'\x02D\x01\x00;',
24+
mimetype='image/gif',
25+
)
26+
27+
1828
lambda_handler = api_gateway_v2_to_wsgi.make_lambda_handler(app)
1929

2030

Diff for: testing/example/tf/.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
/*.tfstate
22
/*.tfstate.*
33
/.terraform
4+
/.terraform.lock.hcl

Diff for: testing/example/tf/lambda_sample_app.tf

+4
Original file line numberDiff line numberDiff line change
@@ -38,3 +38,7 @@ resource "aws_lambda_permission" "sample_app_gateway" {
3838

3939
source_arn = "${aws_apigatewayv2_api.sample_app_gateway.execution_arn}/*/*"
4040
}
41+
42+
output "api_gateway_address" {
43+
value = aws_apigatewayv2_api.sample_app_gateway.api_endpoint
44+
}

Diff for: tests/api_gateway_v2_to_wsgi_test.py

+28
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,16 @@ def cookies_route():
4848
'''
4949

5050

51+
@app.route('/image.gif')
52+
def image_route():
53+
return flask.Response(
54+
b'GIF89a\x01\x00\x01\x00\x80\x00\x00\xff\xff\xff\x00\x00\x00!\xf9'
55+
b'\x04\x01\x00\x00\x00\x00,\x00\x00\x00\x00\x01\x00\x01\x00\x00\x02'
56+
b'\x02D\x01\x00;',
57+
mimetype='image/gif',
58+
)
59+
60+
5161
handler = api_gateway_v2_to_wsgi.make_lambda_handler(app)
5262

5363

@@ -66,6 +76,7 @@ def test_get_request():
6676
'''
6777
assert resp == {
6878
'statusCode': 200,
79+
'isBase64Encoded': False,
6980
'body': expected_body,
7081
'headers': {
7182
'Content-Length': '96',
@@ -82,6 +93,7 @@ def test_post_request():
8293
'''
8394
assert resp == {
8495
'statusCode': 200,
96+
'isBase64Encoded': False,
8597
'body': expected_body,
8698
'headers': {
8799
'Content-Length': '17',
@@ -99,6 +111,7 @@ def test_query_string():
99111
'''
100112
assert resp == {
101113
'statusCode': 200,
114+
'isBase64Encoded': False,
102115
'body': expected_body,
103116
'headers': {
104117
'Content-Length': '45',
@@ -118,6 +131,7 @@ def test_multi_headers():
118131
'''
119132
assert resp == {
120133
'statusCode': 200,
134+
'isBase64Encoded': False,
121135
'body': expected_body,
122136
'headers': {
123137
'Content-Length': '104',
@@ -154,9 +168,23 @@ def test_cookies():
154168
'''
155169
assert resp == {
156170
'statusCode': 200,
171+
'isBase64Encoded': False,
157172
'body': expected_body,
158173
'headers': {
159174
'Content-Length': '42',
160175
'Content-Type': 'text/html; charset=utf-8',
161176
},
162177
}
178+
179+
180+
def test_binary_reposnse():
181+
resp = handler(_event('image'), {})
182+
assert resp == {
183+
'statusCode': 200,
184+
'isBase64Encoded': True,
185+
'body': 'R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==',
186+
'headers': {
187+
'Content-Length': '43',
188+
'Content-Type': 'image/gif',
189+
},
190+
}

0 commit comments

Comments
 (0)