jupyter / help

:sparkles: Need some help or have some questions? Please visit our Discourse page.
https://discourse.jupyter.org
291 stars 97 forks source link

How to return a binary file using Jupyter kernel gateway API - Python ipynb #463

Open esecastro opened 5 years ago

esecastro commented 5 years ago

I have created a notebook (Python code) that is published for requests using Jupyter Kernel Gateway API (kernel_gateway.notebook_http). I'm able to reply the http requests using print, if the response is a string or json.

How can I reply a binary file (PDF for example) from the notebook using Python? I can't not use print as it requires an string and sys.stdout.buffer.write(...) is not available.

Regards

minrk commented 5 years ago

You can use a display message, which allows arbitrary mime-types:

from IPython.display import publish_display_data
with open(pdf_file) as f:
    publish_display_data({'application/pdf': f.read()})

This will result in a display_data message containing the base64-encoded pdf file.

esecastro commented 5 years ago

Hi. This doesn't work. PDF is a binary file, if I try to read with open(pdf_file), I get an exception: "Error UnicodeDecodeError: 'utf-8' codec can't decode byte 0xfe in position 28: invalid start byte ". If I try to read as binary open(pdf_file, 'rb'), I don't receive any response from the service on the browser.

minrk commented 5 years ago

Sorry, open(pdf_file, 'rb') should work.

esecastro commented 5 years ago

I have used 'rb', the problem is that I need to use print() to send this a response of the ipynb execution. If I use publish_display_data, the result is not captured by Kernel Gateway.

I'm using the ipynb for creating a service using Jupyter Kernel Gateway. I'm able to return a base64 encoded file in a json reply, but I would like to reply it as 'application/pdf' to open directly in the browser without any intermediate javascript code.

esecastro commented 5 years ago

From j kernel gateway doc

Setting the Response Body

The response from an annotated cell may be set in one of two ways:

So, I guess that I need to write the binary data to stdout. How can I do this without ...buffer.write?