├── .gitignore ├── .mdlrc ├── .github ├── autolabeler.yml ├── FUNDING.yml ├── CODEOWNERS ├── PULL_REQUEST_TEMPLATE.md ├── invite-contributors.yml ├── ISSUE_TEMPLATE.md ├── potential-duplicates.yml ├── move.yml ├── lock.yml ├── no-response.yml ├── support.yml ├── stale.yml ├── config.yml └── settings.yml ├── jupyterlab ├── rootfs │ └── etc │ │ ├── pip.conf │ │ ├── cont-init.d │ │ ├── 10-requirements.sh │ │ ├── 81-user-scripts.sh │ │ ├── 80-system-packages.sh │ │ ├── 51-github.sh │ │ ├── 11-nginx.sh │ │ ├── 21-persistent-storage.sh │ │ └── 20-notebooks-dir.sh │ │ ├── services.d │ │ ├── nginx │ │ │ ├── finish │ │ │ └── run │ │ └── jupyter │ │ │ ├── finish │ │ │ └── run │ │ ├── jupyter │ │ └── jupyter_notebook_config.py │ │ └── nginx │ │ ├── nginx.conf │ │ ├── nginx-ssl.conf │ │ └── ha-auth.lua ├── icon.png ├── logo.png ├── build.json ├── requirements.txt ├── config.json ├── .README.j2 ├── Dockerfile └── DOCS.md ├── images └── screenshot.png ├── renovate.json ├── .editorconfig ├── .gitlab-ci.yml ├── LICENSE.md ├── CONTRIBUTING.md ├── .yamllint ├── CODE_OF_CONDUCT.md └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.mdlrc: -------------------------------------------------------------------------------- 1 | rules "~MD024" -------------------------------------------------------------------------------- /.github/autolabeler.yml: -------------------------------------------------------------------------------- 1 | --- 2 | "Type: Documentation": ["*.md", "*.j2"] 3 | -------------------------------------------------------------------------------- /jupyterlab/rootfs/etc/pip.conf: -------------------------------------------------------------------------------- 1 | [global] 2 | extra-index-url=https://www.piwheels.org/simple 3 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | --- 2 | github: frenck 3 | patreon: frenck 4 | custom: https://frenck.dev/donate/ 5 | -------------------------------------------------------------------------------- /jupyterlab/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/basnijholt/addon-jupyterlab-lite/master/jupyterlab/icon.png -------------------------------------------------------------------------------- /jupyterlab/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/basnijholt/addon-jupyterlab-lite/master/jupyterlab/logo.png -------------------------------------------------------------------------------- /images/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/basnijholt/addon-jupyterlab-lite/master/images/screenshot.png -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | # Require maintainer's :+1: for changes to the .github/ repo-config files 2 | # mainly due to https://github.com/probot/settings privilege escalation 3 | .github/* @frenck 4 | .gitlab-ci.yml @frenck 5 | -------------------------------------------------------------------------------- /jupyterlab/build.json: -------------------------------------------------------------------------------- 1 | { 2 | "build_from": { 3 | "aarch64": "hassioaddons/debian-base-aarch64:3.2.0", 4 | "amd64": "hassioaddons/debian-base-amd64:3.2.0", 5 | "armv7": "hassioaddons/debian-base-armv7:3.2.0" 6 | }, 7 | "args": {} 8 | } 9 | -------------------------------------------------------------------------------- /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ 3 | "config:base" 4 | ], 5 | "commitMessageAction": "Updates", 6 | "commitMessageTopic": "{{depName}}", 7 | "commitMessagePrefix": ":arrow_up:", 8 | "labels": [ 9 | "Type: Maintenance" 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | # Proposed Changes 2 | 3 | > (Describe the changes and rationale behind them) 4 | 5 | ## Related Issues 6 | 7 | > ([Github link][autolink-references] to related issues or pull requests) 8 | 9 | [autolink-references]: https://help.github.com/articles/autolinked-references-and-urls/ -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | end_of_line = lf 6 | indent_style = space 7 | insert_final_newline = true 8 | trim_trailing_whitespace = true 9 | ident_size = 4 10 | 11 | [*.md] 12 | ident_size = 2 13 | trim_trailing_whitespace = false 14 | 15 | [*.json] 16 | ident_size = 2 17 | 18 | [{.gitignore,.gitkeep,.editorconfig}] 19 | ident_size = 2 20 | -------------------------------------------------------------------------------- /.github/invite-contributors.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # If true, this will add new contributors as outside collaborators 3 | # to the repo their PR was merged in. Team name is ignored if this 4 | # flag is set to true. 5 | isOutside: false 6 | 7 | # Specify team name to add new contributors to a specific team 8 | # within your organization. 9 | # Use team name or team-name-slug 10 | team: Contributors 11 | -------------------------------------------------------------------------------- /jupyterlab/rootfs/etc/cont-init.d/10-requirements.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/with-contenv bashio 2 | # ============================================================================== 3 | # Home Assistant Community Add-on: JupyterLab Lite 4 | # This files check if all user configuration requirements are met 5 | # ============================================================================== 6 | bashio::config.require.ssl 7 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | # Problem/Motivation 2 | 3 | > (Why the issue was filed) 4 | 5 | ## Expected behavior 6 | 7 | > (What you expected to happen) 8 | 9 | ## Actual behavior 10 | 11 | > (What actually happened) 12 | 13 | ## Steps to reproduce 14 | 15 | > (How can someone else make/see it happen) 16 | 17 | ## Proposed changes 18 | 19 | > (If you have a proposed change, workaround or fix, 20 | > describe the rationale behind it) 21 | -------------------------------------------------------------------------------- /jupyterlab/requirements.txt: -------------------------------------------------------------------------------- 1 | beautifulsoup4==4.9.3 2 | bokeh==2.2.3 3 | geopy==2.0.0 4 | HASS-data-detective==2.1 5 | influxdb==5.3.0 6 | ipywidgets==7.5.1 7 | jupyterlab_github==2.0.0 8 | jupyterlab_sql==0.3.3 9 | jupyterlab==2.2.9 10 | matplotlib==3.3.2 11 | mysqlclient==2.0.1 12 | nbconvert==5.6.1 13 | numpy==1.19.3 14 | pandas-datareader==0.9.0 15 | pandas==1.1.4 16 | psycopg2==2.8.6 17 | python-dateutil==2.8.1 18 | scrapy==2.4.0 19 | SQLAlchemy==1.3.20 20 | -------------------------------------------------------------------------------- /jupyterlab/rootfs/etc/services.d/nginx/finish: -------------------------------------------------------------------------------- 1 | #!/usr/bin/execlineb -S0 2 | # ============================================================================== 3 | # Home Assistant Community Add-on: JupyterLab Lite 4 | # Take down the S6 supervision tree when Nginx fails 5 | # ============================================================================== 6 | if -n { s6-test $# -ne 0 } 7 | if -n { s6-test ${1} -eq 256 } 8 | 9 | s6-svscanctl -t /var/run/s6/services 10 | -------------------------------------------------------------------------------- /jupyterlab/rootfs/etc/services.d/jupyter/finish: -------------------------------------------------------------------------------- 1 | #!/usr/bin/execlineb -S0 2 | # ============================================================================== 3 | # Home Assistant Community Add-on: JupyterLab Lite 4 | # Take down the S6 supervision tree when the Jupyter daemon fails 5 | # ============================================================================== 6 | if -n { s6-test $# -ne 0 } 7 | if -n { s6-test ${1} -eq 256 } 8 | 9 | s6-svscanctl -t /var/run/s6/services 10 | -------------------------------------------------------------------------------- /.github/potential-duplicates.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Label name and color to set, when potential duplicates are detected 3 | issueLabel: "Potential duplicate" 4 | labelColor: e6e6e6 5 | 6 | # If similarity is higher than this threshold, issue will be marked as duplicate 7 | threshold: 0.70 8 | 9 | # Comment to post when potential duplicates are detected 10 | referenceComment: > 11 | Potential duplicates found: 12 | {{#issues}} 13 | - [#{{ number }}] {{ title }} ({{ accuracy }}%) 14 | {{/issues}} 15 | -------------------------------------------------------------------------------- /.github/move.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Delete the command comment when it contains no other content 3 | deleteCommand: true 4 | 5 | # Close the source issue after moving 6 | closeSourceIssue: true 7 | 8 | # Lock the source issue after moving 9 | lockSourceIssue: true 10 | 11 | # Mention issue and comment authors 12 | mentionAuthors: true 13 | 14 | # Preserve mentions in the issue content 15 | keepContentMentions: false 16 | 17 | # Set custom aliases for targets 18 | # aliases: 19 | # r: repo 20 | # or: owner/repo 21 | -------------------------------------------------------------------------------- /.gitlab-ci.yml: -------------------------------------------------------------------------------- 1 | --- 2 | include: https://raw.githubusercontent.com/hassio-addons/organization/master/gitlabci/addon.yml 3 | 4 | variables: 5 | ADDON_GITHUB_REPO: "hassio-addons/addon-jupyterlab-lite" 6 | ADDON_SLUG: "jupyterlablite" 7 | ADDON_TARGET: "jupyterlab" 8 | ADDON_ARMHF: "false" 9 | ADDON_I386: "false" 10 | 11 | ADDON_AARCH64_BASE: "hassioaddons/debian-base-aarch64:3.2.0" 12 | ADDON_AMD64_BASE: "hassioaddons/debian-base-amd64:3.2.0" 13 | ADDON_ARMV7_BASE: "hassioaddons/debian-base-armv7:3.2.0" 14 | -------------------------------------------------------------------------------- /jupyterlab/rootfs/etc/cont-init.d/81-user-scripts.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/with-contenv bashio 2 | # ============================================================================== 3 | # Home Assistant Community Add-on: JupyterLab Lite 4 | # Executes user configured/requested commands on startup 5 | # ============================================================================== 6 | if bashio::config.has_value 'init_commands'; then 7 | while read -r cmd; do 8 | eval "${cmd}" \ 9 | || bashio::exit.nok "Failed executing init command: ${cmd}" 10 | done <<< "$(bashio::config 'init_commands')" 11 | fi 12 | -------------------------------------------------------------------------------- /jupyterlab/rootfs/etc/services.d/nginx/run: -------------------------------------------------------------------------------- 1 | #!/usr/bin/with-contenv bashio 2 | # ============================================================================== 3 | # Home Assistant Community Add-on: JupyterLab Lite 4 | # Runs the Nginx daemon 5 | # ============================================================================== 6 | 7 | # Wait for JupyterLab to become available 8 | s6-svwait -u -t 5000 /var/run/s6/services/jupyter 9 | timeout 15 \ 10 | bash -c \ 11 | 'until echo > /dev/tcp/localhost/28459 ; do sleep 0.5; done' \ 12 | > /dev/null 2>&1 13 | 14 | bashio::log.info "Starting NGinx..." 15 | 16 | exec nginx -g "daemon off;" 17 | -------------------------------------------------------------------------------- /.github/lock.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Configuration for lock-threads - https://github.com/dessant/lock-threads 3 | # Number of days of inactivity before a closed issue or pull request is locked 4 | daysUntilLock: 30 5 | 6 | # Comment to post before locking. Set to `false` to disable 7 | lockComment: > 8 | This thread has been automatically locked because it has not had recent 9 | activity. Please open a new issue for related bugs and link to relevant 10 | comments in this thread. 11 | 12 | # Issues or pull requests with these labels will not be locked 13 | # exemptLabels: 14 | # - no-locking 15 | 16 | # Limit to only `issues` or `pulls` 17 | # only: issues 18 | 19 | # Add a label when locking. Set to `false` to disable 20 | lockLabel: false 21 | -------------------------------------------------------------------------------- /jupyterlab/rootfs/etc/cont-init.d/80-system-packages.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/with-contenv bashio 2 | # ============================================================================== 3 | # Home Assistant Community Add-on: JupyterLab Lite 4 | # Install user configured/requested packages 5 | # ============================================================================== 6 | if bashio::config.has_value 'system_packages'; then 7 | apt-get update \ 8 | || bashio::exit.nok 'Failed updating Ubuntu packages repository indexes' 9 | 10 | for package in $(bashio::config 'system_packages'); do 11 | apt-get install -y --no-install-recommends "$package" \ 12 | || bashio::exit.nok "Failed installing package ${package}" 13 | done 14 | fi 15 | -------------------------------------------------------------------------------- /jupyterlab/rootfs/etc/cont-init.d/51-github.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/with-contenv bashio 2 | # ============================================================================== 3 | # Home Assistant Community Add-on: JupyterLab Lite 4 | # Install the users GitHub Access token into JupyterLab 5 | # ============================================================================== 6 | readonly CONFIG_PATH="/etc/jupyter/jupyter_notebook_config.py" 7 | 8 | # Set password 9 | if bashio::config.has_value 'github_access_token'; then 10 | token=$(bashio::config 'github_access_token') 11 | sed -i "s/c.GitHubConfig.access_token\\ .*/c.GitHubConfig.access_token\\ =\\ '${token}'/" "${CONFIG_PATH}" \ 12 | || bashio::exit.nok 'Failed setting up GitHub access token' 13 | fi 14 | -------------------------------------------------------------------------------- /.github/no-response.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Configuration for probot-no-response - https://github.com/probot/no-response 3 | # Number of days of inactivity before an Issue is closed for lack of response 4 | daysUntilClose: 14 5 | # Label requiring a response 6 | responseRequiredLabel: "Status: Awaiting response" 7 | # Comment to post when closing an Issue for lack of response. Set to `false` to disable 8 | closeComment: > 9 | This issue has been automatically closed because there has been no response 10 | to our request for more information from the original author. With only the 11 | information that is currently in the issue, we don't have enough information 12 | to take action. Please reach out if you have or find the answers we need so 13 | that we can investigate further. 14 | -------------------------------------------------------------------------------- /jupyterlab/rootfs/etc/cont-init.d/11-nginx.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/with-contenv bashio 2 | # ============================================================================== 3 | # Home Assistant Community Add-on: JupyterLab Lite 4 | # Configures NGINX for use with JupyterLab 5 | # ============================================================================== 6 | declare certfile 7 | declare keyfile 8 | declare dns_host 9 | 10 | mkdir -p /var/log/nginx 11 | 12 | if bashio::config.true 'ssl'; then 13 | rm /etc/nginx/nginx.conf 14 | mv /etc/nginx/nginx-ssl.conf /etc/nginx/nginx.conf 15 | 16 | certfile=$(bashio::config 'certfile') 17 | keyfile=$(bashio::config 'keyfile') 18 | 19 | sed -i "s#%%certfile%%#${certfile}#g" /etc/nginx/nginx.conf 20 | sed -i "s#%%keyfile%%#${keyfile}#g" /etc/nginx/nginx.conf 21 | fi 22 | 23 | dns_host=$(bashio::dns.host) 24 | sed -i "s/%%dns_host%%/${dns_host}/g" /etc/nginx/nginx.conf 25 | -------------------------------------------------------------------------------- /.github/support.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Configuration for support-requests - https://github.com/dessant/support-requests 3 | 4 | # Label used to mark issues as support requests 5 | supportLabel: "Type: Support" 6 | 7 | # Comment to post on issues marked as support requests. Add a link 8 | # to a support page, or set to `false` to disable 9 | supportComment: > 10 | :wave: We use the issue tracker exclusively for bug reports and feature requests. 11 | However, this issue appears to be a support request. Please use our 12 | support channels to get help with the project. 13 | 14 | Head over to the 15 | [Home Assistant community forum](https://community.home-assistant.io/t/home-assistant-community-add-on-jupyterlab-lite/87337?u=frenck) 16 | or join our [Discord](https://discord.me/hassioaddons) chat. 17 | 18 | # Close issues marked as support requests 19 | close: true 20 | 21 | # Lock issues marked as support requests 22 | lock: false 23 | -------------------------------------------------------------------------------- /jupyterlab/rootfs/etc/cont-init.d/21-persistent-storage.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/with-contenv bashio 2 | # ============================================================================== 3 | # Home Assistant Community Add-on: JupyterLab Lite 4 | # Ensure directories in the persistent storage exists 5 | # ============================================================================== 6 | if ! bashio::fs.directory_exists '/data/user-settings'; then 7 | mkdir -p /data/user-settings \ 8 | || bashio::exit.nok \ 9 | 'Failed creating persistent user-settings directory' 10 | fi 11 | 12 | if ! bashio::fs.directory_exists '/data/workspaces'; then 13 | mkdir -p /data/workspaces \ 14 | || bashio::exit.nok \ 15 | 'Failed creating persistent workspaces directory' 16 | fi 17 | 18 | if ! bashio::fs.directory_exists '/data/local'; then 19 | mkdir -p /data/local \ 20 | || bashio::exit.nok \ 21 | 'Failed creating persistent local directory' 22 | fi 23 | ln -s /data/local /root/.local 24 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | # MIT License 2 | 3 | Copyright (c) 2018-2020 Franck Nijhof 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /jupyterlab/rootfs/etc/jupyter/jupyter_notebook_config.py: -------------------------------------------------------------------------------- 1 | # Configuration file for ipython-notebook. 2 | 3 | c = get_config() 4 | 5 | # ------------------------------------------------------------------------------ 6 | # NotebookApp configuration 7 | # ------------------------------------------------------------------------------ 8 | 9 | c.GitHubConfig.access_token = '' 10 | c.JupyterApp.answer_yes = True 11 | c.LabApp.user_settings_dir = '/data/user-settings' 12 | c.LabApp.workspaces_dir = '/data/workspaces' 13 | c.NotebookApp.allow_origin = '*' 14 | c.NotebookApp.allow_password_change = False 15 | c.NotebookApp.allow_remote_access = True 16 | c.NotebookApp.allow_root = True 17 | c.NotebookApp.base_url = '/' 18 | c.NotebookApp.ip = '127.0.0.1' 19 | c.NotebookApp.notebook_dir = '/config/notebooks' 20 | c.NotebookApp.open_browser = False 21 | c.NotebookApp.password = '' 22 | c.NotebookApp.port = 28459 23 | c.NotebookApp.token = '' 24 | c.NotebookApp.tornado_settings = {'static_url_prefix': '/static/'} 25 | c.NotebookApp.trust_xheaders = True 26 | c.NotebookApp.tornado_settings = { 27 | 'headers': { 28 | 'Content-Security-Policy': "frame-ancestors *" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /jupyterlab/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "JupyterLab Lite", 3 | "version": "dev", 4 | "slug": "jupyterlablite", 5 | "description": "Create documents containing live code, equations, visualizations, and explanatory text", 6 | "url": "https://github.com/hassio-addons/addon-jupyterlab-lite", 7 | "webui": "[PROTO:ssl]://[HOST]:[PORT:7777]", 8 | "startup": "application", 9 | "arch": ["aarch64", "amd64", "armv7"], 10 | "boot": "auto", 11 | "hassio_api": true, 12 | "auth_api": true, 13 | "hassio_role": "default", 14 | "homeassistant_api": true, 15 | "host_network": false, 16 | "ports": { 17 | "7777/tcp": 7777 18 | }, 19 | "map": ["config:rw", "share:rw", "ssl"], 20 | "options": { 21 | "github_access_token": "", 22 | "ssl": false, 23 | "certfile": "fullchain.pem", 24 | "keyfile": "privkey.pem", 25 | "system_packages": [], 26 | "init_commands": [] 27 | }, 28 | "schema": { 29 | "log_level": "list(trace|debug|info|notice|warning|error|fatal)?", 30 | "github_access_token": "password", 31 | "ssl": "bool", 32 | "certfile": "str", 33 | "keyfile": "str", 34 | "system_packages": ["str"], 35 | "init_commands": ["str"] 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | When contributing to this repository, please first discuss the change you wish 4 | to make via issue, email, or any other method with the owners of this repository 5 | before making a change. 6 | 7 | Please note we have a code of conduct, please follow it in all your interactions 8 | with the project. 9 | 10 | ## Issues and feature requests 11 | 12 | You've found a bug in the source code, a mistake in the documentation or maybe 13 | you'd like a new feature? You can help us by submitting an issue to our 14 | [GitHub Repository][github]. Before you create an issue, make sure you search 15 | the archive, maybe your question was already answered. 16 | 17 | Even better: You could submit a pull request with a fix / new feature! 18 | 19 | ## Pull request process 20 | 21 | 1. Search our repository for open or closed [pull requests][prs] that relates 22 | to your submission. You don't want to duplicate effort. 23 | 24 | 1. You may merge the pull request in once you have the sign-off of two other 25 | developers, or if you do not have permission to do that, you may request 26 | the second reviewer to merge it for you. 27 | 28 | [github]: https://github.com/hassio-addons/addon-jupyterlab-lite/issues 29 | [prs]: https://github.com/hassio-addons/addon-jupyterlab-lite/pulls 30 | -------------------------------------------------------------------------------- /jupyterlab/rootfs/etc/services.d/jupyter/run: -------------------------------------------------------------------------------- 1 | #!/usr/bin/with-contenv bashio 2 | # shellcheck disable=SC2191 3 | # ============================================================================== 4 | # Home Assistant Community Add-on: JupyterLab Lite 5 | # Runs Jupyter 6 | # ============================================================================== 7 | declare -a options 8 | 9 | bashio::log.info 'Starting the Jupyter server...' 10 | 11 | # Find the matching Jupyter log level 12 | if bashio::config.exists 'log_level'; then 13 | case "$(bashio::string.lower "$(bashio::config 'log_level')")" in 14 | all|trace|debug) 15 | options+=(--log-level='DEBUG') 16 | ;; 17 | info|notice) 18 | options+=(--log-level='INFO') 19 | ;; 20 | warning) 21 | options+=(--log-level='WARN') 22 | ;; 23 | error) 24 | options+=(--log-level='ERROR') 25 | ;; 26 | fatal|off) 27 | options+=(--log-level='CRITICAL') 28 | ;; 29 | esac 30 | else 31 | options+=(--log-level='INFO') 32 | fi 33 | 34 | # Change current working directory 35 | cd /config/notebooks || bashio::exit.nok 'Failed changing working directory' 36 | 37 | # Run Juypter Notebook server 38 | exec jupyter lab "${options[@]}" 39 | -------------------------------------------------------------------------------- /.yamllint: -------------------------------------------------------------------------------- 1 | --- 2 | rules: 3 | braces: 4 | level: error 5 | min-spaces-inside: 0 6 | max-spaces-inside: 1 7 | min-spaces-inside-empty: -1 8 | max-spaces-inside-empty: -1 9 | brackets: 10 | level: error 11 | min-spaces-inside: 0 12 | max-spaces-inside: 0 13 | min-spaces-inside-empty: -1 14 | max-spaces-inside-empty: -1 15 | colons: 16 | level: error 17 | max-spaces-before: 0 18 | max-spaces-after: 1 19 | commas: 20 | level: error 21 | max-spaces-before: 0 22 | min-spaces-after: 1 23 | max-spaces-after: 1 24 | comments: 25 | level: error 26 | require-starting-space: true 27 | min-spaces-from-content: 2 28 | comments-indentation: 29 | level: error 30 | document-end: 31 | level: error 32 | present: false 33 | document-start: 34 | level: error 35 | present: true 36 | empty-lines: 37 | level: error 38 | max: 1 39 | max-start: 0 40 | max-end: 1 41 | hyphens: 42 | level: error 43 | max-spaces-after: 1 44 | indentation: 45 | level: error 46 | spaces: 2 47 | indent-sequences: true 48 | check-multi-line-strings: false 49 | key-duplicates: 50 | level: error 51 | line-length: 52 | ignore: | 53 | .github/support.yml 54 | level: warning 55 | max: 120 56 | allow-non-breakable-words: true 57 | allow-non-breakable-inline-mappings: true 58 | new-line-at-end-of-file: 59 | level: error 60 | new-lines: 61 | level: error 62 | type: unix 63 | trailing-spaces: 64 | level: error 65 | truthy: 66 | level: error 67 | -------------------------------------------------------------------------------- /jupyterlab/rootfs/etc/nginx/nginx.conf: -------------------------------------------------------------------------------- 1 | worker_processes 1; 2 | pid /var/run/nginx.pid; 3 | error_log stderr; 4 | env SUPERVISOR_TOKEN; 5 | env DISABLE_HA_AUTHENTICATION; 6 | load_module "/usr/lib/nginx/modules/ndk_http_module.so"; 7 | load_module "/usr/lib/nginx/modules/ngx_http_lua_module.so"; 8 | 9 | events { 10 | worker_connections 1024; 11 | } 12 | 13 | http { 14 | access_log stdout; 15 | include mime.types; 16 | default_type application/octet-stream; 17 | sendfile on; 18 | keepalive_timeout 65; 19 | lua_shared_dict auths 16k; 20 | resolver %%dns_host%%; 21 | 22 | upstream jupyter { 23 | ip_hash; 24 | server 127.0.0.1:28459; 25 | } 26 | 27 | map $http_upgrade $connection_upgrade { 28 | default upgrade; 29 | '' close; 30 | } 31 | 32 | server { 33 | server_name hassio.local; 34 | listen 7777 default_server; 35 | root /dev/null; 36 | 37 | location / { 38 | access_by_lua_file /etc/nginx/ha-auth.lua; 39 | 40 | proxy_redirect off; 41 | proxy_pass http://jupyter; 42 | 43 | proxy_http_version 1.1; 44 | proxy_set_header Upgrade $http_upgrade; 45 | proxy_set_header Connection $connection_upgrade; 46 | proxy_set_header Authorization ""; 47 | 48 | proxy_set_header X-Real-IP $remote_addr; 49 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 50 | proxy_set_header X-Forwarded-Proto $scheme; 51 | proxy_set_header Host $http_host; 52 | proxy_set_header X-NginX-Proxy true; 53 | proxy_read_timeout 86400s; 54 | proxy_send_timeout 86400s; 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /jupyterlab/rootfs/etc/cont-init.d/20-notebooks-dir.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/with-contenv bashio 2 | # ============================================================================== 3 | # Home Assistant Community Add-on: JupyterLab Lite 4 | # Ensures the JupyterLab notebooks directory exists 5 | # ============================================================================== 6 | readonly BOOKS="/config/notebooks/" 7 | 8 | if ! bashio::fs.directory_exists '/config/notebooks'; then 9 | mkdir -p /config/notebooks \ 10 | || bashio::exit.nok 'Failed creating notebooks directory' 11 | 12 | git clone -b master --single-branch \ 13 | https://github.com/home-assistant/home-assistant-notebooks.git \ 14 | "${BOOKS}home-assistant" \ 15 | || bashio::exit.nok \ 16 | 'Failed installing Home Assistant example notebooks' 17 | 18 | git clone -b master --single-branch --depth 1 \ 19 | https://github.com/bokeh/bokeh-notebooks.git \ 20 | "${BOOKS}bokeh-examples" \ 21 | || bashio::exit.nok \ 22 | 'Failed installing Bokeh example notebooks' 23 | 24 | ln -sf \ 25 | "${BOOKS}home-assistant/~ GETTING STARTED.ipynb" \ 26 | "${BOOKS}GETTING STARTED.ipynb" 27 | 28 | else 29 | if [ -z "$(git -C ${BOOKS}/home-assistant status --untracked-files=no --porcelain)" ]; 30 | then 31 | git -C "${BOOKS}home-assistant" pull 32 | else 33 | bashio::log.warning "Not updating Home Assistant notebook!" 34 | bashio::log.warning \ 35 | "You have made local changes, which we will not overwrite." 36 | fi 37 | 38 | if [ -z "$(git -C ${BOOKS}/bokeh-examples status --untracked-files=no --porcelain)" ]; 39 | then 40 | git -C "${BOOKS}bokeh-examples" pull 41 | else 42 | bashio::log.warning "Not updating Bokeh examples notebook!" 43 | bashio::log.warning \ 44 | "You have made local changes, which we will not overwrite." 45 | fi 46 | fi 47 | -------------------------------------------------------------------------------- /.github/stale.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Configuration for probot-stale - https://github.com/probot/stale 3 | 4 | # Number of days of inactivity before an Issue or Pull Request becomes stale 5 | daysUntilStale: 60 6 | 7 | # Number of days of inactivity before a stale Issue or Pull Request is closed. 8 | # Set to false to disable. If disabled, issues still need to be closed manually, but will remain marked as stale. 9 | daysUntilClose: 7 10 | 11 | # Issues or Pull Requests with these labels will never be considered stale. Set to `[]` to disable 12 | exemptLabels: 13 | - "Status: On hold" 14 | - "Status: In progress" 15 | - "Status: Awaiting response" 16 | - "Status: Blocked" 17 | - "Idea" 18 | - "Security" 19 | 20 | # Set to true to ignore issues in a project (defaults to false) 21 | exemptProjects: false 22 | 23 | # Set to true to ignore issues in a milestone (defaults to false) 24 | exemptMilestones: false 25 | 26 | # Label to use when marking as stale 27 | staleLabel: "Status: Stale" 28 | 29 | # Comment to post when marking as stale. Set to `false` to disable 30 | markComment: > 31 | This issue has been automatically marked as stale because it has not had 32 | recent activity. It will be closed if no further activity occurs. Thank you 33 | for your contributions. 34 | 35 | # Comment to post when removing the stale label. 36 | # unmarkComment: > 37 | # Your comment here. 38 | unmarkComment: false 39 | 40 | # Comment to post when closing a stale Issue or Pull Request. 41 | # closeComment: > 42 | # Your comment here. 43 | closeComment: false 44 | 45 | # Limit the number of actions per hour, from 1-30. Default is 30 46 | limitPerRun: 30 47 | 48 | # Limit to only `issues` or `pulls` 49 | only: issues 50 | 51 | # Optionally, specify configuration settings that are specific to just 'issues' or 'pulls': 52 | # pulls: 53 | # daysUntilStale: 30 54 | # markComment: > 55 | # This pull request has been automatically marked as stale because it has not had 56 | # recent activity. It will be closed if no further activity occurs. Thank you 57 | # for your contributions. 58 | 59 | # issues: 60 | # exemptLabels: 61 | # - confirmed 62 | -------------------------------------------------------------------------------- /.github/config.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Configuration for request-info - https://github.com/behaviorbot/request-info 3 | 4 | # *OPTIONAL* Comment to reply with 5 | # Can be either a string : 6 | requestInfoReplyComment: 7 | - "We would appreciate it if you could provide us with more info about this issue/pr!" 8 | - "Hmmm... That issue/PR is kinda low on text. Could you please provide some more content?" 9 | 10 | # *OPTIONAL* default titles to check against for lack of descriptiveness 11 | # MUST BE ALL LOWERCASE 12 | requestInfoDefaultTitles: [] 13 | 14 | # *OPTIONAL* Label to be added to Issues and Pull Requests with insufficient information given 15 | requestInfoLabelToAdd: "Incomplete" 16 | 17 | # *OPTIONAL* Require Pull Requests to contain more information than what is provided in the PR template 18 | # Will fail if the pull request's body is equal to the provided template 19 | checkPullRequestTemplate: true 20 | 21 | # *OPTIONAL* Only warn about insufficient information on these events type 22 | # Keys must be lowercase. Valid values are 'issue' and 'pullRequest' 23 | requestInfoOn: 24 | pullRequest: true 25 | issue: true 26 | 27 | # *OPTIONAL* Add a list of people whose Issues/PRs will not be commented on 28 | # keys must be GitHub usernames 29 | requestInfoUserstoExclude: [] 30 | 31 | # Configuration for new-issue-welcome - https://github.com/behaviorbot/new-issue-welcome 32 | 33 | # Comment to be posted to on first time issues 34 | newIssueWelcomeComment: > 35 | :wave: Thanks for opening your first issue here! 36 | If you're reporting a :bug: bug, please make sure you include steps to reproduce it. 37 | Also, logs, error messages and information about your hardware might be useful. 38 | 39 | # Configuration for new-pr-welcome - https://github.com/behaviorbot/new-pr-welcome 40 | 41 | # Comment to be posted to on PRs from first time contributors in your repository 42 | newPRWelcomeComment: > 43 | :sparkling_heart: Thanks for opening this pull request! :sparkling_heart: 44 | If your PR gets accepted and merged in, we will invite you to the project :tada: 45 | 46 | # Configuration for first-pr-merge - https://github.com/behaviorbot/first-pr-merge 47 | 48 | # Comment to be posted to on pull requests merged by a first time user 49 | firstPRMergeComment: > 50 | Congrats on merging your first pull request! :tada::tada::tada: 51 | -------------------------------------------------------------------------------- /jupyterlab/rootfs/etc/nginx/nginx-ssl.conf: -------------------------------------------------------------------------------- 1 | worker_processes 1; 2 | pid /var/run/nginx.pid; 3 | error_log stderr; 4 | env SUPERVISOR_TOKEN; 5 | env DISABLE_HA_AUTHENTICATION; 6 | load_module "/usr/lib/nginx/modules/ndk_http_module.so"; 7 | load_module "/usr/lib/nginx/modules/ngx_http_lua_module.so"; 8 | 9 | events { 10 | worker_connections 1024; 11 | } 12 | 13 | http { 14 | access_log stdout; 15 | include mime.types; 16 | default_type application/octet-stream; 17 | sendfile on; 18 | keepalive_timeout 65; 19 | lua_shared_dict auths 16k; 20 | resolver %%dns_host%%; 21 | 22 | upstream jupyter { 23 | ip_hash; 24 | server 127.0.0.1:28459; 25 | } 26 | 27 | map $http_upgrade $connection_upgrade { 28 | default upgrade; 29 | '' close; 30 | } 31 | 32 | server { 33 | server_name hassio.local; 34 | listen 7777 default_server ssl; 35 | root /dev/null; 36 | 37 | ssl_certificate /ssl/%%certfile%%; 38 | ssl_certificate_key /ssl/%%keyfile%%; 39 | ssl_protocols TLSv1.2; 40 | ssl_prefer_server_ciphers on; 41 | ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:DHE-RSA-AES256-SHA; 42 | ssl_ecdh_curve secp384r1; 43 | ssl_session_timeout 10m; 44 | ssl_session_cache shared:SSL:10m; 45 | ssl_session_tickets off; 46 | ssl_stapling on; 47 | ssl_stapling_verify on; 48 | 49 | add_header X-Content-Type-Options nosniff; 50 | add_header X-XSS-Protection "1; mode=block"; 51 | add_header X-Robots-Tag none; 52 | 53 | location / { 54 | access_by_lua_file /etc/nginx/ha-auth.lua; 55 | 56 | proxy_redirect off; 57 | proxy_pass http://jupyter; 58 | 59 | proxy_http_version 1.1; 60 | proxy_set_header Upgrade $http_upgrade; 61 | proxy_set_header Connection $connection_upgrade; 62 | proxy_set_header Authorization ""; 63 | 64 | proxy_set_header X-Real-IP $remote_addr; 65 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 66 | proxy_set_header X-Forwarded-Proto $scheme; 67 | proxy_set_header Host $http_host; 68 | proxy_set_header X-NginX-Proxy true; 69 | proxy_read_timeout 86400s; 70 | proxy_send_timeout 86400s; 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /jupyterlab/rootfs/etc/nginx/ha-auth.lua: -------------------------------------------------------------------------------- 1 | local http = require "resty.http" 2 | local auths = ngx.shared.auths 3 | 4 | function authenticate() 5 | 6 | --- Test Authentication header is set and with a value 7 | local header = ngx.req.get_headers()['Authorization'] 8 | if header == nil or header:find(" ") == nil then 9 | return false 10 | end 11 | 12 | local divider = header:find(' ') 13 | if header:sub(0, divider-1) ~= 'Basic' then 14 | return false 15 | end 16 | 17 | local auth = ngx.decode_base64(header:sub(divider+1)) 18 | if auth == nil or auth:find(':') == nil then 19 | return false 20 | end 21 | 22 | divider = auth:find(':') 23 | local username = auth:sub(0, divider-1) 24 | local password = auth:sub(divider+1) 25 | 26 | --- Check if authentication is cached 27 | if auths:get(username) == password then 28 | ngx.log(ngx.DEBUG, "Authenticated user against Home Assistant (cache).") 29 | return true 30 | end 31 | 32 | --- HTTP request against the Supervisor API 33 | local httpc = http.new() 34 | local res, err = httpc:request_uri("http://supervisor.local.hass.io/auth", { 35 | method = "POST", 36 | body = ngx.encode_args({["username"]=username, ["password"]=password}), 37 | headers = { 38 | ["Content-Type"] = "application/x-www-form-urlencoded", 39 | ["X-Supervisor-Token"] = os.getenv("SUPERVISOR_TOKEN"), 40 | }, 41 | keepalive_timeout = 60, 42 | keepalive_pool = 10 43 | }) 44 | 45 | --- Error during API request 46 | if err then 47 | ngx.log(ngx.WARN, "Error during Home Assistant user authentication.", err) 48 | return false 49 | end 50 | 51 | --- No result? Something went wrong... 52 | if not res then 53 | ngx.log(ngx.WARN, "Error during Home Assistant user authentication.") 54 | return false 55 | end 56 | 57 | --- Valid response, the username/password is valid 58 | if res.status == 200 then 59 | ngx.log(ngx.INFO, "Authenticated user against Home Assistant.") 60 | auths:set(username, password, 60) 61 | return true 62 | end 63 | 64 | --- Whatever the response is, it is invalid 65 | ngx.log(ngx.WARN, "Authentication against Home Assistant failed!") 66 | return false 67 | end 68 | 69 | -- Only authenticate if its not disabled 70 | if not os.getenv('DISABLE_HA_AUTHENTICATION') then 71 | 72 | --- Try to authenticate against HA 73 | local authenticated = authenticate() 74 | 75 | --- If authentication failed, throw a basic auth 76 | if not authenticated then 77 | ngx.header.content_type = 'text/plain' 78 | ngx.header.www_authenticate = 'Basic realm="Home Assistant"' 79 | ngx.status = ngx.HTTP_UNAUTHORIZED 80 | ngx.say('401 Access Denied') 81 | ngx.exit(ngx.HTTP_UNAUTHORIZED) 82 | end 83 | end 84 | -------------------------------------------------------------------------------- /jupyterlab/.README.j2: -------------------------------------------------------------------------------- 1 | # Home Assistant Community Add-on: JupyterLab Lite 2 | 3 | [![Release][release-shield]][release] ![Project Stage][project-stage-shield] ![Project Maintenance][maintenance-shield] 4 | 5 | [![Discord][discord-shield]][discord] [![Community Forum][forum-shield]][forum] 6 | 7 | [![Sponsor Frenck via GitHub Sponsors][github-sponsors-shield]][github-sponsors] 8 | 9 | [![Support Frenck on Patreon][patreon-shield]][patreon] 10 | 11 | Create documents containing live code, equations, visualizations, 12 | and explanatory text. 13 | 14 | ![The JupyterLab add-on][screenshot] 15 | 16 | ## About 17 | 18 | JupyterLab is an open-source web application that allows you to create and share 19 | documents that contain live code, equations, visualizations and narrative text. 20 | Uses include: data cleaning and transformation, numerical simulation, 21 | statistical modeling, data visualization, machine learning, and much more. 22 | 23 | This add-on runs JupyterLab, which is the next-generation user interface for 24 | Project Jupyter. It is an extensible environment for interactive and 25 | reproducible computing, based on the Jupyter Notebook and Architecture. 26 | 27 | {% if channel == "edge" %} 28 | ## WARNING! THIS IS AN EDGE VERSION! 29 | 30 | This Home Assistant Add-ons repository contains edge builds of add-ons. 31 | Edge builds add-ons are based upon the latest development version. 32 | 33 | - They may not work at all. 34 | - They might stop working at any time. 35 | - They could have a negative impact on your system. 36 | 37 | This repository was created for: 38 | 39 | - Anybody willing to test. 40 | - Anybody interested in trying out upcoming add-ons or add-on features. 41 | - Developers. 42 | 43 | If you are more interested in stable releases of our add-ons: 44 | 45 | 46 | 47 | {% endif %} 48 | {% if channel == "beta" %} 49 | ## WARNING! THIS IS A BETA VERSION! 50 | 51 | This Home Assistant Add-ons repository contains beta releases of add-ons. 52 | 53 | - They might stop working at any time. 54 | - They could have a negative impact on your system. 55 | 56 | This repository was created for: 57 | 58 | - Anybody willing to test. 59 | - Anybody interested in trying out upcoming add-ons or add-on features. 60 | 61 | If you are more interested in stable releases of our add-ons: 62 | 63 | 64 | 65 | {% endif %} 66 | 67 | [discord-shield]: https://img.shields.io/discord/478094546522079232.svg 68 | [discord]: https://discord.me/hassioaddons 69 | [forum-shield]: https://img.shields.io/badge/community-forum-brightgreen.svg 70 | [forum]: https://community.home-assistant.io/t/home-assistant-community-add-on-jupyterlab-lite/87337?u=frenck 71 | [github-sponsors-shield]: https://frenck.dev/wp-content/uploads/2019/12/github_sponsor.png 72 | [github-sponsors]: https://github.com/sponsors/frenck 73 | [maintenance-shield]: https://img.shields.io/maintenance/yes/2020.svg 74 | [patreon-shield]: https://frenck.dev/wp-content/uploads/2019/12/patreon.png 75 | [patreon]: https://www.patreon.com/frenck 76 | [project-stage-shield]: https://img.shields.io/badge/project%20stage-experimental-yellow.svg 77 | [release-shield]: https://img.shields.io/badge/version-{{ version }}-blue.svg 78 | [release]: {{ repo }}/tree/{{ version }} 79 | [screenshot]: https://github.com/hassio-addons/addon-jupyterlab-lite/raw/master/images/screenshot.png 80 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Code of conduct 2 | 3 | ## Our pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to making participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, gender identity and expression, level of experience, 9 | nationality, personal appearance, race, religion, or sexual identity and 10 | orientation. 11 | 12 | ## Our standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | - Using welcoming and inclusive language 18 | - Being respectful of differing viewpoints and experiences 19 | - Gracefully accepting constructive criticism 20 | - Focusing on what is best for the community 21 | - Showing empathy towards other community members 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | - The use of sexualized language or imagery and unwelcome sexual attention 26 | or advances 27 | - Trolling, insulting/derogatory comments, and personal or political attacks 28 | - Public or private harassment 29 | - Publishing others' private information, such as a physical or 30 | electronic address, without explicit permission 31 | - Other conduct which could reasonably be considered inappropriate 32 | in a professional setting 33 | 34 | ## Our responsibilities 35 | 36 | Project maintainers are responsible for clarifying the standards of acceptable 37 | behavior and are expected to take appropriate and fair corrective action in 38 | response to any instances of unacceptable behavior. 39 | 40 | Project maintainers have the right and responsibility to remove, edit, or 41 | reject comments, commits, code, wiki edits, issues, and other contributions 42 | that are not aligned to this Code of Conduct, or to ban temporarily or 43 | permanently any contributor for other behaviors that they deem inappropriate, 44 | threatening, offensive, or harmful. 45 | 46 | ## Scope 47 | 48 | This Code of Conduct applies both within project spaces and in public spaces 49 | when an individual is representing the project or its community. Examples of 50 | representing a project or community include using an official project e-mail 51 | address, posting via an official social media account, or acting as an appointed 52 | representative at an online or offline event. Representation of a project may be 53 | further defined and clarified by project maintainers. 54 | 55 | ## Enforcement 56 | 57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 58 | reported by contacting the project lead at frenck@addons.community. All 59 | complaints will be reviewed and investigated and will result in a response that 60 | is deemed necessary and appropriate to the circumstances. The project lead is 61 | obligated to maintain confidentiality with regard to the reporter of an incident. 62 | Further details of specific enforcement policies may be posted separately. 63 | 64 | Project maintainers who do not follow or enforce the Code of Conduct in good 65 | faith may face temporary or permanent repercussions as determined by other 66 | members of the project's leadership. 67 | 68 | ## Attribution 69 | 70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], 71 | version 1.4, available at [http://contributor-covenant.org/version/1/4][version] 72 | 73 | [homepage]: http://contributor-covenant.org 74 | [version]: http://contributor-covenant.org/version/1/4/ 75 | -------------------------------------------------------------------------------- /jupyterlab/Dockerfile: -------------------------------------------------------------------------------- 1 | ARG BUILD_FROM=hassioaddons/debian-base:3.2.0 2 | # hadolint ignore=DL3006 3 | FROM ${BUILD_FROM} 4 | 5 | # Set shell 6 | SHELL ["/bin/bash", "-o", "pipefail", "-c"] 7 | 8 | # Copy Python requirements file 9 | COPY requirements.txt /opt/ 10 | COPY rootfs/etc/pip.conf /etc/pip.conf 11 | 12 | # Setup base 13 | # hadolint ignore=DL3018 14 | ARG BUILD_ARCH 15 | RUN \ 16 | MAKEFLAGS="-j$(nproc)" \ 17 | && export MAKEFLAGS \ 18 | \ 19 | && apt-get update \ 20 | && apt-get install -y --no-install-recommends \ 21 | build-essential=12.6 \ 22 | dirmngr=2.2.12-1+deb10u1 \ 23 | git=1:2.20.1-2+deb10u3 \ 24 | gpg-agent=2.2.12-1+deb10u1 \ 25 | gpg=2.2.12-1+deb10u1 \ 26 | libffi-dev=3.2.1-9 \ 27 | libffi6=3.2.1-9 \ 28 | libfreetype6-dev=2.9.1-3+deb10u1 \ 29 | libfreetype6=2.9.1-3+deb10u1 \ 30 | libjpeg62-turbo-dev=1:1.5.2-2+b1 \ 31 | libjpeg62-turbo=1:1.5.2-2+b1 \ 32 | libmariadb-dev=1:10.3.22-0+deb10u1 \ 33 | libmariadb3=1:10.3.22-0+deb10u1 \ 34 | libnginx-mod-http-lua=1.14.2-2+deb10u1 \ 35 | libpng-dev=1.6.36-6 \ 36 | libpng16-16=1.6.36-6 \ 37 | libpq-dev=11.7-0+deb10u1 \ 38 | libpq5=11.7-0+deb10u1 \ 39 | libssl-dev=1.1.1d-0+deb10u3 \ 40 | libtiff5-dev=4.1.0+git191117-2~deb10u1 \ 41 | libxml2-dev=2.9.4+dfsg1-7+b3 \ 42 | libxml2=2.9.4+dfsg1-7+b3 \ 43 | libxslt1-dev=1.1.32-2.2~deb10u1 \ 44 | libxslt1.1=1.1.32-2.2~deb10u1 \ 45 | libzmq3-dev=4.3.1-4+deb10u1 \ 46 | libzmq5=4.3.1-4+deb10u1 \ 47 | luarocks=2.4.2+dfsg-1 \ 48 | nginx=1.14.2-2+deb10u1 \ 49 | pandoc=2.2.1-3+b2 \ 50 | pkg-config=0.29-6 \ 51 | python-dev=2.7.16-1 \ 52 | python3-dev=3.7.3-1 \ 53 | python3-distutils=3.7.3-1 \ 54 | python3-minimal=3.7.3-1 \ 55 | zlib1g-dev=1:1.2.11.dfsg-1 \ 56 | \ 57 | && luarocks install lua-resty-http 0.15-0 \ 58 | \ 59 | && curl -sL https://deb.nodesource.com/setup_12.x | bash - \ 60 | \ 61 | && apt-get install -y --no-install-recommends \ 62 | nodejs=12.18.2-1nodesource1 \ 63 | \ 64 | && curl https://bootstrap.pypa.io/get-pip.py | python3 \ 65 | \ 66 | && update-alternatives \ 67 | --install /usr/bin/python python /usr/bin/python3 10 \ 68 | \ 69 | && pip3 install --no-cache-dir numpy==1.18.1 \ 70 | && pip3 install --no-cache-dir -r /opt/requirements.txt \ 71 | \ 72 | && jupyter labextension install \ 73 | @jupyter-widgets/jupyterlab-manager@2.0.0 --no-build \ 74 | && jupyter labextension install @bokeh/jupyter_bokeh --no-build \ 75 | && jupyter labextension install @jupyterlab/github --no-build \ 76 | && jupyter serverextension enable jupyterlab_sql --py --sys-prefix \ 77 | && jupyter lab build \ 78 | \ 79 | && apt-get purge -y --auto-remove \ 80 | build-essential \ 81 | dirmngr \ 82 | gpg \ 83 | gpg-agent \ 84 | libffi-dev \ 85 | libfreetype6-dev \ 86 | libjpeg62-turbo-dev \ 87 | libmariadb-dev \ 88 | libpng-dev \ 89 | libpq-dev \ 90 | libssl-dev \ 91 | libtiff5-dev \ 92 | libxml2-dev \ 93 | libxslt1-dev \ 94 | libzmq3-dev \ 95 | pkg-config \ 96 | python-dev \ 97 | python3-dev \ 98 | zlib1g-dev \ 99 | \ 100 | && find /usr/local/lib/python3.7/ -type d -name tests -depth -exec rm -rf {} \; \ 101 | && find /usr/local/lib/python3.7/ -type d -name test -depth -exec rm -rf {} \; \ 102 | && find /usr/local/lib/python3.7/ -name __pycache__ -depth -exec rm -rf {} \; \ 103 | && find /usr/local/lib/python3.7/ -name "*.pyc" -depth -exec rm -f {} \; \ 104 | \ 105 | && npm cache clean --force \ 106 | \ 107 | && rm -fr \ 108 | /tmp/* \ 109 | /root/{.cache,.config,.gnupg,.local,.log,.npm} \ 110 | /usr/local/share/.cache \ 111 | /var/{cache,log}/* \ 112 | /var/lib/apt/lists/* 113 | 114 | # Copy root filesystem 115 | COPY rootfs / 116 | 117 | # Build arguments 118 | ARG BUILD_DATE 119 | ARG BUILD_REF 120 | ARG BUILD_VERSION 121 | 122 | # Labels 123 | LABEL \ 124 | io.hass.name="JupyterLab Lite" \ 125 | io.hass.description="Create and share documents that contain live code, equations, visualizations, and explanatory text directly in your browser" \ 126 | io.hass.arch="${BUILD_ARCH}" \ 127 | io.hass.type="addon" \ 128 | io.hass.version=${BUILD_VERSION} \ 129 | maintainer="Franck Nijhof " \ 130 | org.opencontainers.image.title="JupyterLab Lite" \ 131 | org.opencontainers.image.description="Create and share documents that contain live code, equations, visualizations, and explanatory text directly in your browser" \ 132 | org.opencontainers.image.vendor="Home Assistant Community Add-ons" \ 133 | org.opencontainers.image.authors="Franck Nijhof " \ 134 | org.opencontainers.image.licenses="MIT" \ 135 | org.opencontainers.image.url="https://addons.community" \ 136 | org.opencontainers.image.source="https://github.com/hassio-addons/addon-jupyterlab-lite" \ 137 | org.opencontainers.image.documentation="https://github.com/hassio-addons/addon-jupyterlab-lite/blob/master/README.md" \ 138 | org.opencontainers.image.created=${BUILD_DATE} \ 139 | org.opencontainers.image.revision=${BUILD_REF} \ 140 | org.opencontainers.image.version=${BUILD_VERSION} 141 | -------------------------------------------------------------------------------- /.github/settings.yml: -------------------------------------------------------------------------------- 1 | --- 2 | repository: 3 | description: "JupyterLab Lite - Home Assistant Community Add-ons" 4 | homepage: https://addons.community 5 | topics: jupyter, jupyterlab, addon, addons, home-assistant, homeassistant 6 | private: false 7 | has_issues: true 8 | has_projects: false 9 | has_wiki: false 10 | has_downloads: false 11 | default_branch: master 12 | allow_squash_merge: true 13 | allow_merge_commit: false 14 | allow_rebase_merge: true 15 | labels: 16 | # Priority labels 17 | - name: "Priority: Critical" 18 | color: ee0701 19 | description: "This should be dealt with ASAP. Not fixing this issue would be a serious error." 20 | - name: "Priority: High" 21 | color: b60205 22 | description: "After critical issues are fixed, these should be dealt with before any further issues." 23 | - name: "Priority: Medium" 24 | color: 0e8a16 25 | description: "This issue may be useful, and needs some attention." 26 | - name: "Priority: Low" 27 | color: e4ea8a 28 | description: "Nice addition, maybe... someday..." 29 | 30 | # Type labels 31 | - name: "Type: Bug" 32 | color: ee0701 33 | description: "Inconsistencies or issues which will cause a problem for users or implementors." 34 | - name: "Type: Documentation" 35 | color: 0052cc 36 | description: "Solely about the documentation of the project." 37 | - name: "Type: Enhancement" 38 | color: 1d76db 39 | description: "Enhancement of the code, not introducing new features." 40 | - name: "Type: Feature" 41 | color: 0e8a16 42 | description: "New features or options." 43 | - name: "Type: Support" 44 | color: 5319e7 45 | description: "Marks an issue as a support ticket." 46 | - name: "Type: Discussion" 47 | color: d4c5f9 48 | description: "Marks an issue as a generic discussion ticket." 49 | - name: "Type: Maintenance" 50 | color: 2af79e 51 | description: "Generic maintenance tasks, e.g., package updates." 52 | 53 | # Additional markers 54 | - name: "Security" 55 | color: ee0701 56 | description: "Marks a security issue that needs to be resolved asap." 57 | - name: "Idea" 58 | color: fef2c0 59 | description: "Marks an idea, which might be excepted and implemented." 60 | - name: "Incomplete" 61 | color: fef2c0 62 | description: "Marks a PR or issue that is missing information." 63 | - name: "Pull request" 64 | color: fbca04 65 | description: "There is an PR opened for this issue." 66 | - name: "Accepted" 67 | color: c2e0c6 68 | description: "This issue or PR has been accepted." 69 | - name: "Declined" 70 | color: f9d0c4 71 | description: "This issue or PR has been declined." 72 | - name: "Potential duplicate" 73 | color: e6e6e6 74 | description: "This issue has been automatically marked as a potential duplicate." 75 | 76 | # Ongoing Status labels 77 | - name: "Status: Triage" 78 | color: fbca04 79 | description: "This issue needs to be triaged." 80 | - name: "Status: On hold" 81 | color: cccccc 82 | description: "Issue or PR that has been placed on hold for now." 83 | - name: "Status: In progress" 84 | color: fbca04 85 | description: "Issue is currently being resolved by a developer." 86 | - name: "Status: Stale" 87 | color: fef2c0 88 | description: "There has not been activity on this issue or PR for quite some time." 89 | - name: "Status: Awaiting response" 90 | color: fef2c0 91 | description: "Issue or PR awaits response from the creator." 92 | - name: "Status: Blocked" 93 | color: fef2c0 94 | description: "Progress on this issue is currently not possible." 95 | 96 | # Closing status labels 97 | - name: "Closed: Known limitation" 98 | color: e6e6e6 99 | description: "Issue is closed, it is a known limitation." 100 | - name: "Closed: Expected behavior" 101 | color: e6e6e6 102 | description: "Issues is closed, it is expected behavior." 103 | - name: "Closed: Duplicate" 104 | color: e6e6e6 105 | description: "Issue is closed, duplicate of an existing issue." 106 | - name: "Closed: Invalid" 107 | color: e6e6e6 108 | description: "Issue is closed, marked as not a valid issue (e.g., an user error)." 109 | - name: "Closed: Wrong repository" 110 | color: e6e6e6 111 | description: "Issue is closed, was created in the wrong repository." 112 | - name: "Closed: Won't Fix" 113 | color: e6e6e6 114 | description: "Issue is closed, it won't be fixed." 115 | - name: "Closed: Done" 116 | color: c2e0c6 117 | description: "Issue closed, work on this issue has been marked complete." 118 | 119 | # Others 120 | - name: "Beginner Friendly" 121 | color: 0e8a16 122 | description: "Good first issue for people wanting to contribute to the project." 123 | - name: "Help wanted" 124 | color: 0e8a16 125 | description: "We need some extra helping hands or expertise in order to resolve this." 126 | - name: "Hacktoberfest" 127 | description: "Issues/PRs are participating in the Hacktoberfest" 128 | color: fbca04 129 | 130 | branches: 131 | - name: master 132 | protection: 133 | required_pull_request_reviews: 134 | # required_approving_review_count: 1 135 | dismiss_stale_reviews: true 136 | require_code_owner_reviews: true 137 | dismissal_restrictions: 138 | users: [] 139 | teams: 140 | - Admins 141 | - Masters 142 | required_status_checks: 143 | strict: false 144 | contexts: [] 145 | enforce_admins: false 146 | restrictions: 147 | users: [] 148 | teams: 149 | - Admins 150 | - Masters 151 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Home Assistant Community Add-on: JupyterLab Lite 2 | 3 | [![GitHub Release][releases-shield]][releases] 4 | ![Project Stage][project-stage-shield] 5 | [![License][license-shield]](LICENSE.md) 6 | 7 | ![Supports armhf Architecture][armhf-shield] 8 | ![Supports armv Architecture][armhf-shield] 9 | ![Supports aarch64 Architecture][aarch64-shield] 10 | ![Supports amd64 Architecture][amd64-shield] 11 | ![Supports i386 Architecture][i386-shield] 12 | 13 | [![GitLab CI][gitlabci-shield]][gitlabci] 14 | ![Project Maintenance][maintenance-shield] 15 | [![GitHub Activity][commits-shield]][commits] 16 | 17 | [![Discord][discord-shield]][discord] 18 | [![Community Forum][forum-shield]][forum] 19 | 20 | [![Sponsor Frenck via GitHub Sponsors][github-sponsors-shield]][github-sponsors] 21 | 22 | [![Support Frenck on Patreon][patreon-shield]][patreon] 23 | 24 | Create documents containing live code, equations, visualizations, 25 | and explanatory text. 26 | 27 | ![The JupyterLab add-on](images/screenshot.png) 28 | 29 | ## About 30 | 31 | JupyterLab is an open-source web application that allows you to create and share 32 | documents that contain live code, equations, visualizations and narrative text. 33 | Uses include: data cleaning and transformation, numerical simulation, 34 | statistical modeling, data visualization, machine learning, and much more. 35 | 36 | This add-on runs JupyterLab, which is the next-generation user interface for 37 | Project Jupyter. It is an extensible environment for interactive and 38 | reproducible computing, based on the Jupyter Notebook and Architecture. 39 | 40 | ## Support 41 | 42 | Got questions? 43 | 44 | You have several options to get them answered: 45 | 46 | - The [Home Assistant Community Add-ons Discord chat server][discord] for add-on 47 | support and feature requests. 48 | - The [Home Assistant Discord chat server][discord-ha] for general Home 49 | Assistant discussions and questions. 50 | - The Home Assistant [Community Forum][forum]. 51 | - Join the [Reddit subreddit][reddit] in [/r/homeassistant][reddit] 52 | 53 | You could also [open an issue here][issue] GitHub. 54 | 55 | ## Contributing 56 | 57 | This is an active open-source project. We are always open to people who want to 58 | use the code or contribute to it. 59 | 60 | We have set up a separate document containing our 61 | [contribution guidelines](CONTRIBUTING.md). 62 | 63 | Thank you for being involved! :heart_eyes: 64 | 65 | ## Authors & contributors 66 | 67 | The original setup of this repository is by [Franck Nijhof][frenck]. 68 | 69 | For a full list of all authors and contributors, 70 | check [the contributor's page][contributors]. 71 | 72 | ## We have got some Home Assistant add-ons for you 73 | 74 | Want some more functionality to your Home Assistant instance? 75 | 76 | We have created multiple add-ons for Home Assistant. For a full list, check out 77 | our [GitHub Repository][repository]. 78 | 79 | ## License 80 | 81 | MIT License 82 | 83 | Copyright (c) 2018-2020 Franck Nijhof 84 | 85 | Permission is hereby granted, free of charge, to any person obtaining a copy 86 | of this software and associated documentation files (the "Software"), to deal 87 | in the Software without restriction, including without limitation the rights 88 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 89 | copies of the Software, and to permit persons to whom the Software is 90 | furnished to do so, subject to the following conditions: 91 | 92 | The above copyright notice and this permission notice shall be included in all 93 | copies or substantial portions of the Software. 94 | 95 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 96 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 97 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 98 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 99 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 100 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 101 | SOFTWARE. 102 | 103 | [aarch64-shield]: https://img.shields.io/badge/aarch64-yes-green.svg 104 | [alpine-packages]: https://pkgs.alpinelinux.org/packages 105 | [amd64-shield]: https://img.shields.io/badge/amd64-yes-green.svg 106 | [armhf-shield]: https://img.shields.io/badge/armhf-no-red.svg 107 | [armv7-shield]: https://img.shields.io/badge/armv7-yes-green.svg 108 | [commits-shield]: https://img.shields.io/github/commit-activity/y/hassio-addons/addon-jupyterlab-lite.svg 109 | [commits]: https://github.com/hassio-addons/addon-jupyterlab-lite/commits/master 110 | [contributors]: https://github.com/hassio-addons/addon-jupyterlab-lite/graphs/contributors 111 | [discord-ha]: https://discord.gg/c5DvZ4e 112 | [discord-shield]: https://img.shields.io/discord/478094546522079232.svg 113 | [discord]: https://discord.me/hassioaddons 114 | [docs]: https://github.com/hassio-addons/addon-jupyterlab-lite/blob/master/jupyterlab-lite/DOCS.md 115 | [forum-shield]: https://img.shields.io/badge/community-forum-brightgreen.svg 116 | [forum]: https://community.home-assistant.io/t/home-assistant-community-add-on-jupyterlab-lite/87337?u=frenck 117 | [frenck]: https://github.com/frenck 118 | [github-sponsors-shield]: https://frenck.dev/wp-content/uploads/2019/12/github_sponsor.png 119 | [github-sponsors]: https://github.com/sponsors/frenck 120 | [gitlabci-shield]: https://gitlab.com/hassio-addons/addon-jupyterlab-lite/badges/master/pipeline.svg 121 | [gitlabci]: https://gitlab.com/hassio-addons/addon-jupyterlab-lite/pipelines 122 | [home-assistant]: https://home-assistant.io 123 | [i386-shield]: https://img.shields.io/badge/i386-no-red.svg 124 | [issue]: https://github.com/hassio-addons/addon-jupyterlab-lite/issues 125 | [license-shield]: https://img.shields.io/github/license/hassio-addons/addon-jupyterlab-lite.svg 126 | [maintenance-shield]: https://img.shields.io/maintenance/yes/2020.svg 127 | [patreon-shield]: https://frenck.dev/wp-content/uploads/2019/12/patreon.png 128 | [patreon]: https://www.patreon.com/frenck 129 | [project-stage-shield]: https://img.shields.io/badge/project%20stage-experimental-yellow.svg 130 | [python-packages]: https://pypi.org/ 131 | [reddit]: https://reddit.com/r/homeassistant 132 | [releases-shield]: https://img.shields.io/github/release/hassio-addons/addon-jupyterlab-lite.svg 133 | [releases]: https://github.com/hassio-addons/addon-jupyterlab-lite/releases 134 | [repository]: https://github.com/hassio-addons/repository 135 | -------------------------------------------------------------------------------- /jupyterlab/DOCS.md: -------------------------------------------------------------------------------- 1 | # Home Assistant Community Add-on: JupyterLab Lite 2 | 3 | JupyterLab is an open-source web application that allows you to create and share 4 | documents that contain live code, equations, visualizations and narrative text. 5 | Uses include: data cleaning and transformation, numerical simulation, 6 | statistical modeling, data visualization, machine learning, and much more. 7 | 8 | This add-on runs JupyterLab, which is the next-generation user interface for 9 | Project Jupyter. It is an extensible environment for interactive and 10 | reproducible computing, based on the Jupyter Notebook and Architecture. 11 | 12 | ## Installation 13 | 14 | The installation of this add-on is pretty straightforward and not different in 15 | comparison to installing any other Home Assistant add-on. 16 | 17 | 1. Search for the "JupyterLab Lite" add-on in the Supervisor add-on store 18 | and install it. 19 | 1. Start the "JupyterLab Lite" add-on 20 | 1. Check the logs of the "JupyterLab Lite" add-on to see if everything went well. 21 | 22 | ## Configuration 23 | 24 | **Note**: _Remember to restart the add-on when the configuration is changed._ 25 | 26 | Example add-on configuration: 27 | 28 | ```yaml 29 | log_level: info 30 | github_access_token: abcdef1234567890abcdef0123456789abcdef01 31 | ssl: true 32 | certfile: fullchain.pem 33 | keyfile: privkey.pem 34 | system_packages: 35 | - ffmpeg 36 | init_commands: 37 | - pip install virtualenv 38 | - pip install yamllint 39 | ``` 40 | 41 | **Note**: _This is just an example, don't copy and past it! Create your own!_ 42 | 43 | ### Option: `log_level` 44 | 45 | The `log_level` option controls the level of log output by the addon and can 46 | be changed to be more or less verbose, which might be useful when you are 47 | dealing with an unknown issue. Possible values are: 48 | 49 | - `trace`: Show every detail, like all called internal functions. 50 | - `debug`: Shows detailed debug information. 51 | - `info`: Normal (usually) interesting events. 52 | - `warning`: Exceptional occurrences that are not errors. 53 | - `error`: Runtime errors that do not require immediate action. 54 | - `fatal`: Something went terribly wrong. Add-on becomes unusable. 55 | 56 | Please note that each level automatically includes log messages from a 57 | more severe level, e.g., `debug` also shows `info` messages. By default, 58 | the `log_level` is set to `info`, which is the recommended setting unless 59 | you are troubleshooting. 60 | 61 | ### Option: `github_access_token` 62 | 63 | Sets an GitHub access token. When making unauthenticated requests to GitHub 64 | (as we must do to get repository data), GitHub imposes fairly strict rate-limits 65 | on how many requests we can make. As such, you are likely to hit that limit 66 | within a few minutes of work. 67 | 68 | There is a chapter in this document with instruction on obtaining such a token. 69 | 70 | **Note**: _This option support secrets, e.g., `!secret github_token`._ 71 | 72 | ### Option: `ssl` 73 | 74 | Enables/Disables SSL (HTTPS) on the JupyterLab Set it `true` to enable it, 75 | `false` otherwise. 76 | 77 | ### Option: `certfile` 78 | 79 | The certificate file to use for SSL. 80 | 81 | **Note**: _The file MUST be stored in `/ssl/`, which is the default_ 82 | 83 | ### Option: `keyfile` 84 | 85 | The private key file to use for SSL. 86 | 87 | **Note**: _The file MUST be stored in `/ssl/`, which is the default_ 88 | 89 | ### Option: `system_packages` 90 | 91 | Allows you to specify additional [Alpine packages][alpine-packages] to be 92 | installed to your JupyterLab setup (e.g., `g++`. `make`, `ffmpeg`). 93 | 94 | **Note**: _Adding many packages will result in a longer start-up time 95 | for the add-on._ 96 | 97 | #### Option: `init_commands` 98 | 99 | Customize your environment even more with the `init_commands` option. 100 | Add one or more shell commands to the list, and they will be executed every 101 | single time this add-on starts. 102 | 103 | ## Embedding into Home Assistant 104 | 105 | It is possible to embed JupyterLab directly into Home Assistant, allowing 106 | you to access the JupyterLab through the Home Assistant frontend. 107 | 108 | Home Assistant provides the `panel_iframe` integration, for these purposes. 109 | 110 | Example configuration: 111 | 112 | ```yaml 113 | panel_iframe: 114 | jupyterlab: 115 | title: JupyterLab 116 | icon: mdi:flask 117 | url: https://addres.to.your.home.assistant:7777 118 | ``` 119 | 120 | ## Getting a GitHub access token 121 | 122 | You can get an access token by following these steps: 123 | 124 | 1. [Verify][github-verify] your email address with GitHub. 125 | 1. Go to your account settings on GitHub and select "Developer Settings" 126 | from the left panel. 127 | 1. On the left, select "Personal access tokens" 128 | 1. Click the "Generate new token" button, and enter your password. 129 | 1. Give the token a description, and check the "**repo**" scope box. 130 | 1. Click "Generate token" 131 | 1. You should be given a string which will be your access token. 132 | 133 | Remember that this token is effectively a password for your GitHub account. 134 | *Do not* share it online or check the token into version control, 135 | as people can use it to access all of your data on GitHub. 136 | 137 | ## Changelog & Releases 138 | 139 | This repository keeps a change log using [GitHub's releases][releases] 140 | functionality. The format of the log is based on 141 | [Keep a Changelog][keepchangelog]. 142 | 143 | Releases are based on [Semantic Versioning][semver], and use the format 144 | of ``MAJOR.MINOR.PATCH``. In a nutshell, the version will be incremented 145 | based on the following: 146 | 147 | - ``MAJOR``: Incompatible or major changes. 148 | - ``MINOR``: Backwards-compatible new features and enhancements. 149 | - ``PATCH``: Backwards-compatible bugfixes and package updates. 150 | 151 | ## Support 152 | 153 | Got questions? 154 | 155 | You have several options to get them answered: 156 | 157 | - The [Home Assistant Community Add-ons Discord chat server][discord] for add-on 158 | support and feature requests. 159 | - The [Home Assistant Discord chat server][discord-ha] for general Home 160 | Assistant discussions and questions. 161 | - The Home Assistant [Community Forum][forum]. 162 | - Join the [Reddit subreddit][reddit] in [/r/homeassistant][reddit] 163 | 164 | You could also [open an issue here][issue] GitHub. 165 | 166 | ## Authors & contributors 167 | 168 | The original setup of this repository is by [Franck Nijhof][frenck]. 169 | 170 | For a full list of all authors and contributors, 171 | check [the contributor's page][contributors]. 172 | 173 | ## License 174 | 175 | MIT License 176 | 177 | Copyright (c) 2018-2020 Franck Nijhof 178 | 179 | Permission is hereby granted, free of charge, to any person obtaining a copy 180 | of this software and associated documentation files (the "Software"), to deal 181 | in the Software without restriction, including without limitation the rights 182 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 183 | copies of the Software, and to permit persons to whom the Software is 184 | furnished to do so, subject to the following conditions: 185 | 186 | The above copyright notice and this permission notice shall be included in all 187 | copies or substantial portions of the Software. 188 | 189 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 190 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 191 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 192 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 193 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 194 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 195 | SOFTWARE. 196 | 197 | [alpine-packages]: https://pkgs.alpinelinux.org/packages 198 | [contributors]: https://github.com/hassio-addons/addon-jupyterlab-lite/graphs/contributors 199 | [discord-ha]: https://discord.gg/c5DvZ4e 200 | [discord]: https://discord.me/hassioaddons 201 | [forum-shield]: https://img.shields.io/badge/community-forum-brightgreen.svg 202 | [forum]: https://community.home-assistant.io/t/home-assistant-community-add-on-jupyterlab-lite/87337?u=frenck 203 | [frenck]: https://github.com/frenck 204 | [github-verify]: https://help.github.com/articles/verifying-your-email-address 205 | [issue]: https://github.com/hassio-addons/addon-jupyterlab-lite/issues 206 | [keepchangelog]: http://keepachangelog.com/en/1.0.0/ 207 | [python-packages]: https://pypi.org/ 208 | [reddit]: https://reddit.com/r/homeassistant 209 | [releases]: https://github.com/hassio-addons/addon-jupyterlab-lite/releases 210 | [semver]: http://semver.org/spec/v2.0.0.htm 211 | --------------------------------------------------------------------------------