Skip to content

Commit

Permalink
Add simple example Jupyter notebook (for Binder) (#127)
Browse files Browse the repository at this point in the history
* examples: Add Binder-compatible Jupyter notebook example

* TO BE SQUASHED jupyterlab

* try jupyterlab

* give up on JupyterLab; leave as TODO

* address review

* address review

* address review
  • Loading branch information
EricCousineau-TRI authored Feb 22, 2021
1 parent f399f97 commit aa5920c
Show file tree
Hide file tree
Showing 7 changed files with 251 additions and 6 deletions.
1 change: 1 addition & 0 deletions .binder/.dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
README.md
65 changes: 65 additions & 0 deletions .binder/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# -*- mode: dockerfile -*-
# vi: set ft=dockerfile :

# TODO(eric.cousineau): Figure out how to make JupyterLab work with this setup:
# https://github.com/binder-examples/jupyterlab

# TODO(eric.cousineau): See if it's easier to use a conda-based workflow, or a
# simpler Docker base image, to use Eigen headers, rather than doing a custom
# Docker image:
# https://mybinder.readthedocs.io/en/latest/using/config_files.html

FROM ubuntu:18.04

ARG NB_USER=jovyan
ARG NB_UID=1000
ARG NB_GID=100
EXPOSE 7000/tcp
EXPOSE 8888/tcp

RUN export DEBIAN_FRONTEND=noninteractive \
&& apt-get update \
&& apt-get install -y --no-install-recommends \
-o Dpkg::Options::=--force-confdef -o Dpkg::Options::=--force-confnew \
-o Dpkg::Use-Pty=0 \
locales \
python3-pip \
python3-setuptools \
&& rm -rf /var/lib/apt/lists/* \
&& locale-gen en_US.UTF-8

# Install common C++ libraries for experimenting. These are not necessary to
# use pygccxml itself.
RUN export DEBIAN_FRONTEND=noninteractive \
&& apt-get update \
&& apt-get install -y --no-install-recommends \
-o Dpkg::Options::=--force-confdef -o Dpkg::Options::=--force-confnew \
-o Dpkg::Use-Pty=0 \
libeigen3-dev \
libstdc++-7-dev \
&& rm -rf /var/lib/apt/lists/*

RUN useradd -d "/home/$NB_USER" -G $NB_GID -mU -s /bin/bash "$NB_USER"
ENV HOME="/home/$NB_USER" \
LANG=en_US.UTF-8 \
LANGUAGE=en_US.UTF-8 \
LC_ALL=en_US.UTF-8 \
SHELL=/bin/bash \
USER="$NB_USER" \
PATH="/home/$NB_USER/.local/bin:/usr/local/bin:/usr/bin:/bin"

# Upgrade pip to use newer indices for castxml.
# WARNING: Never upgrade a distribution `pip` on a host system using sudo!
# We are only doing this for a transient Docker image. For a host system, use a
# virtualenv to upgrade pip.
RUN pip3 --no-cache-dir install -U pip

WORKDIR $HOME
RUN mkdir pygccxml
COPY ["/", "pygccxml/"]
RUN chown -R $NB_UID:$NB_GID \
"$HOME/pygccxml"
USER "$NB_USER"
RUN pip3 --no-cache-dir install castxml
RUN pip3 --no-cache-dir install -e ./pygccxml[examples]
CMD ["jupyter", "notebook", "--ip", "0.0.0.0", "pygccxml/docs/examples/notebook/example.ipynb"]
33 changes: 33 additions & 0 deletions .binder/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Docker Image for Binder

<!--
This is derived from the following setup:
https://github.com/RobotLocomotion/drake/tree/dc2a9394d/.binder
-->

*Note that due to Binder conventions, this directory MUST always be in the root
of the repository and named either `binder` or `.binder`. This image is NOT
intended for use by most developers or users.*

These instructions are for running the image locally. For Binder itself, you
should only need to visit the link from the root-level README.

To create a Docker image and run a Docker container similar to those used by
[Binder](https://mybinder.org) for local debugging purposes, execute the
following `build` and `run` commands from the top level of this Git repository:

```bash
docker build -f .binder/Dockerfile -t binder .
docker run --rm -it --name mybinder -p 8888:8888 binder
```

For the URLs printed, only open the `127.0.0.1:8888` URL (including the login
token) in a web browser on your host system.

To stop the running container, simply exit it from the terminal with Ctrl+C.

*Note*: If you want to test the Docker image with the current source tree
(without copying, so you can modify source files), insert the arguments
`-v "${PWD}:/home/jovyan/pygccxml"` to `docker run`, before the image name
(`binder`), to mount it directly. This will *not* act on any changes to
`./setup.py`.
1 change: 1 addition & 0 deletions .dockerignore
14 changes: 14 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,23 @@ Documentation and examples
--------------------------

The documentation can be found `here <http://pygccxml.readthedocs.io>`_, examples can be found `here <http://pygccxml.readthedocs.io/en/master/examples.html>`_.
You can also run an example JupyterLab Notebook using Binder, or view it using
``nbviewer``:

..
Developers: See `.binder/README.md` for more information.
.. image:: https://mybinder.org/badge_logo.svg
:target: https://mybinder.org/v2/gh/EricCousineau-TRI/pygccxml/feature-py-notebook-example?urlpath=tree/pygccxml/docs/examples/notebook/
:alt: Binder
.. image:: https://img.shields.io/badge/view%20on-nbviewer-brightgreen.svg
:target: https://nbviewer.jupyter.org/github/EricCousineau-TRI/pygccxml/tree/feature-py-notebook-example/docs/examples/notebook/
:alt: nbviewer

If you want to know more about the API provided by pygccxml, read the `query interface <http://pygccxml.readthedocs.io/en/develop/query_interface.html>`_ document or the `API documentation <http://pygccxml.readthedocs.io/en/develop/apidocs/modules.html>`_.



A `FAQ <http://pygccxml.readthedocs.io/en/master/faq.html>`_ is also available and may answer some of your questions.

License
Expand Down
127 changes: 127 additions & 0 deletions docs/examples/notebook/example.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Example pygccxml notebook on Binder\n",
"\n",
"Running this notebook on Binder allows you to execute the code online:",
"<a target=\"_doc\" href=\"https://mybinder.org/v2/gh/EricCousineau-TRI/pygccxml/feature-py-notebook-example?urlpath=tree/pygccxml/docs/examples/notebook/example.ipynb\">\n",
" <img src=\"https://mybinder.org/badge_logo.svg\"/>\n",
"</a>\n",
"\n",
"Please note that provisioning may take about 1-2 minutes.\n",
"\n",
"\n",
"The following example shows an example usage of `pygccxml` on Ubuntu\n",
"Bionic, from within a Docker container, for a simple toy C++ API that\n",
"uses both `std::vector` and `Eigen::Matrix<>`. The code is defined inline."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from pygccxml import declarations\n",
"from pygccxml import utils\n",
"from pygccxml import parser"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Find out the c++ parser. This should resolve to the castxml\n",
"# version installed in Docker.\n",
"generator_path, generator_name = utils.find_xml_generator()\n",
"\n",
"# Configure the xml generator\n",
"config = parser.xml_generator_configuration_t(\n",
" xml_generator_path=generator_path,\n",
" xml_generator=generator_name,\n",
" include_paths=[\"/usr/include/eigen3\"],\n",
" compiler_path=generator_path,\n",
")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"code = r\"\"\"\n",
"#include <vector>\n",
"\n",
"#include <Eigen/Dense>\n",
"\n",
"namespace ns {\n",
"\n",
"template <typename T, typename U = int>\n",
"class ExampleClass {\n",
"public:\n",
" std::vector<T> make_std_vector() const;\n",
" Eigen::Matrix<U, 3, 3> make_matrix3();\n",
"};\n",
"\n",
"// Analyze concrete instantiations of the given class.\n",
"extern template class ExampleClass<int>;\n",
"extern template class ExampleClass<float, float>;\n",
"\n",
"} // namespace ns\n",
"\"\"\"\n",
"\n",
"(global_ns,) = parser.parse_string(code, config)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"scrolled": false
},
"outputs": [],
"source": [
"ns = global_ns.namespace(\"ns\")\n",
"declarations.print_declarations([ns])"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Retrieve an instantiation and show template parameters.\n",
"cls, = ns.classes('ExampleClass<float, float>')\n",
"declarations.templates.split(cls.name)"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.9"
}
},
"nbformat": 4,
"nbformat_minor": 4
}
16 changes: 10 additions & 6 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,18 @@

version = utils.find_version("../pygccxml/__init__.py")

requirements_test = {
requirements_test = [
"coverage",
"coveralls",
"pycodestyle",
}
requirements_docs = {
]
requirements_docs = [
"sphinx",
"sphinx_rtd_theme",
}
]
requirements_examples = [
"notebook",
]

setup(name="pygccxml",
version=version,
Expand All @@ -36,8 +39,9 @@
"pygccxml.parser",
"pygccxml.utils"],
extras_require={
"test": list(requirements_test),
"docs": list(requirements_docs),
"test": requirements_test,
"docs": requirements_docs,
"examples": requirements_examples,
},
classifiers=[
"Development Status :: 5 - Production/Stable",
Expand Down

0 comments on commit aa5920c

Please sign in to comment.