Skip to content

Commit

Permalink
Support sending response as binary data
Browse files Browse the repository at this point in the history
  • Loading branch information
zootalures committed Jul 6, 2020
1 parent 8faa373 commit 9f74407
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 4 deletions.
26 changes: 26 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,32 @@ def handler(ctx, data: io.BytesIO=None):

```

## Writing binary data from functions
In order to write a binary response to your function pass a `bytes` object to the response_data

```python
import io
from PIL import Image, ImageDraw
from fdk import response


def handler(ctx, data: io.BytesIO=None):
img = Image.new('RGB', (100, 30), color='red')
d = ImageDraw.Draw(img)
d.text((10, 10), "hello world", fill=(255, 255, 0))
# write png image to memory
output = io.BytesIO()
img.save(output, format="PNG")
# get the bytes of the image
imgbytes = output.getvalue()

return response.Response(
ctx, response_data=imgbytes,
headers={"Content-Type": "image/png"}
)
```



## Unit testing your functions

Expand Down
2 changes: 1 addition & 1 deletion fdk/async_http/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ async def handle_request(self, request, write_callback, stream_callback):
headers = res.headers
status = res.status
response = HTTPResponse(
body=body, status=status, headers=headers,
body_bytes=body, status=status, headers=headers,
)
except CancelledError:
response = None
Expand Down
2 changes: 1 addition & 1 deletion fdk/event_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ async def pure_handler(request):
headers=headers,
status=status,
content_type=headers.get(constants.CONTENT_TYPE),
body_bytes=func_response.body(),
body_bytes=func_response.body_bytes(),
)

return pure_handler
Expand Down
17 changes: 15 additions & 2 deletions fdk/response.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,16 @@

from fdk import context
from fdk import constants
from typing import Union


class Response(object):

def __init__(self, ctx: context.InvokeContext,
response_data: str=None,
response_data: Union[str, bytes]=None,
headers: dict=None,
status_code: int=200):
status_code: int=200,
response_encoding: str="utf-8"):
"""
Creates an FDK-readable response object
:param ctx: invoke context
Expand All @@ -32,10 +34,14 @@ def __init__(self, ctx: context.InvokeContext,
:type headers: dict
:param status_code: response code
:type status_code: int
:param response_encoding: response encoding for strings ("utf-8")
:type response_encoding: str
"""
self.ctx = ctx
self.status_code = status_code
self.response_data = response_data if response_data else ""
self.response_encoding = response_encoding

if headers is None:
headers = {}
headers.update({constants.FN_FDK_VERSION:
Expand All @@ -49,5 +55,12 @@ def status(self):
def body(self):
return self.response_data

def body_bytes(self):
if isinstance(self.response_data, bytes) or \
isinstance(self.response_data, bytearray):
return self.response_data
else:
return str(self.response_data).encode(self.response_encoding)

def context(self):
return self.ctx
4 changes: 4 additions & 0 deletions fdk/tests/funcs.py
Original file line number Diff line number Diff line change
Expand Up @@ -141,3 +141,7 @@ def capture_request_ctx(ctx, **kwargs):
global captured_context
captured_context = ctx
return response.Response(ctx, response_data="OK")


def binary_result(ctx, **kwargs):
return response.Response(ctx, response_data=bytes([1, 2, 3, 4, 5]))
7 changes: 7 additions & 0 deletions fdk/tests/test_http_stream.py
Original file line number Diff line number Diff line change
Expand Up @@ -249,3 +249,10 @@ async def test_encap_request_headers_gateway():

assert input_ctx.HTTPHeaders() == {"my-header": "foo",
"funny-header": ["baz", "bob"]}


@pytest.mark.asyncio
async def test_bytes_response():
call = await fixtures.setup_fn_call(funcs.binary_result)
content, status, headers = await call
assert content == bytes([1, 2, 3, 4, 5])

0 comments on commit 9f74407

Please sign in to comment.