Consulting about how to use websocket to submit jobs to IPython 3.2.1 notebook while having password to login in to IPython notebook

207 views
Skip to first unread message

薛亚兰

unread,
May 3, 2016, 4:09:17 AM5/3/16
to jup...@googlegroups.com, benja...@gmail.com
Hi MinRK and Jupyter community,
          I am a member of IBM software engineers, and we are using IPython 3.2.1 in our products, to meet our requirements, we need to use comman line to submit jobs to IPython notebook instead of using the IPyhton GUI, we know from this site https://github.com/ipython/ipython/wiki/Dev:-URL-mapping-of-IPython-notebook that we can use 
WS/api/kernels
/<kernel_id>/channels
Websocket stream
to submit jhobs to IPython, however, this really works when we do not set login password for IPython notebook, but in our usage, we need to set passward to each notebook, as we write our own authenticator class and define it equal to c.NotebookApp.login_handler_class= in ipython_notebook_config.py file, in this case, when we use websocket to connect to the URL, it returned 403 error due to the password limitation.

the code we use to submit job like this:

code:

  wss_url = "ws://$HOSTNAME:$PORT/api/kernels/$KERNEL_ID/channels?session_id=$SESSION_ID"
  ws.connect(wss_url)

results:

  File "JPMC_Spark161_Ipython321_submitJob.py", line 134, in create_ws_spark_twitter_analyzer
    ws.connect(wss_url)
  File "/usr/lib/python2.7/site-packages/websocket_client-0.35.0-py2.7.egg/websocket/_core.py", line 272, in connect
    self.handshake_response = handshake(self.sock, *addrs, **options)
  File "/usr/lib/python2.7/site-packages/websocket_client-0.35.0-py2.7.egg/websocket/_handshake.py", line 67, in handshake
    status, resp = _get_resp_headers(sock)
  File "/usr/lib/python2.7/site-packages/websocket_client-0.35.0-py2.7.egg/websocket/_handshake.py", line 123, in _get_resp_headers
    raise WebSocketBadStatusException("Handshake status %d", status)
  WebSocketBadStatusException: Handshake status 403

we are wondering how to pass the password check using websocket, looking forward to your reply.

Many thanks in advance!
  

--
Yalan  Xue

Peter Parente

unread,
May 3, 2016, 10:58:03 AM5/3/16
to Project Jupyter, benja...@gmail.com
Hello fellow IBMer, :)

The kernel gateway (https://github.com/jupyter/kernel_gateway) was created to handle programmatic access to kernels via websockets. It supports token auth instead of human-friendly cookie auth. If you're not 100% strictly tied to using the notebook server, you should check it out.

If that's not an option, then I think you need to programmatically go through the steps of doing form based authentication on the Jupyter login form, and then pass the cookie header back in your websocket connection like a browser would. How you pass that header depends on the client you are using and whether it supports setting headers on websocket connections or not. For example, with the Tornado websocket client (http://tornado.readthedocs.io/en/latest/websocket.html?highlight=websocket#client-side-support), you can pass an HTTPRequest object with arbitrary headers. 

Cheers,
Pete

薛亚兰

unread,
May 10, 2016, 1:41:33 AM5/10/16
to MinRK, jup...@googlegroups.com
Hi MinRK,
                 Thanks for your kind recommedation and suggestion, and we have got the cookie using post method by POST the login url , like the following, and cookies will be stored in the request object y:
   para = {'password':'123')
   y = s.post(post_url,data=para)
however, we really have no way in how to inlcude the cookie in the websocket connection, could you help give some hint(regardless of the authhandler defined by ourself, just using the default handler), it's really important for us, and we really found no way to solve this. and the way we are using websocket to submit job to kernel is as follows:
wss_url = "ws://asc-08.ma.platformlab.ibm.com:8891/api/kernels/3dde3fd9-cd05-4c74-a48f-168ac105f308/channels?session_id=46FC60A7B6B14D729296D3BC5FE4CC02"
 ws.connect(wss_url)


the s and ws are objects created with python's request and websocket module.


Thanks and have a nice day!

Yalan Xue


2016-05-03 16:39 GMT+08:00 MinRK <benja...@gmail.com>:

With the default handler, that would be logging in with a POST with username/password to the login URL, which sets a cookie, and then including that cookie when making the websocket connection.

Your login_handler_class can override .get_user(handler), which should return the logged-in username (None if not authenticated). I’m not sure how you are implementing custom login, but this is one place where custom logic can reside, in particular the ability to be authenticated without setting any cookies by using a token in headers, etc.

-MinRK




--
Yalan  Xue , SIT  Lab of   Nanjing  University 
 Address: Nanjing ,China。

MinRK

unread,
May 10, 2016, 4:01:24 AM5/10/16
to 薛亚兰, Project Jupyter

On Tue, May 10, 2016 at 7:41 AM, 薛亚兰 <nju08e...@gmail.com> wrote:

Hi MinRK,
                 Thanks for your kind recommedation and suggestion, and we have got the cookie using post method by POST the login url , like the following, and cookies will be stored in the request object y:
   para = {'password':'123')
   y = s.post(post_url,data=para)
however, we really have no way in how to inlcude the cookie in the websocket connection, could you help give some hint(regardless of the authhandler defined by ourself, just using the default handler), it's really important for us, and we really found no way to solve this. and the way we are using websocket to submit job to kernel is as follows:
wss_url = "ws://asc-08.ma.platformlab.ibm.com:8891/api/kernels/3dde3fd9-cd05-4c74-a48f-168ac105f308/channels?session_id=46FC60A7B6B14D729296D3BC5FE4CC02"
 ws.connect(wss_url)


the s and ws are objects created with python's request and websocket module.

Cookies can be passed to the websocket via the cookie kwarg in WebSocket.connect:

import requests
import websocket

nb_url = 'https://notebook-host:8888'
password = 'yourpasword'
kernel_id = 'u-u-i-d'

# login with requests
login = requests.post(nb_url + '/login', data={'password': password}, allow_redirects=False)
login.raise_for_status()
cookie = login.headers['set-cookie']

# connect websocket with our login cookie:
ws_url = 'ws' + nb_url[4:] # http[s] -> ws[s]
ws = websocket.WebSocket()
ws.connect('{0}/api/kernels/{1}/channels'.format(ws_url, kernel_id), cookie=cookie)

-MinRK

薛亚兰

unread,
May 10, 2016, 5:44:48 AM5/10/16
to MinRK, jup...@googlegroups.com
Thanks very much!

Appreciate your help!

Sincere regards to you.
Reply all
Reply to author
Forward
0 new messages