From 3017361904582bf206d7c37fc46e89b26931db61 Mon Sep 17 00:00:00 2001 From: vermeul <swen@ethz.ch> Date: Wed, 31 Oct 2018 18:10:32 +0100 Subject: [PATCH] added server.py --- jupyter-openbis-extension/.server.py.swp | Bin 0 -> 28672 bytes jupyter-openbis-extension/__init__.py | 0 .../__pycache__/__init__.cpython-36.pyc | Bin 0 -> 161 bytes .../__pycache__/extension.cpython-36.pyc | Bin 0 -> 2057 bytes .../__pycache__/server.cpython-36.pyc | Bin 0 -> 6373 bytes jupyter-openbis-extension/server.py | 238 ++++++++++++++++++ 6 files changed, 238 insertions(+) create mode 100644 jupyter-openbis-extension/.server.py.swp create mode 100644 jupyter-openbis-extension/__init__.py create mode 100644 jupyter-openbis-extension/__pycache__/__init__.cpython-36.pyc create mode 100644 jupyter-openbis-extension/__pycache__/extension.cpython-36.pyc create mode 100644 jupyter-openbis-extension/__pycache__/server.cpython-36.pyc create mode 100644 jupyter-openbis-extension/server.py diff --git a/jupyter-openbis-extension/.server.py.swp b/jupyter-openbis-extension/.server.py.swp new file mode 100644 index 0000000000000000000000000000000000000000..c294c69447df13190139740612a621e8cc044143 GIT binary patch literal 28672 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 literal 0 HcmV?d00001 diff --git a/jupyter-openbis-extension/__init__.py b/jupyter-openbis-extension/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/jupyter-openbis-extension/__pycache__/__init__.cpython-36.pyc b/jupyter-openbis-extension/__pycache__/__init__.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..17c85d6c830fc23516d571d3b9fbc90fd636a634 GIT binary patch literal 161 zcmXr!<>jhByCs?d2p)q77+?f49Dul(1xTbY1T$zd`mJOr0tq9CUw-<b#i>Qb`ems_ zxv8Z&`dOs~l_jY~y7>jEc}bbYx~UZ<sd>ej`FVI`;^Q;(GE3s)^$IF)aoFVMr<CTT L+JWpT24V&PvAQeO literal 0 HcmV?d00001 diff --git a/jupyter-openbis-extension/__pycache__/extension.cpython-36.pyc b/jupyter-openbis-extension/__pycache__/extension.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d5f03417cffd6d3922495cb9dca6bf4efab96353 GIT binary patch literal 2057 zcmaJ?Uys{F5Z_(@iO+Fz=~Yxvpje_p<fJ+hyr2`RPHHQtkgk>5!pS^XPIm9&)Un;& zHP^TaFR6Ir1@YJ~z&qkI@C}gmm8X6Mo|xS@cjZrOYuB^0GqW?ZzZrkp>-pV3e*JdU zLFiBP%3}k42t)h?6Gar~XpUoyHBE9dw_?lCR&LLo*ujW7)TYjlIChyk>rj_=*2GA7 zxfgq&<>fo^j`{kr58s`<I}hT($oP40-jDn9-FO$)T^c+`@qqSdAHJ8qKy;T5o+CP7 z*4m2qsP_O3FTDi6&=9L$&GV#6<usX<Spkgx-TMnUEsHPHg650^r*p4j#W)kqwW*Yq zI2esY#j`@*C^!6w$!QZ!rXXs8wYc*g<8xN$&ETtAN|w`<Qkd&cq9YIqCQ~+foRqb! zYB?mz0~Jx_nN&Vdbz$g<_HO$SAa21BK1>u-lHpSfF<3{+otL!ES@Yqnt`?H<txGr9 zQ^^XEl|^(;{erkQa54RLZ}dnoE=H}tqt_aF!_K++s9LBGlGa25cEM_LzH3q}c6Agw z9E5oQ^8{-e9t{^gOqe%;SfUwPVTxBo;w7FDO5Q=#T9cIpD{D!Xmb6dEDb^s70G*jD zJ8Qhw0CONUZZp4?=6QHFWko2bEIfB4%tV-%DP=VB{ScmmD&^@sEXG@()2ccMH@6?k z(r6!*l8wvqad^hYo5;ef5Hc+$EHXwKE84#vd*f8F1a7ezj9P4rXexmzn?bbz2(?Ea zgwIw-Lr-<UUIOQFos-xDIhhrwA`SpC$#eriq58MM#sel>L@LLiPq`;0pQn=RybbNR z_m2p8Pg@M8rI0%H0F5H<aR43LE-!GvyCAFH*I9Y({apqTgFocB*d_zKhxsMo{RgOr zTJUX{7>Y4PF`+oND4`aVqD^hM8;AE{ySa9|JS+5>Cc~UPshN<BhHbFt&~QQcT^I%$ zzX744u?BD~`VxS#giBwMZ&0ysBWXSM`5{L71u0wC%FNLc)OtY-IKY8pv<Q}D=7J3i z^gaW<4(R=W(aOfCd9T%UwC2)YgX<T%)Lz-&+sCLN$4Gj!oteJ`FwVLFOvmWCdPO^+ z>%ghr3u}AoaHqN2f+`Jb08x1V(ZjF}JIa2BN`RDXE*j7gPRcr`VNuF(%)*nhE@%YJ z!UfRDS}1?>eF(5VYCd|M8f`Pos0Q52-*wvex58(s2t_@aFd<IrJYR$t(i-;9R?*Pn zd!VA+3i{by$~6XtLEJlKGMS08NX8{yC|t%}&7m8hEC1^>uh|{WORk(Vo&od*pa?y@ z^+xU7c{*X0gyy73DU_|dud;Rf<!|XDTxAQEpO^*UN2o3ZXk<ldR50Tj4*!O)1>N*I z@Wsb4A<H8K_u;h(Ap_#VD!>D?+Jp6g03TM(UYm`!v?4HaG<1}gBt<%BNuvBD*|b=o zgCu!Ur+K^6NfKI4l7xqF-Yedi9;++Lz+7(%U7;SfEyEdJj{9(}rk_N$%yO}*{wwE9 z-9@5p^>Yi9W5;w4Q|kN*FqD&*r&$46gL~jtHOGa%lV@XqMm?^0sqdBR+EKw~BZ58$ tu!A2p;+~##12#2m-1@%=l=t~2_?x;<o2m{Vj{)&vcv!!XRm-!z-rwt0ESLZQ literal 0 HcmV?d00001 diff --git a/jupyter-openbis-extension/__pycache__/server.cpython-36.pyc b/jupyter-openbis-extension/__pycache__/server.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0a1e17fe0c786f4007391b5c58e6c6c99190b531 GIT binary patch literal 6373 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 literal 0 HcmV?d00001 diff --git a/jupyter-openbis-extension/server.py b/jupyter-openbis-extension/server.py new file mode 100644 index 0000000..8a6781c --- /dev/null +++ b/jupyter-openbis-extension/server.py @@ -0,0 +1,238 @@ +from notebook.utils import url_path_join +from notebook.base.handlers import IPythonHandler +from pybis import Openbis + +import json +import os +import urllib +from subprocess import check_output +from urllib.parse import urlsplit, urlunsplit +import yaml + +openbis_connections = {} + + +def _jupyter_server_extension_paths(): + return [{'module': 'jupyter-openbis-extension.server'}] + +def _load_configuration(filename='openbis-connections.yaml'): + + home = os.path.expanduser("~") + abs_filename = os.path.join(home, '.jupyter', filename) + + with open(abs_filename, 'r') as stream: + try: + config = yaml.safe_load(stream) + return config + except yaml.YAMLexception as exc: + print(exc) + return None + + +def load_jupyter_server_extension(nb_server_app): + """Call when the extension is loaded. + :param nb_server_app: Handle to the Notebook webserver instance. + """ + + # load the configuration file + config = _load_configuration() + if config is not None: + for conn in config['connections']: + try: + register_connection(conn) + except Exception as exc: + print(exc) + + + web_app = nb_server_app.web_app + host_pattern = '.*$' + + base_url = web_app.settings['base_url'] + + web_app.add_handlers( + host_pattern, + [(url_path_join( + base_url, + '/openbis/dataset/(?P<connection_name>.*)?/(?P<permId>.*)'), + DataSetHandler + )] + ) + web_app.add_handlers( + host_pattern, + [(url_path_join( + base_url, + '/openbis/sample/(?P<connection_name>.*)?/(?P<permId>.*)'), + SampleHandler + )] + ) + web_app.add_handlers( + host_pattern, + [(url_path_join(base_url, '/openbis/conn'), OpenBISHandler)] + ) + + + print("pybis loaded: {}".format(Openbis)) + + +def register_connection(connection_info): + + conn = OpenBISConnection( + name = connection_info['name'], + url = connection_info['url'], + verify_certificates = connection_info['verify_certificates'], + username = connection_info['username'], + password = connection_info['password'], + status = 'not connected', + ) + openbis_connections[conn.name] = conn + + openbis = Openbis( + url = conn.url, + verify_certificates = conn.verify_certificates + ) + conn.openbis = openbis + + try: + openbis.login( + username = conn.username, + password = conn.password + ) + conn.status = 'connected' + except Exception as exc: + conn.status = 'FAILED: {}'.format(exc) + raise exc + + +def check_connection(connection_name): + """Checks whether connection is valid and session is still active + and tries to reconnect, if possible. Returns the active session + """ + + if connection_name not in openbis_connections: + return None + + conn = openbis_connections[connection_name] + if not conn.openbis.isSessionActive(): + conn.openbis.login(conn.username, conn.password) + + +class OpenBISConnection: + """register an openBIS connection + """ + + def __init__(self, **kwargs): + for key in kwargs: + setattr(self, key, kwargs[key]) + + def is_session_active(self): + return self.openbis.is_session_active() + + def reconnect(self): + openbis.login(self.username, self.password) + + +class OpenBISHandler(IPythonHandler): + """Handle the requests to /openbis/conn + """ + + def get(self): + """returns all available openBIS connections + """ + connections= [] + for conn in openbis_connections.values(): + connections.append({ + 'name': conn.name, + 'url' : conn.url + }) + + self.write({ + 'connections': connections + }) + return + +class SampleHandler(IPythonHandler): + """Handle the requests for /openbis/sample/connection/permId""" + + def get_datasets(self, conn, permId): + sample = None + try: + sample = conn.openbis.get_sample(permId) + except Exception: + self.send_error( + reason = 'No such sample found: {}'.format(permId) + ) + return + + datasets = sample.get_datasets().df + dataset_records = datasets.to_dict(orient='records') + self.write({'dataSets': dataset_records }) + return + + def get(self, **params): + """Handle a request to /openbis/sample/connection_name/permId + download the data and return a message + """ + try: + conn = openbis_connections[params['connection_name']] + except KeyError: + self.send_error( + reason = 'connection {} was not found'.format(params['connection_name']) + ) + return + + results = self.get_datasets(conn, params['permId']) + + +class DataSetHandler(IPythonHandler): + """Handle the requests for /openbis/dataset/connection/permId""" + + + def download_data(self, conn, permId): + if not conn.is_session_active(): + try: + conn.reconnect() + except Exception as exc: + self.send_error( + reason = 'connection to {} could not be established: {}'.format(conn.name, exc) + ) + return + + try: + dataset = conn.openbis.get_dataset(permId) + except Exception as exc: + self.send_error( + reason = 'No such dataSet found: {}'.format(permId) + ) + return + + # dataset was found, download the data to the disk + try: + destination = dataset.download() + except Exception as exc: + print(exc) + self.send_error( + reason = 'Data for DataSet {} could not be downloaded: {}'.format(permId, exc) + ) + return + + # return success message + path = os.path.join(destination, dataset.permId) + self.write({ + 'permId' : dataset.permId, + 'statusText': 'Data for DataSet {} was successfully downloaded to {}.'.format(dataset.permId, path) + }) + + def get(self, **params): + """Handle a request to /openbis/dataset/connection_name/permId + download the data and return a message + """ + try: + conn = openbis_connections[params['connection_name']] + except KeyError: + self.send_error( + reason = 'connection {} was not found'.format(params['connection_name']) + ) + return + + results = self.download_data(conn, params['permId']) + -- GitLab