mirror of
https://github.com/galaxyproject/galaxy.git
synced 2026-09-24 16:30:27 +08:00
Merge pull request #1400 from bgruening/jupyter
Add Jupyter Interactive Environment
This commit is contained in:
@@ -0,0 +1,43 @@
|
||||
[main]
|
||||
# Following options are ignored if using the Galaxy dynamic proxy but
|
||||
# are useful if mapping a range of ports for environment consumption.
|
||||
#password_auth = False
|
||||
#ssl = False
|
||||
|
||||
[docker]
|
||||
# Command to launch docker container. For example `sudo docker` or `docker-lxc`.
|
||||
# If you need to use a command like `sg` you can do that here, just be sure to
|
||||
# wrap all of the docker portion in single quotes. E.g. `sg 'docker' 'docker {docker_args}'`
|
||||
#
|
||||
# It is recommended that you use command_inject if you need to inject
|
||||
# additional parameters. This command string is re-used for a `docker inspect`
|
||||
# command and will likely cause errors if it is extensively modified, past the
|
||||
# usual group/sudo changes.
|
||||
#command = docker {docker_args}
|
||||
|
||||
# The docker image name that should be started.
|
||||
image = bgruening/docker-jupyter-notebook:16.01
|
||||
|
||||
# Additional arguments that are passed to the `docker run` command.
|
||||
command_inject = --sig-proxy=true -e DEBUG=false -e DEFAULT_CONTAINER_RUNTIME=120
|
||||
|
||||
# URL to access the Galaxy API with from the spawn Docker containter, if empty
|
||||
# this falls back to galaxy.ini's galaxy_infrastructure_url and finally to the
|
||||
# Docker host of the spawned container if that is also not set.
|
||||
#galaxy_url =
|
||||
|
||||
# The Docker hostname. It can be useful to run the Docker daemon on a different
|
||||
# host than Galaxy.
|
||||
#docker_hostname = localhost
|
||||
|
||||
# Try to set the tempdirectory to world execute - this can fix the issue
|
||||
# where 'sudo docker' is not able to mount the folder otherwise.
|
||||
# "finalize namespace chdir to /import permission denied"
|
||||
#wx_tempdir = False
|
||||
|
||||
# Overwride the IE tempdirectory. This can be useful if you regular tempdir is
|
||||
# located on an NFS share, which does not work well as Docker volume. In this case
|
||||
# you can have a shared sshfs share which you can use as temporary directory to
|
||||
# share data between the IE and Galaxy.
|
||||
#docker_galaxy_temp_dir = None
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE interactive_environment SYSTEM "../../interactive_environments.dtd">
|
||||
<interactive_environment name="Jupyter (Programming Environment)">
|
||||
<data_sources>
|
||||
<data_source>
|
||||
<model_class>HistoryDatasetAssociation</model_class>
|
||||
<test type="isinstance" test_attr="datatype" result_type="datatype">tabular.Tabular</test>
|
||||
<test type="isinstance" test_attr="datatype" result_type="datatype">data.Text</test>
|
||||
<to_param param_attr="id">dataset_id</to_param>
|
||||
</data_source>
|
||||
</data_sources>
|
||||
<params>
|
||||
<param type="dataset" var_name_in_template="hda" required="true">dataset_id</param>
|
||||
</params>
|
||||
<entry_point entry_point_type="mako">jupyter.mako</entry_point>
|
||||
</interactive_environment>
|
||||
@@ -0,0 +1,123 @@
|
||||
function message_failed_auth(password){
|
||||
toastr.info(
|
||||
"Automatic authorization failed. You can manually login with:<br>" + password + "<br> <a href='https://github.com/bgruening/galaxy-ipython/wiki/Automatic-Authorization-Failed' target='_blank'>More details ...</a>",
|
||||
"Please login manually",
|
||||
{'closeButton': true, 'timeOut': 100000, 'tapToDismiss': false}
|
||||
);
|
||||
}
|
||||
|
||||
function message_failed_connection(){
|
||||
toastr.error(
|
||||
"Could not connect to Jupyter Notebook. Please contact your administrator. <a href='https://github.com/bgruening/galaxy-ipython/wiki/Could-not-connect-to-IPython-Notebook' target='_blank'>More details ...</a>",
|
||||
"Security warning",
|
||||
{'closeButton': true, 'timeOut': 20000, 'tapToDismiss': true}
|
||||
);
|
||||
}
|
||||
|
||||
function message_no_auth(){
|
||||
// No longer a security issue, proxy validates Galaxy session token.
|
||||
/*
|
||||
toastr.warning(
|
||||
"IPython Notebook was lunched without authentication. This is a security issue. <a href='https://github.com/bgruening/galaxy-ipython/wiki/IPython-Notebook-was-lunched-without-authentication' target='_blank'>More details ...</a>",
|
||||
"Security warning",
|
||||
{'closeButton': true, 'timeOut': 20000, 'tapToDismiss': false}
|
||||
);
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Load an interactive environment (IE) from a remote URL
|
||||
* @param {String} password: password used to authenticate to the remote resource
|
||||
* @param {String} notebook_login_url: URL that should be POSTed to for login
|
||||
* @param {String} notebook_access_url: the URL embeded in the page and loaded
|
||||
*
|
||||
*/
|
||||
function load_notebook(password, notebook_login_url, notebook_access_url){
|
||||
$( document ).ready(function() {
|
||||
// Test notebook_login_url for accessibility, executing the login+load function whenever
|
||||
// we've successfully connected to the IE.
|
||||
test_ie_availability(notebook_login_url, function(){
|
||||
_handle_notebook_loading(password, notebook_login_url, notebook_access_url);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function keep_alive(){
|
||||
/**
|
||||
* This is needed to keep the container alive. If the user leaves this site
|
||||
* this function is not constantly pinging the container, the container will
|
||||
* terminate itself.
|
||||
*/
|
||||
|
||||
var request_count = 0;
|
||||
interval = setInterval(function(){
|
||||
$.ajax({
|
||||
url: notebook_access_url,
|
||||
xhrFields: {
|
||||
withCredentials: true
|
||||
},
|
||||
type: "GET",
|
||||
timeout: 500,
|
||||
success: function(){
|
||||
console.log("Connected to IE, returning");
|
||||
},
|
||||
error: function(jqxhr, status, error){
|
||||
request_count++;
|
||||
console.log("Request " + request_count);
|
||||
if(request_count > 30){
|
||||
clearInterval(interval);
|
||||
clear_main_area();
|
||||
toastr.error(
|
||||
"Could not connect to IE, contact your administrator",
|
||||
"Error",
|
||||
{'closeButton': true, 'timeOut': 20000, 'tapToDismiss': false}
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
}, 30000);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Must be implemented by IEs
|
||||
*/
|
||||
function _handle_notebook_loading(password, notebook_login_url, notebook_access_url){
|
||||
if ( ie_password_auth ) {
|
||||
// Make an AJAX POST
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
// to the Login URL
|
||||
url: notebook_login_url,
|
||||
// With our password
|
||||
data: {
|
||||
'password': password
|
||||
},
|
||||
xhrFields: {
|
||||
withCredentials: true
|
||||
},
|
||||
// If that is successful, load the notebook
|
||||
success: function(){
|
||||
append_notebook(notebook_access_url);
|
||||
},
|
||||
error: function(jqxhr, status, error){
|
||||
if(ie_password_auth){
|
||||
// Failure happens due to CORS
|
||||
message_failed_auth(password);
|
||||
append_notebook(notebook_access_url);
|
||||
}else{
|
||||
message_failed_connection();
|
||||
// Do we want to try and load the notebook anyway? Just in case?
|
||||
append_notebook(notebook_access_url);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
// Not using password auth, just embed it to avoid content-origin issues.
|
||||
message_no_auth();
|
||||
append_notebook(notebook_access_url);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
<%namespace name="ie" file="ie.mako" />
|
||||
|
||||
<%
|
||||
import os
|
||||
import shutil
|
||||
import hashlib
|
||||
|
||||
# Sets ID and sets up a lot of other variables
|
||||
ie_request.load_deploy_config()
|
||||
ie_request.attr.docker_port = 8888
|
||||
ie_request.attr.import_volume = False
|
||||
|
||||
if ie_request.attr.PASSWORD_AUTH:
|
||||
m = hashlib.sha1()
|
||||
m.update( ie_request.notebook_pw + ie_request.notebook_pw_salt )
|
||||
PASSWORD = 'sha1:%s:%s' % (ie_request.notebook_pw_salt, m.hexdigest())
|
||||
else:
|
||||
PASSWORD = "none"
|
||||
|
||||
## Jupyter Notbook Specific
|
||||
if hda.datatype.__class__.__name__ == "Ipynb":
|
||||
DATASET_HID = hda.hid
|
||||
else:
|
||||
DATASET_HID = None
|
||||
|
||||
# Add all environment variables collected from Galaxy's IE infrastructure
|
||||
ie_request.launch(env_override={
|
||||
'notebook_password': PASSWORD,
|
||||
'dataset_hid': DATASET_HID,
|
||||
})
|
||||
|
||||
## General IE specific
|
||||
# Access URLs for the notebook from within galaxy.
|
||||
notebook_access_url = ie_request.url_template('${PROXY_URL}/ipython/notebooks/ipython_galaxy_notebook.ipynb')
|
||||
notebook_login_url = ie_request.url_template('${PROXY_URL}/ipython/login?next=${PROXY_PREFIX}%2Fipython%2Ftree')
|
||||
|
||||
%>
|
||||
<html>
|
||||
<head>
|
||||
${ ie.load_default_js() }
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<script type="text/javascript">
|
||||
${ ie.default_javascript_variables() }
|
||||
var notebook_login_url = '${ notebook_login_url }';
|
||||
var notebook_access_url = '${ notebook_access_url }';
|
||||
${ ie.plugin_require_config() }
|
||||
|
||||
// Keep container running
|
||||
requirejs(['interactive_environments', 'plugin/jupyter'], function(){
|
||||
keep_alive();
|
||||
});
|
||||
|
||||
|
||||
// Load notebook
|
||||
|
||||
requirejs(['interactive_environments', 'plugin/jupyter'], function(){
|
||||
load_notebook(ie_password, notebook_login_url, notebook_access_url);
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</script>
|
||||
<div id="main" width="100%" height="100%">
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user