kopia lustrzana https://github.com/jupyterhub/repo2docker
Merge branch 'master' of github.com:jupyter/repo2docker into feature/launch_script
commit
da0ed1eee0
|
@ -9,6 +9,7 @@ MANIFEST
|
|||
|
||||
.DS_Store
|
||||
.cache
|
||||
.pytest_cache
|
||||
.coverage
|
||||
htmlcov
|
||||
|
||||
|
|
16
.travis.yml
16
.travis.yml
|
@ -15,9 +15,17 @@ install:
|
|||
script:
|
||||
# cd into tests so CWD being repo2docker does not hide
|
||||
# possible issues with MANIFEST.in
|
||||
- if [ ${REPO_TYPE} == "r" ]; then cd tests && travis_wait pytest --cov repo2docker
|
||||
-v ${REPO_TYPE}; else cd tests && travis_retry pytest --cov repo2docker -v ${REPO_TYPE};
|
||||
fi
|
||||
- pushd tests;
|
||||
if [ ${REPO_TYPE} == "r" ]; then
|
||||
travis_wait pytest --cov repo2docker -v ${REPO_TYPE};
|
||||
else
|
||||
travis_retry pytest --cov repo2docker -v ${REPO_TYPE};
|
||||
fi;
|
||||
popd;
|
||||
- pip install -r docs/doc-requirements.txt
|
||||
- pushd docs;
|
||||
make html;
|
||||
popd;
|
||||
after_success:
|
||||
- pip install codecov
|
||||
- codecov
|
||||
|
@ -35,8 +43,10 @@ jobs:
|
|||
branch: master
|
||||
env:
|
||||
matrix:
|
||||
- REPO_TYPE=base
|
||||
- REPO_TYPE=conda
|
||||
- REPO_TYPE=venv
|
||||
- REPO_TYPE=stencila
|
||||
- REPO_TYPE=julia
|
||||
- REPO_TYPE=r
|
||||
- REPO_TYPE=dockerfile
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
#
|
||||
|
||||
# You can set these variables from the command line.
|
||||
SPHINXOPTS =
|
||||
SPHINXOPTS = -W
|
||||
SPHINXBUILD = python3 -msphinx
|
||||
SPHINXPROJ = repo2docker
|
||||
SOURCEDIR = source
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
.. NOTE: the header characters are different in this file because it is 'included' in another site
|
||||
.. see https://raw.githubusercontent.com/jupyterhub/binder/master/doc/using.rst
|
||||
.. _config-files:
|
||||
|
||||
Configuration Files
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
-------------------
|
||||
|
||||
``repo2docker`` looks for configuration files in the repository being built
|
||||
to determine how to build it. In general, ``repo2docker`` uses the same
|
||||
|
@ -31,7 +33,7 @@ Below is a list of supported configuration files (roughly in the order of build
|
|||
:depth: 1
|
||||
|
||||
``Dockerfile``
|
||||
^^^^^^^^^^^^^^
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
In the majority of cases, providing your own Dockerfile is not necessary as the base
|
||||
images provide core functionality, compact image sizes, and efficient builds. We recommend
|
||||
|
@ -46,7 +48,7 @@ best-practices with Dockerfiles.
|
|||
.. _environment-yml:
|
||||
|
||||
``environment.yml``
|
||||
^^^^^^^^^^^^^^^^^^^
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
``environment.yml`` is the standard configuration file used by Anaconda, conda,
|
||||
and miniconda that lets you install Python packages.
|
||||
|
@ -63,7 +65,7 @@ a Python version in a ``runtime.txt`` file in addition to your
|
|||
``environment.yml``, your ``runtime.txt`` **will be ignored**.
|
||||
|
||||
``requirements.txt``
|
||||
^^^^^^^^^^^^^^^^^^^^
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
This specifies a list of Python packages that should be installed in your
|
||||
environment. Our
|
||||
|
@ -71,7 +73,7 @@ environment. Our
|
|||
on GitHub shows a typical requirements file.
|
||||
|
||||
``REQUIRE``
|
||||
^^^^^^^^^^^
|
||||
~~~~~~~~~~~
|
||||
|
||||
This specifies a list of Julia packages. Repositories with a ``REQUIRE`` file
|
||||
**must also contain an** ``environment.yml`` **file**. To see an example of a
|
||||
|
@ -79,7 +81,7 @@ Julia repository with ``REQUIRE`` and ``environment.yml``,
|
|||
visit `binder-examples/julia-python <https://github.com/binder-examples/julia-python>`_.
|
||||
|
||||
``install.R``
|
||||
^^^^^^^^^^^^^
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
This is used to install R libraries pinned to a specific snapshot on
|
||||
`MRAN <https://mran.microsoft.com/documents/rro/reproducibility>`_.
|
||||
|
@ -87,7 +89,7 @@ To set the date of the snapshot add a runtime.txt_.
|
|||
For an example ``install.R`` file, visit our `example install.R file <https://github.com/binder-examples/r/blob/master/install.R>`_.
|
||||
|
||||
``apt.txt``
|
||||
^^^^^^^^^^^
|
||||
~~~~~~~~~~~
|
||||
|
||||
A list of Debian packages that should be installed. The base image used is usually the latest released
|
||||
version of Ubuntu.
|
||||
|
@ -97,7 +99,7 @@ We use ``apt.txt``, for example, to install LaTeX in our
|
|||
|
||||
|
||||
``setup.py``
|
||||
^^^^^^^^^^^^
|
||||
~~~~~~~~~~~~
|
||||
|
||||
To install your repository like a Python package, you may include a
|
||||
``setup.py`` file. repo2docker installs ``setup.py`` files by running
|
||||
|
@ -110,7 +112,7 @@ repo2docker **requires configuration files such as** ``environment.yml`` or
|
|||
.. _postBuild:
|
||||
|
||||
``postBuild``
|
||||
^^^^^^^^^^^^^
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
A script that can contain arbitrary commands to be run after the whole repository has been built. If you
|
||||
want this to be a shell script, make sure the first line is ```#!/bin/bash``.
|
||||
|
@ -136,7 +138,7 @@ equivalent.
|
|||
.. _runtime.txt:
|
||||
|
||||
``runtime.txt``
|
||||
^^^^^^^^^^^^^^^
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
This allows you to control the runtime of Python or R.
|
||||
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
.. _usage:
|
||||
.. _deploy:
|
||||
|
||||
Using ``repo2docker`` as part of your Continuous Integration
|
||||
============================================================
|
||||
|
||||
We've created for you the `continuous-build <https://www.github.com/binder-examples/continuous-build/>`_
|
||||
repository so that you can push a `Docker <https://docs.docker.com/>`_ container
|
||||
We've created for you the `continuous-build <https://www.github.com/binder-examples/continuous-build/>`_
|
||||
repository so that you can push a `Docker <https://docs.docker.com/>`_ container
|
||||
to `Docker Hub <https://hub.docker.com/>`_ directly from a Github repository
|
||||
that has a Jupyter notebook. Here are instructions to do this.
|
||||
|
||||
|
@ -25,7 +25,7 @@ to pull from Docker Hub.
|
|||
Step 1. Clone the Repository
|
||||
............................
|
||||
First, fork the `continuous-build <https://www.github.com/binder-examples/continuous-build/>`_ Github
|
||||
repository to your account, and clone the branch.
|
||||
repository to your account, and clone the branch.
|
||||
|
||||
git clone https://www.github.com/<username>/continuous-build
|
||||
# or
|
||||
|
@ -35,9 +35,9 @@ repository to your account, and clone the branch.
|
|||
Step 2. Choose your Configuration
|
||||
.................................
|
||||
|
||||
The hidden folder `.circleci/config.yml` has instructions for `CircleCI <https://circleci.com/dashboard/>`_
|
||||
The hidden folder `.circleci/config.yml` has instructions for `CircleCI <https://circleci.com/dashboard/>`_
|
||||
to automatically discover and build your repo2docker jupyter notebook container.
|
||||
The default template provided in the repository in this folder will do the most basic steps,
|
||||
The default template provided in the repository in this folder will do the most basic steps,
|
||||
including:
|
||||
|
||||
1. clone of the repository with the notebook that you specify
|
||||
|
@ -45,7 +45,7 @@ including:
|
|||
3. push to Docker Hub
|
||||
|
||||
This repository aims to provide templates for your use.
|
||||
If you have a request for a new template, please
|
||||
If you have a request for a new template, please
|
||||
`let us know <https://www.github.com/binder-examples/continuous-build/issues/>`_.
|
||||
We will add templates as they are requested to do additional tasks like test containers, run
|
||||
nbconvert, etc.
|
||||
|
@ -57,7 +57,7 @@ creating a new folder called "myrepo" and then copying the entire folder there.
|
|||
mkdir -p myrepo
|
||||
cp -R continuous-build/.circleci myrepo/
|
||||
|
||||
You would then logically create a Github repository in the "myrepo" folder,
|
||||
You would then logically create a Github repository in the "myrepo" folder,
|
||||
add the circleci configuration folder, and continue on to the next steps.
|
||||
|
||||
cd myrepo
|
||||
|
@ -69,7 +69,7 @@ Step 3. Docker Hub
|
|||
..................
|
||||
Go to `Docker Hub <https://hub.docker.com/>`_, log in, and click the big blue
|
||||
button that says "create repository" (not an automated build). Choose an organization
|
||||
and name that you like (in the traditional format ``<ORG>/<NAME>``), and
|
||||
and name that you like (in the traditional format ``<ORG>/<NAME>``), and
|
||||
remember it! We will be adding it, along with your
|
||||
Docker credentials, to be encrypted CircleCI environment variables.
|
||||
|
||||
|
@ -78,12 +78,12 @@ Step 4. Connect to CircleCI
|
|||
...........................
|
||||
If you navigate to the main `app page <https://circleci.com/dashboard/>`_ you
|
||||
should be able to click "Add Projects" and then select your repository. If you don't
|
||||
see it on the list, then select a different organization in the top left. Once
|
||||
see it on the list, then select a different organization in the top left. Once
|
||||
you find the repository, you can click the button to "Start Building" adn accept
|
||||
the defaults.
|
||||
|
||||
Before you push or trigger a build, let's set up the following environment variables.
|
||||
Also in the project interface on CirleCi, click the gears icon next to the project
|
||||
Also in the project interface on CirleCi, click the gears icon next to the project
|
||||
name to get to your project settings. Under settings, click on the "Environment
|
||||
Variables" tab. In this section, you want to define the following:
|
||||
|
||||
|
@ -92,7 +92,7 @@ Variables" tab. In this section, you want to define the following:
|
|||
3. ``DOCKER_USER`` and ``DOCKER_PASS`` should be your credentials (to allowing pushing)
|
||||
4. ``REPO_NAME`` should be the full Github url (or other) of the repository with the notebook. This doesn't have to coincide with the repository you are using to do the build (e.g., "myrepo" in our example).
|
||||
|
||||
If you don't define the ``CONTAINER_NAME`` it will default to be the repository where it is
|
||||
If you don't define the ``CONTAINER_NAME`` it will default to be the repository where it is
|
||||
building from, which you should only do if the Docker Hub repository is named equivalently.
|
||||
If you don't define either of the variables from step 3. for the Docker credentials, your
|
||||
image will build but not be pushed to Docker Hub. Finally, if you don't define the ``REPO_NAME``
|
||||
|
@ -120,7 +120,7 @@ You should then be able to pull your new container, and run it! Here is an examp
|
|||
|
||||
docker pull <ORG>/<NAME>
|
||||
docker run -it --name repo2docker -p 8888:8888 <ORG>/<NAME> jupyter notebook --ip 0.0.0.0
|
||||
|
||||
|
||||
|
||||
For a pre-built working example, try the following:
|
||||
|
||||
|
|
|
@ -57,19 +57,19 @@ Bash on Windows) provides additional information about Windows and docker.
|
|||
|
||||
.. _using Windows and the WSL: https://nickjanetakis.com/blog/setting-up-docker-for-windows-and-wsl-to-work-flawlessly
|
||||
|
||||
.. _jupyterhub:
|
||||
.. _jupyterhub_ready:
|
||||
|
||||
JupyterHub-ready images
|
||||
-----------------------
|
||||
|
||||
`JupyterHub <https://jupyterhub.readthedocs.io/en/stable/>`_ allows multiple
|
||||
JupyterHub_ allows multiple
|
||||
users to collaborate on a shared Jupyter server. ``repo2docker`` can build
|
||||
Docker images that can be shared within a JupyterHub deployment. For example,
|
||||
`mybinder.org <https://mybinder.org>`_ uses JupyterHub and ``repo2docker``
|
||||
to allow anyone to build a Docker image of a git repository online and
|
||||
share an executable version of the repository with a URL to the built image.
|
||||
|
||||
To build `JupyterHub <https://github.com/jupyterhub/jupyterhub>`_-ready
|
||||
To build JupyterHub_-ready
|
||||
Docker images with ``repo2docker``, the version of your JupterHub deployment
|
||||
must be included in the ``environment.yml`` or ``requiements.txt`` of the
|
||||
git repositories you build.
|
||||
|
@ -79,3 +79,5 @@ command to run ``jupyterhub-singleuser`` by adding this line in your
|
|||
configuration file::
|
||||
|
||||
c.DockerSpawner.cmd = ['jupyterhub-singleuser']
|
||||
|
||||
.. _JupyterHub: https://github.com/jupyterhub/jupyterhub
|
||||
|
|
|
@ -21,7 +21,7 @@ repo2docker is called with this command::
|
|||
where ``<URL-or-path to repo>`` is a URL or path to the source repository.
|
||||
|
||||
For example, use the following to build an image of Peter Norvig's
|
||||
`Pytudes <https://github.com/norvig/pytudes/>`_::
|
||||
Pytudes_::
|
||||
|
||||
jupyter-repo2docker https://github.com/norvig/pytudes
|
||||
|
||||
|
@ -47,12 +47,14 @@ Python 3.6 unless you include the version of Python in your
|
|||
Python 2.7, 3.5, and 3.6. In the case of this repo, a Python version is not
|
||||
specified in their configuation files and Python 3.6 is installed.
|
||||
|
||||
`Pytudes <https://github.com/norvig/pytudes>`_
|
||||
Pytudes_
|
||||
uses a `requirements.txt file <https://github.com/norvig/pytudes/blob/master/requirements.txt>`_
|
||||
to specify its Python environment. ``repo2docker`` uses ``pip`` to install
|
||||
dependencies listed in the ``requirement.txt`` in the image. To learn more about
|
||||
configuration files in ``repo2docker`` visit :ref:`config-files`.
|
||||
|
||||
.. _Pytudes: https://github.com/norvig/pytudes
|
||||
|
||||
When the image is built, a message will be output to your terminal::
|
||||
|
||||
Copy/paste this URL into your browser when you connect for the first time,
|
||||
|
|
|
@ -18,6 +18,7 @@ import tempfile
|
|||
import time
|
||||
|
||||
import docker
|
||||
from urllib.parse import urlparse
|
||||
from docker.utils import kwargs_from_env
|
||||
from docker.errors import DockerException
|
||||
import escapism
|
||||
|
@ -520,11 +521,26 @@ class Repo2Docker(Application):
|
|||
Returns running container
|
||||
"""
|
||||
client = docker.from_env(version='auto')
|
||||
|
||||
docker_host = os.environ.get('DOCKER_HOST')
|
||||
if docker_host:
|
||||
host_name = urlparse(docker_host).hostname
|
||||
else:
|
||||
host_name = '127.0.0.1'
|
||||
self.hostname = host_name
|
||||
|
||||
if not self.run_cmd:
|
||||
port = str(self._get_free_port())
|
||||
self.port = port
|
||||
run_cmd = ['jupyter', 'notebook', '--ip', '0.0.0.0',
|
||||
'--port', port]
|
||||
# To use the option --NotebookApp.custom_display_url
|
||||
# make sure the base-notebook image is updated:
|
||||
# docker pull jupyter/base-notebook
|
||||
run_cmd = [
|
||||
'jupyter', 'notebook',
|
||||
'--ip', '0.0.0.0',
|
||||
'--port', port,
|
||||
"--NotebookApp.custom_display_url=http://{}:{}".format(host_name, port),
|
||||
]
|
||||
ports = {'%s/tcp' % port: port}
|
||||
else:
|
||||
# run_cmd given by user, if port is also given then pass it on
|
||||
|
@ -535,6 +551,7 @@ class Repo2Docker(Application):
|
|||
ports = {}
|
||||
# store ports on self so they can be retrieved in tests
|
||||
self.ports = ports
|
||||
|
||||
container_volumes = {}
|
||||
if self.volumes:
|
||||
api_client = docker.APIClient(
|
||||
|
|
|
@ -43,6 +43,11 @@ RUN adduser --disabled-password \
|
|||
${NB_USER}
|
||||
WORKDIR ${HOME}
|
||||
|
||||
RUN wget --quiet -O - https://deb.nodesource.com/gpgkey/nodesource.gpg.key | apt-key add - && \
|
||||
DISTRO="bionic" && \
|
||||
echo "deb https://deb.nodesource.com/node_10.x $DISTRO main" >> /etc/apt/sources.list.d/nodesource.list && \
|
||||
echo "deb-src https://deb.nodesource.com/node_10.x $DISTRO main" >> /etc/apt/sources.list.d/nodesource.list
|
||||
|
||||
RUN apt-get update && \
|
||||
apt-get install --yes --no-install-recommends \
|
||||
{% for package in base_packages -%}
|
||||
|
@ -65,9 +70,9 @@ RUN apt-get update && \
|
|||
|
||||
EXPOSE 8888
|
||||
|
||||
{% if env -%}
|
||||
# Almost all environment variables
|
||||
{% for item in env -%}
|
||||
{% if build_env -%}
|
||||
# Environment variables required for build
|
||||
{% for item in build_env -%}
|
||||
ENV {{item[0]}} {{item[1]}}
|
||||
{% endfor -%}
|
||||
{% endif -%}
|
||||
|
@ -94,6 +99,14 @@ USER root
|
|||
COPY src/ ${HOME}
|
||||
RUN chown -R ${NB_USER}:${NB_USER} ${HOME}
|
||||
|
||||
{% if env -%}
|
||||
# The rest of the environment
|
||||
{% for item in env -%}
|
||||
ENV {{item[0]}} {{item[1]}}
|
||||
{% endfor -%}
|
||||
{% endif -%}
|
||||
|
||||
|
||||
# Run assemble scripts! These will actually build the specification
|
||||
# in the repository into the image.
|
||||
{% for sd in assemble_script_directives -%}
|
||||
|
@ -186,14 +199,25 @@ class BuildPack:
|
|||
return {
|
||||
# Utils!
|
||||
"less",
|
||||
|
||||
# FIXME: Use npm from nodesource!
|
||||
# Everything seems to depend on npm these days, unfortunately.
|
||||
"npm",
|
||||
|
||||
"nodejs",
|
||||
"unzip",
|
||||
}
|
||||
|
||||
def get_build_env(self):
|
||||
"""
|
||||
Ordered list of environment variables to be set for this image.
|
||||
|
||||
Ordered so that environment variables can use other environment
|
||||
variables in their values.
|
||||
|
||||
Expects tuples, with the first item being the environment variable
|
||||
name and the second item being the value.
|
||||
|
||||
These environment variables will be set prior to build.
|
||||
Use .get_env() to set environment variables after build.
|
||||
"""
|
||||
return []
|
||||
|
||||
def get_env(self):
|
||||
"""
|
||||
Ordered list of environment variables to be set for this image.
|
||||
|
@ -203,6 +227,8 @@ class BuildPack:
|
|||
|
||||
Expects tuples, with the first item being the environment variable
|
||||
name and the second item being the value.
|
||||
|
||||
These variables will not be available to build.
|
||||
"""
|
||||
return []
|
||||
|
||||
|
@ -237,6 +263,30 @@ class BuildPack:
|
|||
"""
|
||||
return {}
|
||||
|
||||
|
||||
@property
|
||||
def stencila_manifest_dir(self):
|
||||
"""Find the stencila manifest dir if it exists"""
|
||||
if hasattr(self, '_stencila_manifest_dir'):
|
||||
return self._stencila_manifest_dir
|
||||
|
||||
# look for a manifest.xml that suggests stencila could be used
|
||||
# when we find one, stencila should be installed
|
||||
# and set environment variables such that
|
||||
# this file is located at:
|
||||
# ${STENCILA_ARCHIVE_DIR}/${STENCILA_ARCHIVE}/manifest.xml
|
||||
|
||||
self._stencila_manifest_dir = None
|
||||
for root, dirs, files in os.walk("."):
|
||||
if "manifest.xml" in files:
|
||||
self._stencila_manifest_dir = root.split(os.path.sep, 1)[1]
|
||||
self.log.info(
|
||||
"Found stencila manifest.xml in %s",
|
||||
self._stencila_manifest_dir,
|
||||
)
|
||||
break
|
||||
return self._stencila_manifest_dir
|
||||
|
||||
def get_build_scripts(self):
|
||||
"""
|
||||
Ordered list of shell script snippets to build the base image.
|
||||
|
@ -349,6 +399,7 @@ class BuildPack:
|
|||
return t.render(
|
||||
packages=sorted(self.get_packages()),
|
||||
path=self.get_path(),
|
||||
build_env=self.get_build_env(),
|
||||
env=self.get_env(),
|
||||
labels=self.get_labels(),
|
||||
build_script_directives=build_script_directives,
|
||||
|
@ -416,11 +467,31 @@ class BuildPack:
|
|||
|
||||
|
||||
class BaseImage(BuildPack):
|
||||
def get_env(self):
|
||||
def get_build_env(self):
|
||||
"""Return env directives required for build"""
|
||||
return [
|
||||
("APP_BASE", "/srv")
|
||||
]
|
||||
|
||||
def get_env(self):
|
||||
"""Return env directives to be set after build"""
|
||||
env = []
|
||||
if self.stencila_manifest_dir:
|
||||
# manifest_dir is the path containing the manifest.xml
|
||||
# archive_dir is the directory containing archive directories (one level up)
|
||||
# default archive is the name of the directory in the archive_dir
|
||||
# such that
|
||||
# ${STENCILA_ARCHIVE_DIR}/${STENCILA_ARCHIVE}/manifest.xml
|
||||
# exists.
|
||||
|
||||
archive_dir, archive = os.path.split(self.stencila_manifest_dir)
|
||||
env.extend([
|
||||
("STENCILA_ARCHIVE_DIR", "${HOME}/" + archive_dir),
|
||||
("STENCILA_ARCHIVE", archive),
|
||||
])
|
||||
return env
|
||||
|
||||
|
||||
def detect(self):
|
||||
return True
|
||||
|
||||
|
@ -453,6 +524,22 @@ class BaseImage(BuildPack):
|
|||
))
|
||||
except FileNotFoundError:
|
||||
pass
|
||||
if self.stencila_manifest_dir:
|
||||
assemble_scripts.extend(
|
||||
[
|
||||
(
|
||||
"${NB_USER}",
|
||||
r"""
|
||||
${KERNEL_PYTHON_PREFIX}/bin/pip install --no-cache https://github.com/stencila/py/archive/f6a245fd.tar.gz && \
|
||||
${KERNEL_PYTHON_PREFIX}/bin/python -m stencila register && \
|
||||
${NB_PYTHON_PREFIX}/bin/pip install --no-cache nbstencilaproxy==0.1.1 && \
|
||||
jupyter serverextension enable --sys-prefix --py nbstencilaproxy && \
|
||||
jupyter nbextension install --sys-prefix --py nbstencilaproxy && \
|
||||
jupyter nbextension enable --sys-prefix --py nbstencilaproxy
|
||||
""",
|
||||
)
|
||||
]
|
||||
)
|
||||
return assemble_scripts
|
||||
|
||||
def get_post_build_scripts(self):
|
||||
|
|
|
@ -18,14 +18,14 @@ class CondaBuildPack(BaseImage):
|
|||
Uses miniconda since it is more lightweight than Anaconda.
|
||||
|
||||
"""
|
||||
def get_env(self):
|
||||
def get_build_env(self):
|
||||
"""Return environment variables to be set.
|
||||
|
||||
We set `CONDA_DIR` to the conda install directory and
|
||||
the `NB_PYTHON_PREFIX` to the location of the jupyter binary.
|
||||
|
||||
"""
|
||||
env = super().get_env() + [
|
||||
env = super().get_build_env() + [
|
||||
('CONDA_DIR', '${APP_BASE}/conda'),
|
||||
('NB_PYTHON_PREFIX', '${CONDA_DIR}'),
|
||||
]
|
||||
|
|
|
@ -57,8 +57,12 @@ if [[ -f /tmp/kernel-environment.yml ]]; then
|
|||
|
||||
conda env create -n kernel -f /tmp/kernel-environment.yml
|
||||
${CONDA_DIR}/envs/kernel/bin/ipython kernel install --prefix "${CONDA_DIR}"
|
||||
rm -f ${CONDA_DIR}/envs/kernel/conda-meta/history
|
||||
fi
|
||||
|
||||
# remove conda history file,
|
||||
# which seems to result in some effective pinning of packages in the initial env,
|
||||
# which we don't intend
|
||||
rm -f ${CONDA_DIR}/conda-meta/history
|
||||
# Clean things out!
|
||||
conda clean -tipsy
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ class JuliaBuildPack(CondaBuildPack):
|
|||
See https://github.com/JuliaPy/PyCall.jl/issues/410
|
||||
|
||||
"""
|
||||
def get_env(self):
|
||||
def get_build_env(self):
|
||||
"""Get additional environment settings for Julia and Jupyter
|
||||
|
||||
Returns:
|
||||
|
@ -31,7 +31,7 @@ class JuliaBuildPack(CondaBuildPack):
|
|||
For example, a tuple may be `('JULIA_VERSION', '0.6.0')`.
|
||||
|
||||
"""
|
||||
return super().get_env() + [
|
||||
return super().get_build_env() + [
|
||||
('JULIA_PATH', '${APP_BASE}/julia'),
|
||||
('JULIA_HOME', '${JULIA_PATH}/bin'),
|
||||
('JULIA_PKGDIR', '${JULIA_PATH}/pkg'),
|
||||
|
|
|
@ -82,7 +82,7 @@ class RBuildPack(PythonBuildPack):
|
|||
'/usr/lib/rstudio-server/bin/'
|
||||
]
|
||||
|
||||
def get_env(self):
|
||||
def get_build_env(self):
|
||||
"""
|
||||
Return environment variables to be set.
|
||||
|
||||
|
@ -90,7 +90,7 @@ class RBuildPack(PythonBuildPack):
|
|||
without needing root. This is set via the `R_LIBS_USER` environment
|
||||
variable, so we set that here.
|
||||
"""
|
||||
return super().get_env() + [
|
||||
return super().get_build_env() + [
|
||||
# This is the path where user libraries are installed
|
||||
('R_LIBS_USER', '${APP_BASE}/rlibs')
|
||||
]
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
Test that node 10 is installed and runnable.
|
|
@ -0,0 +1,7 @@
|
|||
#!/bin/sh
|
||||
|
||||
set -e
|
||||
which node
|
||||
node --version | grep v10
|
||||
which npm
|
||||
npm --version | grep 6.2
|
|
@ -24,3 +24,9 @@
|
|||
url: https://github.com/binder-examples/requirements
|
||||
ref: test
|
||||
verify: python -c 'import matplotlib'
|
||||
# Test that custom channels and downgrades don't
|
||||
# get blocked by pinning
|
||||
- name: Xeus-Cling
|
||||
url: https://github.com/QuantStack/xeus-cling
|
||||
ref: 0.4.5
|
||||
verify: jupyter kernelspec list
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
@article{kluyver2016jupyter,
|
||||
title={Jupyter Notebooks-a publishing format for reproducible computational workflows.},
|
||||
author={Kluyver, Thomas and Ragan-Kelley, Benjamin and P{\'e}rez, Fernando and Granger, Brian E and Bussonnier, Matthias and Frederic, Jonathan and Kelley, Kyle and Hamrick, Jessica B and Grout, Jason and Corlay, Sylvain and others},
|
||||
journal={ELPUB},
|
||||
pages={87--90},
|
||||
year={2016}
|
||||
}
|
||||
@article{ragan2014jupyter,
|
||||
title={The Jupyter/IPython architecture: a unified view of computational research, from interactive exploration to communication and publication.},
|
||||
author={Ragan-Kelley, M and Perez, F and Granger, B and Kluyver, T and Ivanov, P and Frederic, J and Bussonnier, M},
|
||||
journal={AGU Fall Meeting Abstracts},
|
||||
year={2014}
|
||||
}
|
||||
@article{perez2015project,
|
||||
title={Project Jupyter: Computational narratives as the engine of collaborative data science},
|
||||
author={Perez, Fernando and Granger, Brian E},
|
||||
journal={Retrieved September},
|
||||
volume={11},
|
||||
pages={207},
|
||||
year={2015}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
<dar>
|
||||
<documents>
|
||||
<document id="py-jupyter.ipynb" name="py-jupyter.ipynb" type="article" path="py-jupyter.ipynb.jats.xml" src="py-jupyter.ipynb" />
|
||||
</documents>
|
||||
<assets/>
|
||||
</dar>
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,212 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE article PUBLIC "-//NLM//DTD JATS (Z39.96) Journal Archiving and Interchange DTD v1.1d3 20150301//EN" "JATS-archivearticle1.dtd">
|
||||
<article xmlns:mml="http://www.w3.org/1998/Math/MathML" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<front>
|
||||
<article-meta>
|
||||
<title-group>
|
||||
<article-title>Jupyter and Stencila</article-title>
|
||||
</title-group>
|
||||
<contrib-group content-type="author">
|
||||
<contrib contrib-type="person">
|
||||
<name>
|
||||
<surname>Pawlik</surname>
|
||||
<given-names>Aleksandra</given-names>
|
||||
</name>
|
||||
</contrib>
|
||||
</contrib-group>
|
||||
<abstract>
|
||||
<p>An example of a Jupyter notebook converted into a JATS document for editing in Stencila.</p>
|
||||
</abstract>
|
||||
</article-meta>
|
||||
</front>
|
||||
|
||||
<body>
|
||||
<sec id="introduction-1">
|
||||
<title>Introduction</title>
|
||||
<p>Jupyter notebooks (<xref ref-type="bibr" rid="ref-1">1</xref>–<xref ref-type="bibr" rid="ref-3">3</xref>) are one of the most popular platforms for doing reproducible research. Stencila supports importing of Jupyter Notebook <monospace>.ipynb</monospace> files. This allows you to work with collegues to refine a document for final publication while still retaining the code cells, and thus reprodubility of your the work. In the future we also plan to support exporting to <monospace>.ipynb</monospace> files.</p>
|
||||
</sec>
|
||||
<sec id="markdown-cells-1">
|
||||
<title>Markdown cells</title>
|
||||
<p>Most standard Markdown should be supported by the importer including inline <monospace>code</monospace>, headings etc (although the Stencila user interface do not currently support rendering of some elements e.g. math and lists).</p>
|
||||
</sec>
|
||||
<sec id="code-cells-1">
|
||||
<title>Code cells</title>
|
||||
<p>Code cells in notebooks are imported without loss. Stencila’s user interface currently differs from Jupyter in that code cells are executed on update while you are typing. This produces a very reactive user experience but is inappropriate for more compute intensive, longer running code cells. We are currently working on improving this to allowing users to decide to execute cells explicitly (e.g. using <monospace>Ctrl+Enter</monospace>).</p>
|
||||
<code specific-use="cell"><named-content><alternatives>
|
||||
<code specific-use="source" language="pyjp" executable="yes">import sys
|
||||
import time
|
||||
'Hello this is Python %s.%s and it is %s' % (sys.version_info[0], sys.version_info[1], time.strftime('%c'))</code>
|
||||
<code specific-use="output" language="json">{}</code>
|
||||
</alternatives>
|
||||
</named-content>
|
||||
</code>
|
||||
<p>Stencila also support Jupyter code cells that produce plots. The cell below produces a simple plot based on the example from <ext-link ext-link-type="uri" xlink:href="https://matplotlib.org/examples/shapes_and_collections/scatter_demo.html">the Matplotlib website</ext-link>. Try changing the code below (for example, the variable <monospace>N</monospace>).</p>
|
||||
<code specific-use="cell"><named-content><alternatives>
|
||||
<code specific-use="source" language="pyjp" executable="yes">import numpy as np
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
N = 50
|
||||
N = min(N, 1000) # Prevent generation of too many numbers :)
|
||||
x = np.random.rand(N)
|
||||
y = np.random.rand(N)
|
||||
colors = np.random.rand(N)
|
||||
area = np.pi * (15 * np.random.rand(N))**2 # 0 to 15 point radii
|
||||
|
||||
plt.scatter(x, y, s=area, c=colors, alpha=0.5)
|
||||
plt.show()</code>
|
||||
<code specific-use="output" language="json">{}</code>
|
||||
</alternatives>
|
||||
</named-content>
|
||||
</code>
|
||||
<p>We are currently working on supporting <ext-link ext-link-type="uri" xlink:href="http://ipython.readthedocs.io/en/stable/interactive/magics.html">Jupyter’s magic commands</ext-link> in Stencila via a bridge to Jupyter kernels.</p>
|
||||
</sec>
|
||||
<sec id="metadata-1">
|
||||
<title>Metadata</title>
|
||||
<p>To add some metadata about the document (such as authors, title, abstract and so on), In Jupyter, select <monospace>Edit -> Edit Notebook metadata</monospace> from the top menu. Add the title and abstract as JSON strings and authors and organisations metadata as <ext-link ext-link-type="uri" xlink:href="https://www.w3schools.com/js/js_json_arrays.asp">JSON arrays</ext-link>. Author <monospace>affiliation</monospace> identifiers (like <monospace>university-of-earth</monospace> below) must be unique and preferably use only lowercase characters and no spaces.</p>
|
||||
<p>For example,</p>
|
||||
<preformat> "authors": [
|
||||
{
|
||||
"given-names": "Your first name goes here",
|
||||
"surname": "Your last name goes here",
|
||||
"email": "your.email@your-organisation",
|
||||
"corresponding": "yes / no",
|
||||
"affiliation": "university-of-earth"
|
||||
}
|
||||
],
|
||||
|
||||
"organisations": [
|
||||
{
|
||||
"university-of-earth": {
|
||||
"institution": "Your organisation name",
|
||||
"city": "Your city",
|
||||
"country": "Your country"
|
||||
}
|
||||
],
|
||||
|
||||
"title": "Your title goes here",
|
||||
"abstract": "This is a paper about lots of different interesting things",
|
||||
</preformat>
|
||||
</sec>
|
||||
<sec id="citations-and-references-1">
|
||||
<title>Citations and references</title>
|
||||
<p>Stencila supports Pandoc style citations and reference lists within Jupyter notebook Markdown cells. Add a <monospace>bibliography</monospace> entry to the notebook’s metadata which points to a file containing your list of references e.g.</p>
|
||||
<code language="json">"bibliography": "my-bibliography.bibtex"</code>
|
||||
<p>Then, within Markdown cells, you can insert citations inside square brackets and separated by semicolons. Each citation is represented using the <monospace>@</monospace> symbol followed by the citation identifier from the bibliography database e.g.</p>
|
||||
<code language="json">[@perez2015project; @kluyver2016jupyter]</code>
|
||||
<p>The <ext-link ext-link-type="uri" xlink:href="https://github.com/takluyver/cite2c">cite2c</ext-link> Jupyter extension allows for easier, “cite-while-you-write” insertion of citations from a Zotero library. We’re hoping to support conversion of cite2cstyle citations/references in the <ext-link ext-link-type="uri" xlink:href="https://github.com/stencila/convert/issues/14">future</ext-link>.</p>
|
||||
</sec>
|
||||
</body>
|
||||
<back>
|
||||
<ref-list>
|
||||
<ref id="ref-1">
|
||||
<element-citation publication-type="journal">
|
||||
<person-group person-group-type="author">
|
||||
<name>
|
||||
<surname>Perez</surname>
|
||||
<given-names>Fernando</given-names>
|
||||
</name>
|
||||
<name>
|
||||
<surname>Granger</surname>
|
||||
<given-names>Brian E</given-names>
|
||||
</name>
|
||||
</person-group>
|
||||
<article-title>Project jupyter: Computational narratives as the engine of collaborative data science</article-title>
|
||||
<source>Retrieved September</source>
|
||||
<year>2015</year>
|
||||
<volume>11</volume>
|
||||
<fpage>207</fpage>
|
||||
</element-citation>
|
||||
</ref>
|
||||
<ref id="ref-2">
|
||||
<element-citation publication-type="journal">
|
||||
<person-group person-group-type="author">
|
||||
<name>
|
||||
<surname>Kluyver</surname>
|
||||
<given-names>Thomas</given-names>
|
||||
</name>
|
||||
<name>
|
||||
<surname>Ragan-Kelley</surname>
|
||||
<given-names>Benjamin</given-names>
|
||||
</name>
|
||||
<name>
|
||||
<surname>Pérez</surname>
|
||||
<given-names>Fernando</given-names>
|
||||
</name>
|
||||
<name>
|
||||
<surname>Granger</surname>
|
||||
<given-names>Brian E</given-names>
|
||||
</name>
|
||||
<name>
|
||||
<surname>Bussonnier</surname>
|
||||
<given-names>Matthias</given-names>
|
||||
</name>
|
||||
<name>
|
||||
<surname>Frederic</surname>
|
||||
<given-names>Jonathan</given-names>
|
||||
</name>
|
||||
<name>
|
||||
<surname>Kelley</surname>
|
||||
<given-names>Kyle</given-names>
|
||||
</name>
|
||||
<name>
|
||||
<surname>Hamrick</surname>
|
||||
<given-names>Jessica B</given-names>
|
||||
</name>
|
||||
<name>
|
||||
<surname>Grout</surname>
|
||||
<given-names>Jason</given-names>
|
||||
</name>
|
||||
<name>
|
||||
<surname>Corlay</surname>
|
||||
<given-names>Sylvain</given-names>
|
||||
</name>
|
||||
<name>
|
||||
<surname>Others</surname>
|
||||
</name>
|
||||
</person-group>
|
||||
<article-title>Jupyter notebooks-a publishing format for reproducible computational workflows.</article-title>
|
||||
<source>ELPUB</source>
|
||||
<year>2016</year>
|
||||
<fpage>87</fpage>
|
||||
</element-citation>
|
||||
</ref>
|
||||
<ref id="ref-3">
|
||||
<element-citation publication-type="journal">
|
||||
<person-group person-group-type="author">
|
||||
<name>
|
||||
<surname>Ragan-Kelley</surname>
|
||||
<given-names>M</given-names>
|
||||
</name>
|
||||
<name>
|
||||
<surname>Perez</surname>
|
||||
<given-names>F</given-names>
|
||||
</name>
|
||||
<name>
|
||||
<surname>Granger</surname>
|
||||
<given-names>B</given-names>
|
||||
</name>
|
||||
<name>
|
||||
<surname>Kluyver</surname>
|
||||
<given-names>T</given-names>
|
||||
</name>
|
||||
<name>
|
||||
<surname>Ivanov</surname>
|
||||
<given-names>P</given-names>
|
||||
</name>
|
||||
<name>
|
||||
<surname>Frederic</surname>
|
||||
<given-names>J</given-names>
|
||||
</name>
|
||||
<name>
|
||||
<surname>Bussonnier</surname>
|
||||
<given-names>M</given-names>
|
||||
</name>
|
||||
</person-group>
|
||||
<article-title>The jupyter/ipython architecture: A unified view of computational research, from interactive exploration to communication and publication.</article-title>
|
||||
<source>AGU Fall Meeting Abstracts</source>
|
||||
<year>2014</year>
|
||||
</element-citation>
|
||||
</ref>
|
||||
</ref-list>
|
||||
</back>
|
||||
</article>
|
|
@ -0,0 +1,13 @@
|
|||
@article{baumer2014r,
|
||||
title={R Markdown: Integrating a reproducible analysis tool into introductory statistics},
|
||||
author={Baumer, Ben and Cetinkaya-Rundel, Mine and Bray, Andrew and Loi, Linda and Horton, Nicholas J},
|
||||
journal={arXiv preprint arXiv:1402.1894},
|
||||
year={2014}
|
||||
}
|
||||
|
||||
@book{xie2016bookdown,
|
||||
title={Bookdown: Authoring Books and Technical Documents with R Markdown},
|
||||
author={Xie, Yihui},
|
||||
year={2016},
|
||||
publisher={CRC Press}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
<dar>
|
||||
<documents>
|
||||
<document id="rmarkdown.Rmd" name="rmarkdown.Rmd" type="article" path="rmarkdown.Rmd.jats.xml" src="rmarkdown.Rmd" />
|
||||
</documents>
|
||||
<assets/>
|
||||
</dar>
|
|
@ -0,0 +1,57 @@
|
|||
---
|
||||
title: RMarkdown and Stencila
|
||||
author:
|
||||
- surname: Bentley
|
||||
given-names: Nokome
|
||||
affiliation: stencila
|
||||
- surname: Pawlik
|
||||
given-names: Aleksandra
|
||||
- surname: Aufrieter
|
||||
given-names: Michael
|
||||
affiliation: substance
|
||||
- surname: Buchtala
|
||||
given-names: Oliver
|
||||
affiliation: substance
|
||||
organisations:
|
||||
- id: stencila
|
||||
name: Stencila
|
||||
city: Kaikoura
|
||||
country: New Zealand
|
||||
- id: substance
|
||||
name: Substance GmbH
|
||||
city: Linz
|
||||
country: Austria
|
||||
abstract: |
|
||||
Stencila currently supports import of RMarkdown documents. This allows use cases like allowing collaborators to work on the same document using a WYSIWYG editing environment, or for you to put the final touches on a paper before final submission to a journal.
|
||||
bibliography: bibliography.bibtex
|
||||
---
|
||||
|
||||
# Introduction
|
||||
|
||||
[RMarkdown](https://rmarkdown.rstudio.com/) is a popular format for reproducible research using the R programming language ([@baumer2014r],[@xie2016bookdown]). Stencila is a able to import RMarkdown documents. For example, the source for this example document is available on [Github](https://github.com/stencila/stencila/blob/more-examples/data/r-markdown/rmarkdown.Rmd). Eventually, we'll also support exporting to RMarkdown, allowing WYSIWYG editing of RMarkdown documents in Stencila.
|
||||
|
||||
# Code chunks
|
||||
|
||||
In RMarkdown, code "chunks" are written using "fenced" code blocks. Stencila converts these code "chunks" into Stencila code "cells" like this one:
|
||||
|
||||
```{r}
|
||||
n <- 500
|
||||
```
|
||||
|
||||
Stencila cells behave like functions having zero or more named `inputs` (like function arguments) and an optional `output` (like a assigning a function's return value). A cell's inputs and outputs are determined by analyzing the cell's code. The cell above has no inputs but produces an output variable named `n`. Stencila's execution engine uses this information to make code cells reactive. For instance, the cell below has `n` as an input i.e it is dependent on the first cell. So when you update the `n` in the cell above, the following plot will update.
|
||||
|
||||
```{r}
|
||||
s <- min(1000, n)
|
||||
x <- runif(s)
|
||||
y <- x + runif(s)
|
||||
z <- y + rnorm(s)
|
||||
plot(x, y, cex=z*2, col=rainbow(length(z), alpha=0.5)[rank(x+z)], pch=16)
|
||||
```
|
||||
|
||||
# Figures
|
||||
|
||||
In RMarkdown, code chunks can have various options. A common use for options is to set the caption and dimensions of figures. Stencila converts code chunks with the `fig.cap` option into JATS `<fig fig-type="repro-fig">` elements with a `<caption>`. This allows the user to edit the figure caption and for automatic figure numbering and referencing (although that is not working 100% right now). Other options are placed in a comment at the top of the cell so that they are preserved (and eventually will be used to apply those options within the R execution context).
|
||||
|
||||
```{r fig.width=7,fig.height=6,fig.cap="Figure title"}
|
||||
hist(z, breaks=40, col=hsv(0.6, 0.9, 1), xlab="Value", main="")
|
||||
```
|
|
@ -0,0 +1,141 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE article PUBLIC "-//NLM//DTD JATS (Z39.96) Journal Archiving and Interchange DTD v1.1d3 20150301//EN" "JATS-archivearticle1.dtd">
|
||||
<article xmlns:mml="http://www.w3.org/1998/Math/MathML" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<front>
|
||||
<article-meta>
|
||||
<title-group>
|
||||
<article-title>RMarkdown and Stencila</article-title>
|
||||
</title-group>
|
||||
<contrib-group content-type="author">
|
||||
<contrib contrib-type="person">
|
||||
<name>
|
||||
<surname>Bentley</surname>
|
||||
<given-names>Nokome</given-names>
|
||||
</name>
|
||||
<xref ref-type="aff" rid="stencila" />
|
||||
</contrib>
|
||||
<contrib contrib-type="person">
|
||||
<name>
|
||||
<surname>Pawlik</surname>
|
||||
<given-names>Aleksandra</given-names>
|
||||
</name>
|
||||
</contrib>
|
||||
<contrib contrib-type="person">
|
||||
<name>
|
||||
<surname>Aufrieter</surname>
|
||||
<given-names>Michael</given-names>
|
||||
</name>
|
||||
<xref ref-type="aff" rid="substance" />
|
||||
</contrib>
|
||||
<contrib contrib-type="person">
|
||||
<name>
|
||||
<surname>Buchtala</surname>
|
||||
<given-names>Oliver</given-names>
|
||||
</name>
|
||||
<xref ref-type="aff" rid="substance" />
|
||||
</contrib>
|
||||
</contrib-group>
|
||||
<aff id="stencila">
|
||||
<institution content-type="orgname">Stencila</institution>
|
||||
<city>Kaikoura</city>
|
||||
<country>New Zealand</country>
|
||||
</aff>
|
||||
<aff id="substance">
|
||||
<institution content-type="orgname">Substance GmbH</institution>
|
||||
<city>Linz</city>
|
||||
<country>Austria</country>
|
||||
</aff>
|
||||
<abstract>
|
||||
<p>Stencila currently supports import of RMarkdown documents. This allows use cases like allowing collaborators to work on the same document using a WYSIWYG editing environment, or for you to put the final touches on a paper before final submission to a journal.</p>
|
||||
</abstract>
|
||||
</article-meta>
|
||||
</front>
|
||||
|
||||
<body>
|
||||
<sec id="introduction-1">
|
||||
<title>Introduction</title>
|
||||
<p><ext-link ext-link-type="uri" xlink:href="https://rmarkdown.rstudio.com/">RMarkdown</ext-link> is a popular format for reproducible research using the R programming language (<xref ref-type="bibr" rid="ref-1">1</xref>,<xref ref-type="bibr" rid="ref-2">2</xref>). Stencila is a able to import RMarkdown documents. For example, the source for this example document is available on <ext-link ext-link-type="uri" xlink:href="https://github.com/stencila/stencila/blob/more-examples/data/r-markdown/rmarkdown.Rmd">Github</ext-link>. Eventually, we’ll also support exporting to RMarkdown, allowing WYSIWYG editing of RMarkdown documents in Stencila.</p>
|
||||
</sec>
|
||||
<sec id="code-chunks-1">
|
||||
<title>Code chunks</title>
|
||||
<p>In RMarkdown, code “chunks” are written using “fenced” code blocks. Stencila converts these code “chunks” into Stencila code “cells” like this one:</p>
|
||||
<code specific-use="cell"><named-content><alternatives>
|
||||
<code specific-use="source" language="r" executable="yes">n <- 500</code>
|
||||
<code specific-use="output" language="json">{}</code>
|
||||
</alternatives>
|
||||
</named-content>
|
||||
</code>
|
||||
<p>Stencila cells behave like functions having zero or more named <monospace>inputs</monospace> (like function arguments) and an optional <monospace>output</monospace> (like a assigning a function’s return value). A cell’s inputs and outputs are determined by analyzing the cell’s code. The cell above has no inputs but produces an output variable named <monospace>n</monospace>. Stencila’s execution engine uses this information to make code cells reactive. For instance, the cell below has <monospace>n</monospace> as an input i.e it is dependent on the first cell. So when you update the <monospace>n</monospace> in the cell above, the following plot will update.</p>
|
||||
<code specific-use="cell"><named-content><alternatives>
|
||||
<code specific-use="source" language="r" executable="yes">s <- min(1000, n)
|
||||
x <- runif(s)
|
||||
y <- x + runif(s)
|
||||
z <- y + rnorm(s)
|
||||
plot(x, y, cex=z*2, col=rainbow(length(z), alpha=0.5)[rank(x+z)], pch=16)</code>
|
||||
<code specific-use="output" language="json">{}</code>
|
||||
</alternatives>
|
||||
</named-content>
|
||||
</code>
|
||||
</sec>
|
||||
<sec id="figures-1">
|
||||
<title>Figures</title>
|
||||
<p>In RMarkdown, code chunks can have various options. A common use for options is to set the caption and dimensions of figures. Stencila converts code chunks with the <monospace>fig.cap</monospace> option into JATS <monospace><fig fig-type="repro-fig"></monospace> elements with a <monospace><caption></monospace>. This allows the user to edit the figure caption and for automatic figure numbering and referencing (although that is not working 100% right now). Other options are placed in a comment at the top of the cell so that they are preserved (and eventually will be used to apply those options within the R execution context).</p>
|
||||
<fig fig-type="repro-fig">
|
||||
<caption>
|
||||
<title>Figure title</title>
|
||||
</caption>
|
||||
<alternatives>
|
||||
<code specific-use="source" language="r" executable="yes">#: fig.width=7,fig.height=6
|
||||
hist(z, breaks=40, col=hsv(0.6, 0.9, 1), xlab="Value", main="")</code>
|
||||
<code specific-use="output" language="json">{}</code>
|
||||
</alternatives>
|
||||
</fig>
|
||||
</sec>
|
||||
</body>
|
||||
<back>
|
||||
<ref-list>
|
||||
<ref id="ref-1">
|
||||
<element-citation publication-type="journal">
|
||||
<person-group person-group-type="author">
|
||||
<name>
|
||||
<surname>Baumer</surname>
|
||||
<given-names>Ben</given-names>
|
||||
</name>
|
||||
<name>
|
||||
<surname>Cetinkaya-Rundel</surname>
|
||||
<given-names>Mine</given-names>
|
||||
</name>
|
||||
<name>
|
||||
<surname>Bray</surname>
|
||||
<given-names>Andrew</given-names>
|
||||
</name>
|
||||
<name>
|
||||
<surname>Loi</surname>
|
||||
<given-names>Linda</given-names>
|
||||
</name>
|
||||
<name>
|
||||
<surname>Horton</surname>
|
||||
<given-names>Nicholas J</given-names>
|
||||
</name>
|
||||
</person-group>
|
||||
<article-title>R markdown: Integrating a reproducible analysis tool into introductory statistics</article-title>
|
||||
<source>arXiv preprint arXiv:1402.1894</source>
|
||||
<year>2014</year>
|
||||
</element-citation>
|
||||
</ref>
|
||||
<ref id="ref-2">
|
||||
<element-citation publication-type="book">
|
||||
<person-group person-group-type="author">
|
||||
<name>
|
||||
<surname>Xie</surname>
|
||||
<given-names>Yihui</given-names>
|
||||
</name>
|
||||
</person-group>
|
||||
<source>Bookdown: Authoring books and technical documents with r markdown</source>
|
||||
<publisher-name>CRC Press</publisher-name>
|
||||
<year>2016</year>
|
||||
</element-citation>
|
||||
</ref>
|
||||
</ref-list>
|
||||
</back>
|
||||
</article>
|
|
@ -0,0 +1,4 @@
|
|||
#!/bin/sh
|
||||
|
||||
jupyter serverextension list 2>&1 | grep nbstencilaproxy
|
||||
jupyter nbextension list 2>&1 | grep nbstencilaproxy
|
|
@ -0,0 +1,52 @@
|
|||
"""
|
||||
Test if the explict hostname is supplied correctly to the container
|
||||
"""
|
||||
import requests
|
||||
import time
|
||||
from repo2docker.app import Repo2Docker
|
||||
|
||||
def test_connect_url(tmpdir):
|
||||
tmpdir.chdir()
|
||||
#q = tmpdir.join("environment.yml")
|
||||
#q.write("dependencies:\n"
|
||||
# " - notebook==5.6.0")
|
||||
p = tmpdir.join("requirements.txt")
|
||||
p.write("notebook==5.6.0")
|
||||
|
||||
app = Repo2Docker()
|
||||
argv = [str(tmpdir), ]
|
||||
app.initialize(argv)
|
||||
app.debug = True
|
||||
app.run = False
|
||||
app.start() # This just build the image and does not run it.
|
||||
container = app.start_container()
|
||||
container_url = 'http://{}:{}/api'.format(app.hostname, app.port)
|
||||
expected_url = 'http://{}:{}'.format(app.hostname, app.port)
|
||||
|
||||
# wait a bit for the container to be ready
|
||||
# give the container a chance to start
|
||||
time.sleep(1)
|
||||
|
||||
try:
|
||||
# try a few times to connect
|
||||
success = False
|
||||
for i in range(1, 4):
|
||||
container.reload()
|
||||
assert container.status == 'running'
|
||||
if expected_url not in container.logs().decode("utf8"):
|
||||
time.sleep(i * 3)
|
||||
continue
|
||||
try:
|
||||
info = requests.get(container_url).json()
|
||||
except Exception as e:
|
||||
print("Error: %s" % e)
|
||||
time.sleep(i * 3)
|
||||
else:
|
||||
print(info)
|
||||
success = True
|
||||
break
|
||||
assert success, "Notebook never started in %s" % container
|
||||
finally:
|
||||
# stop the container
|
||||
container.stop()
|
||||
app.wait_for_container(container)
|
Ładowanie…
Reference in New Issue