{ "info": { "author": "Christian Barra", "author_email": "info@cassiny.io", "bugtrack_url": null, "classifiers": [ "Development Status :: 3 - Alpha", "Intended Audience :: Developers", "License :: OSI Approved :: BSD License", "Programming Language :: Python :: 3.3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Topic :: Software Development :: Libraries :: Python Modules" ], "description": "==============================\nSwarmSpawner\n==============================\n\n.. image:: https://badge.fury.io/py/swarmspawner.svg\n :target: https://badge.fury.io/py/swarmspawner\n :alt: PyPI version\n\n.. image:: https://img.shields.io/pypi/pyversions/swarmspawner.svg\n :target: https://pypi.org/project/swarmspawner/\n :alt: Python Versions\n\n\n**SwarmSpawner** enables `JupyterHub `_ to spawn single user notebook servers in Docker Services.\n\nMore info about Docker Services `here `_.\n\n\nPrerequisites\n================\n\nPython version 3.3 and above is required.\n\n\nInstallation\n================\n\n.. code-block:: sh\n\n pip install swarmspawner\n\nInstallation from GitHub\n============================\n\n.. code-block:: sh\n\n git clone https://github.com/cassinyio/SwarmSpawner\n cd SwarmSpawner\n python setup.py install\n\nConfiguration\n================\n\nYou can find an example jupyter_config.py inside `examples `_.\n\nThe spawner\n================\nDocker Engine in Swarm mode and the related services work in a different way compared to Docker containers.\n\nTell JupyterHub to use SwarmSpawner by adding the following lines to your `jupyterhub_config.py`:\n\n.. code-block:: python\n\n c.JupyterHub.spawner_class = 'cassinyspawner.SwarmSpawner'\n c.JupyterHub.hub_ip = '0.0.0.0'\n # This should be the name of the jupyterhub service\n c.SwarmSpawner.jupyterhub_service_name = 'NameOfTheService'\n\nWhat is ``jupyterhub_service_name``?\n\nInside a Docker engine in Swarm mode the services use a `name` instead of a `ip` to communicate with each other.\n'jupyterhub_service_name' is the name of ther service for the JupyterHub.\n\nNetworks\n============\nIt's important to put the JupyterHub service (also the proxy) and the services that are running jupyter notebook inside the same network, otherwise they couldn't reach each other.\nSwarmSpawner use the service's name instead of the service's ip, as a consequence JupyterHub and servers should share the same overlay network (network across nodes).\n\n.. code-block:: python\n\n #list of networks\n c.SwarmSpawner.networks = [\"mynetwork\"]\n\n\nDefine the services inside jupyterhub_config.py\n===============================================\nYou can define *container_spec*, *resource_spec* and *networks* inside **jupyterhub_config.py**.\n\nContainer_spec__\n-------------------\n__ https://github.com/docker/docker-py/blob/master/docs/user_guides/swarm_services.md\n\n\n``command`` and ``args`` depends on the image that you are using.\n\nIf you use one of the images from the Jupyter docker-stack you need to specify ``args`` as: ``/usr/local/bin/start-singleuser.sh``\n\nIf you are using a specific image, well it's up to you to specify the right command.\n\n.. code-block:: python\n\n c.SwarmSpawner.container_spec = {\n # The command to run inside the service\n # 'args' : ['/usr/local/bin/start-singleuser.sh'], # (list)\n 'Image' : 'YourImage',\n 'mounts' : mounts\n }\n\n\n**Note:** in a container spec, ``args`` sets the equivalent of CMD in the Dockerfile, ``command`` sets the equivalent of ENTRYPOINT.\nThe notebook server command should not be the ENTRYPOINT, so generally use ``args``, not ``command``, to specify how to launch the notebook server.\n\nSee this `issue `_ for more info.\n\nBind a Host dir\n---------------------\nWith ``'type':'bind'`` you mount a local directory of the host inside the container.\n\n*Remember that source should exist in the node where you are creating the service.*\n\n.. code-block:: python\n\n notebook_dir = os.environ.get('NOTEBOOK_DIR') or '/home/jovyan/work'\n c.SwarmSpawner.notebook_dir = notebook_dir\n\n.. code-block:: python\n\n mounts = [{'type' : 'bind',\n 'source' : 'MountPointOnTheHost',\n 'target' : 'MountPointInsideTheContainer',}]\n\n\nMount a named volume\n----------------------\nWith ``'type':'volume'`` you mount a Docker Volume inside the container.\nIf the volume doesn't exist it will be created.\n\n.. code-block:: python\n\n mounts = [{'type' : 'volume',\n 'source' : 'NameOfTheVolume',\n 'target' : 'MountPointInsideTheContainer',}]\n\n\nNamed path\n--------------\nFor both types, volume and bind, you can specify a ``{username}`` inside the source:\n\n.. code-block:: python\n\n mounts = [{'type' : 'volume',\n 'source' : 'jupyterhub-user-{username}',\n 'target' : 'MountPointInsideTheContainer',}]\n\n\nusername will be the hashed version of the username.\n\n\nMount an anonymous volume\n-------------------------\n**This kind of volume will be removed with the service.**\n\n.. code-block:: python\n\n mounts = [{'type' : 'volume',\n 'target' : 'MountPointInsideTheContainer',}]\n\n\nResource_spec\n---------------\n\nYou can also specify some resource for each service\n\n.. code-block:: python\n\n c.SwarmSpawner.resource_spec = {\n 'cpu_limit' : 1000, # (int) \u2013 CPU limit in units of 10^9 CPU shares.\n 'mem_limit' : int(512 * 1e6), # (int) \u2013 Memory limit in Bytes.\n 'cpu_reservation' : 1000, # (int) \u2013 CPU reservation in units of 10^9 CPU shares.\n 'mem_reservation' : int(512 * 1e6), # (int) \u2013 Memory reservation in Bytes\n }\n\nUsing user_options\n--------------------\n\nThere is the possibility to set parameters using ``user_options``\n\n.. code-block:: python\n\n # To use user_options in service creation\n c.SwarmSpawner.use_user_options = False\n\n\nTo control the creation of the services you have 2 ways, using **jupyterhub_config.py** or **user_options**.\n\nRemember that at the end you are just using the `Docker Engine API `_.\n\n**user_options, if used, will overwrite jupyter_config.py for services.**\n\nIf you set ``c.SwarmSpawner.use_user_option = True`` the spawner will use the dict passed through the form or as json body when using the Hub Api.\n\nThe spawner expect a dict with these keys:\n\n.. code-block:: python\n\n user_options = {\n 'container_spec' : {\n # (string or list) command to run in the image.\n 'args' : ['/usr/local/bin/start-singleuser.sh'],\n # name of the image\n 'Image' : '',\n 'mounts' : mounts,\n 'resource_spec' : {\n # (int) \u2013 CPU limit in units of 10^9 CPU shares.\n 'cpu_limit': int(1 * 1e9),\n # (int) \u2013 Memory limit in Bytes.\n 'mem_limit': int(512 * 1e6),\n # (int) \u2013 CPU reservation in units of 10^9 CPU shares.\n 'cpu_reservation': int(1 * 1e9),\n # (int) \u2013 Memory reservation in bytes\n 'mem_reservation': int(512 * 1e6),\n },\n # list of constrains\n 'placement' : [],\n # list of networks\n 'network' : [],\n # name of service\n 'name' : ''\n }\n }\n\n\nNames of the Jupyter notebook service inside Docker engine in Swarm mode\n--------------------------------------------------------------------------\n\nWhen JupyterHub spawns a new Jupyter notebook server the name of the service will be ``{service_prefix}-{service_owner}-{service_suffix}``\n\nYou can change the service_prefix in this way:\n\nPrefix of the service in Docker\n\n.. code-block:: python\n\n c.SwarmSpawner.service_prefix = \"jupyterhub\"\n\n\n``service_owner`` is the hexdigest() of the hashed ``user.name``.\n\nIn case of named servers (more than one server for user) ``service_suffix`` is the name of the server, otherwise is always 1.\n\nDownloading images\n-------------------\nDocker Engine in Swarm mode downloads images automatically from the repository.\nEither the image is available on the remote repository or locally, if not you will get an error.\n\nBecause before starting the service you have to complete the download of the image is better to have a longer timeout (default is 30 secs)\n\n.. code-block:: python\n\n c.SwarmSpawner.start_timeout = 60 * 5\n\n\nYou can use all the docker images inside the `Jupyter docker-stacks`_.\n\n.. _Jupyter docker-stacks: https://github.com/jupyter/docker-stacks\n\nContributing\n-------------\nIf you would like to contribute to the project, please read `contributor documentation `_.\n\nFor a **development install**, clone the `repository `_ and then install from source:\n\n.. code-block:: sh\n\n git clone https://github.com/cassiny/SwarmSpawner\n cd SwarmSpawner\n pip install -r requirements/base.txt -e .\n\n\nCredit\n=======\n`DockerSpawner `_\n\nLicense\n=======\nAll code is licensed under the terms of the revised BSD license.\n\n\n\n\n", "description_content_type": null, "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/cassinyio/SwarmSpawner", "keywords": "Interactive,Interpreter,Shell,Web", "license": "BSD", "maintainer": "", "maintainer_email": "", "name": "swarmspawner", "package_url": "https://pypi.org/project/swarmspawner/", "platform": "", "project_url": "https://pypi.org/project/swarmspawner/", "project_urls": { "Homepage": "https://github.com/cassinyio/SwarmSpawner" }, "release_url": "https://pypi.org/project/swarmspawner/0.1.0/", "requires_dist": [ "docker (>=2.0.2)", "jupyterhub (>=0.7.2)" ], "requires_python": "", "summary": " SwarmSpawner: A spawner for JupyterHub that uses Docker Swarm's services", "version": "0.1.0" }, "last_serial": 3092281, "releases": { "0.0.2": [ { "comment_text": "", "digests": { "md5": "d18bdf3805f82787cae20c6b7a82a795", "sha256": "47e84a53867d552080b481961dfdfc24df826f03cc997d50462e5b88de315c5b" }, "downloads": -1, "filename": "swarmspawner-0.0.2-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "d18bdf3805f82787cae20c6b7a82a795", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 11165, "upload_time": "2017-02-08T01:00:43", "url": "https://files.pythonhosted.org/packages/b9/20/3eda123747101779ab5b514e55cdac3dba3c6f7c90209e5ca48558dc2a96/swarmspawner-0.0.2-py2.py3-none-any.whl" } ], "0.0.3": [ { "comment_text": "", "digests": { "md5": "5eadeb417dd52cd8780e99e272ffee1f", "sha256": "c4c122762bfa5fa390679d68664e9f6eee0bba5e82235017061ae33cc1ea9509" }, "downloads": -1, "filename": "swarmspawner-0.0.3-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "5eadeb417dd52cd8780e99e272ffee1f", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 11139, "upload_time": "2017-02-08T01:17:17", "url": "https://files.pythonhosted.org/packages/33/4b/9c92eb9efc5f38f56ce4515cf9176525f9ff574c972e6d9740e0b8a8fe37/swarmspawner-0.0.3-py2.py3-none-any.whl" } ], "0.1.0": [ { "comment_text": "", "digests": { "md5": "f37e6eb17038d81664f5bed990fee8e2", "sha256": "5a8046cfb921e1af25f8a56fdabc056736dd10f38e45a210c240cebb426a9d41" }, "downloads": -1, "filename": "swarmspawner-0.1.0-py3-none-any.whl", "has_sig": false, "md5_digest": "f37e6eb17038d81664f5bed990fee8e2", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 12068, "upload_time": "2017-08-12T14:49:03", "url": "https://files.pythonhosted.org/packages/60/ac/418d2d1ad7a40b351f776da4ec4c730d5677c69d94c17e17f70fcf66b4ac/swarmspawner-0.1.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "35391ef7f5963568f02d26fb02f16e47", "sha256": "0d194f03a8899b6ca645c13177d1a627d2399ddaf01256050d1c8b856a5c51d4" }, "downloads": -1, "filename": "swarmspawner-0.1.0.tar.gz", "has_sig": false, "md5_digest": "35391ef7f5963568f02d26fb02f16e47", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8455, "upload_time": "2017-08-12T14:49:04", "url": "https://files.pythonhosted.org/packages/20/61/ed8f82498e874fdf1941f24777dae9e3234dd5edb5367af8891f8892e66f/swarmspawner-0.1.0.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "f37e6eb17038d81664f5bed990fee8e2", "sha256": "5a8046cfb921e1af25f8a56fdabc056736dd10f38e45a210c240cebb426a9d41" }, "downloads": -1, "filename": "swarmspawner-0.1.0-py3-none-any.whl", "has_sig": false, "md5_digest": "f37e6eb17038d81664f5bed990fee8e2", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 12068, "upload_time": "2017-08-12T14:49:03", "url": "https://files.pythonhosted.org/packages/60/ac/418d2d1ad7a40b351f776da4ec4c730d5677c69d94c17e17f70fcf66b4ac/swarmspawner-0.1.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "35391ef7f5963568f02d26fb02f16e47", "sha256": "0d194f03a8899b6ca645c13177d1a627d2399ddaf01256050d1c8b856a5c51d4" }, "downloads": -1, "filename": "swarmspawner-0.1.0.tar.gz", "has_sig": false, "md5_digest": "35391ef7f5963568f02d26fb02f16e47", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8455, "upload_time": "2017-08-12T14:49:04", "url": "https://files.pythonhosted.org/packages/20/61/ed8f82498e874fdf1941f24777dae9e3234dd5edb5367af8891f8892e66f/swarmspawner-0.1.0.tar.gz" } ] }