Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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])