Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.idea
5 changes: 5 additions & 0 deletions install.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"packageManager": "python",
"packageName": "jupyterlab_gcloud_auth",
"uninstallInstructions": "Use your Python package manager (pip, conda, etc.) to uninstall the package jupyterlab_gcloud_auth"
}
7 changes: 7 additions & 0 deletions jupyter-config/nb-config/jupyterlab_gcloud_auth.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"NotebookApp": {
"nbserver_extensions": {
"jupyterlab_gcloud_auth": true
}
}
}
7 changes: 7 additions & 0 deletions jupyter-config/server-config/jupyterlab_gcloud_auth.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"ServerApp": {
"jpserver_extensions": {
"jupyterlab_gcloud_auth": true
}
}
}
54 changes: 21 additions & 33 deletions jupyterlab_gcloud_auth/__init__.py
Original file line number Diff line number Diff line change
@@ -1,47 +1,35 @@
import tornado.gen as gen
import subprocess

import json
from pathlib import Path

from ._version import __version__

from notebook.utils import url_path_join
from . import gcloud_auth_helper
from notebook.base.handlers import APIHandler
HERE = Path(__file__).parent.resolve()

with (HERE / "labextension" / "package.json").open() as fid:
data = json.load(fid)

class GcpAuthHandler(APIHandler):
def _jupyter_labextension_paths():
return [{
"src": "labextension",
"dest": data["name"]
}]

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.gcloud_auth_helper = gcloud_auth_helper.GcloudAuthHelper()

@gen.coroutine
def post(self):
data = json.loads(self.request.body.decode("utf-8"))
if data.get("signout"):
self.gcloud_auth_helper.sign_out(data["signout"])
elif data.get("signin"):
self.gcloud_auth_helper.create_login_request()
else:
self.gcloud_auth_helper.finish_authentication(data["auth_code"])
return self.finish("DONE")

@gen.coroutine
def get(self):
data = {
"auth_url": self.gcloud_auth_helper.get_link(),
"signed_in": self.gcloud_auth_helper.signed_in()
}
return self.finish(data)
from .handlers import setup_handlers


def _jupyter_server_extension_paths():
def _jupyter_server_extension_points():
return [{
"module": "jupyterlab_gcloud_auth"
}]


def load_jupyter_server_extension(nb_server_app):
web_app = nb_server_app.web_app
base_url = web_app.settings["base_url"]
endpoint = url_path_join(base_url, "gcloud-auth")
handlers = [(endpoint, GcpAuthHandler)]
web_app.add_handlers(".*$", handlers)
def _load_jupyter_server_extension(server_app):
setup_handlers(server_app.web_app)
server_app.log.info("Registered jupyterlab-gcloud-auth extension at URL path /gcloud-auth")

# For backward compatibility with notebook server - useful for Binder/JupyterHub
load_jupyter_server_extension = _load_jupyter_server_extension

23 changes: 23 additions & 0 deletions jupyterlab_gcloud_auth/_version.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import json
from pathlib import Path

__all__ = ["__version__"]

def _fetchVersion():
HERE = Path(__file__).parent.resolve()

for settings in HERE.rglob("package.json"):
try:
with settings.open() as f:
version = json.load(f)["version"]
return (
version.replace("-alpha.", "a")
.replace("-beta.", "b")
.replace("-rc.", "rc")
)
except FileNotFoundError:
pass

raise FileNotFoundError(f"Could not find package.json under dir {HERE!s}")

__version__ = _fetchVersion()
44 changes: 44 additions & 0 deletions jupyterlab_gcloud_auth/handlers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import json

from jupyter_server.base.handlers import APIHandler
from jupyter_server.utils import url_path_join
import tornado

from . import gcloud_auth_helper

class GcpAuthHandler(APIHandler):

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.gcloud_auth_helper = gcloud_auth_helper.GcloudAuthHelper()

# The following decorator should be present on all verb methods (head, get, post,
# patch, put, delete, options) to ensure only authorized user can request the
# Jupyter server
@tornado.web.authenticated
def post(self):
data = json.loads(self.request.body.decode("utf-8"))
if data.get("signout"):
self.gcloud_auth_helper.sign_out(data["signout"])
elif data.get("signin"):
self.gcloud_auth_helper.create_login_request()
else:
self.gcloud_auth_helper.finish_authentication(data["auth_code"])
return self.finish("DONE")

@tornado.web.authenticated
def get(self):
data = {
"auth_url": self.gcloud_auth_helper.get_link(),
"signed_in": self.gcloud_auth_helper.signed_in()
}
return self.finish(data)


def setup_handlers(web_app):
host_pattern = ".*$"

base_url = web_app.settings["base_url"]
route_pattern = url_path_join(base_url, "gcloud-auth")
handlers = [(route_pattern, GcpAuthHandler)]
web_app.add_handlers(host_pattern, handlers)
55 changes: 39 additions & 16 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "jupyterlab-gcloud-auth",
"version": "0.3.0",
"description": "Plugin that allows to run gclout auth directly from the Notebooks.",
"version": "0.4.0",
"description": "Plugin that allows to run gcloud auth directly from the Notebooks.",
"keywords": [
"jupyter",
"jupyterlab",
Expand All @@ -16,7 +16,8 @@
"files": [
"lib/**/*.{d.ts,eot,gif,html,jpg,js,js.map,json,png,svg,woff2,ttf}",
"style/*.css",
"style/images/*.png"
"style/images/*.png",
"style/index.js"
],
"main": "lib/index.js",
"types": "lib/index.d.ts",
Expand All @@ -25,22 +26,42 @@
"url": "https://github.com/gclouduniverse/jupyterlab-gcloud-auth.git"
},
"scripts": {
"build": "tsc",
"clean": "rimraf lib",
"build": "jlpm run build:lib && jlpm run build:labextension:dev",
"build:labextension": "jupyter labextension build .",
"build:labextension:dev": "jupyter labextension build --development True .",
"build:lib": "tsc",
"build:prod": "jlpm run clean && jlpm run build:lib && jlpm run build:labextension",
"clean": "jlpm run clean:lib",
"clean:all": "jlpm run clean:lib && jlpm run clean:labextension",
"clean:labextension": "rimraf jupyterlab_gcloud_auth/labextension",
"clean:lib": "rimraf lib tsconfig.tsbuildinfo",
"eslint": "eslint . --ext .ts,.tsx --fix",
"eslint:check": "eslint . --ext .ts,.tsx",
"install:extension": "jlpm run build",
"prepare": "npm run clean && npm run build",
"watch": "tsc -w"
"watch": "run-p watch:src watch:labextension",
"watch:labextension": "jupyter labextension watch .",
"watch:src": "tsc -w"
},
"dependencies": {
"@jupyterlab/application": "^1.0.2",
"@jupyterlab/mainmenu": "^0.8.0",
"@types/react": "^15.0.0",
"@jupyterlab/coreutils": "^3.0.0",
"@phosphor/widgets": "^1.9.0",
"@jupyterlab/apputils": "^1.0.2"
"@jupyterlab/application": "^3.2.4",
"@jupyterlab/apputils": "^3.2.4",
"@jupyterlab/coreutils": "^5.2.4",
"@jupyterlab/mainmenu": "^3.2.4",
"@lumino/widgets": "^1.19.0"
},
"devDependencies": {
"rimraf": "^2.6.1",
"typescript": "~3.0.0"
"@jupyterlab/builder": "^3.1.0",
"@typescript-eslint/eslint-plugin": "^4.8.1",
"@typescript-eslint/parser": "^4.8.1",
"eslint": "^7.14.0",
"eslint-config-prettier": "^6.15.0",
"eslint-plugin-prettier": "^3.1.4",
"mkdirp": "^1.0.3",
"npm-run-all": "^4.1.5",
"prettier": "^2.1.1",
"rimraf": "^3.0.2",
"typescript": "~4.1.3"
},
"jupyterlab": {
"extension": true,
Expand All @@ -53,6 +74,8 @@
"name": "jupyterlab_gcloud_auth"
}
}
}
}
},
"outputDir": "jupyterlab_gcloud_auth/labextension"
},
"styleModule": "style/index.js"
}
17 changes: 17 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
[build-system]
requires = ["jupyter_packaging~=0.10,<2", "jupyterlab~=3.1"]
build-backend = "jupyter_packaging.build_api"

[tool.jupyter-packaging.options]
skip-if-exists = ["jupyterlab_gcloud_auth/labextension/static/style.js"]
ensured-targets = ["jupyterlab_gcloud_auth/labextension/static/style.js", "jupyterlab_gcloud_auth/labextension/package.json"]

[tool.jupyter-packaging.builder]
factory = "jupyter_packaging.npm_builder"

[tool.jupyter-packaging.build-args]
build_cmd = "build:prod"
npm = ["jlpm"]

[tool.check-manifest]
ignore = ["jupyterlab_gcloud_auth/labextension/**", "yarn.lock", ".*", "package-lock.json"]
124 changes: 91 additions & 33 deletions setup.py
Original file line number Diff line number Diff line change
@@ -1,43 +1,101 @@
"""
Setup module for the share proxy extension
jupyterlab_gcloud_auth setup
"""
import json
import sys
from pathlib import Path

import setuptools
from setupbase import (
create_cmdclass, ensure_python, find_packages
)

HERE = Path(__file__).parent.resolve()

# The name of the project
name = "jupyterlab_gcloud_auth"

lab_path = (HERE / name.replace("-", "_") / "labextension")

# Representative files that should exist after a successful build
ensured_targets = [
str(lab_path / "package.json"),
str(lab_path / "static/style.js")
]

labext_name = "jupyterlab-gcloud-auth"

data_files_spec = [
('etc/jupyter/jupyter_notebook_config.d',
'jupyter-config/jupyter_notebook_config.d', 'jupyterlab_gcloud_auth.json'),
("share/jupyter/labextensions/%s" % labext_name, str(lab_path.relative_to(HERE)), "**"),
("share/jupyter/labextensions/%s" % labext_name, str("."), "install.json"),
("etc/jupyter/jupyter_server_config.d",
"jupyter-config/server-config", "jupyterlab_gcloud_auth.json"),
# For backward compatibility with notebook server
("etc/jupyter/jupyter_notebook_config.d",
"jupyter-config/nb-config", "jupyterlab_gcloud_auth.json"),
]

requires = [line.strip() for line in open('requirements.txt').readlines() if not line.startswith("#")]

cmdclass = create_cmdclass(data_files_spec=data_files_spec)

setup_dict = dict(
name='jupyterlab_gcloud_auth',
description='Plugin that allows to run gclout auth directly from the Notebooks.',
packages=find_packages(),
cmdclass=cmdclass,
author = 'Viacheslav Kovalevskyi',
author_email = 'viacheslav@kovalevskyi.com',
license = 'MIT',
platforms = "Linux, Mac OS X, Windows",
keywords = ['Jupyter', 'JupyterLab', 'GitHub', 'GCP'],
python_requires = '>=3.5',
classifiers = [
'Intended Audience :: Developers',
'Intended Audience :: System Administrators',
'Intended Audience :: Science/Research',
'License :: OSI Approved :: MIT License',
'Programming Language :: Python',
'Programming Language :: Python :: 3',
long_description = (HERE / "README.md").read_text()

# Get the package info from package.json
pkg_json = json.loads((HERE / "package.json").read_bytes())
version = (
pkg_json["version"]
.replace("-alpha.", "a")
.replace("-beta.", "b")
.replace("-rc.", "rc")
)

setup_args = dict(
name=name,
version=version,
url=pkg_json["homepage"],
author=pkg_json["author"],
description=pkg_json["description"],
license=pkg_json["license"],
license_file="LICENSE",
long_description=long_description,
long_description_content_type="text/markdown",
packages=setuptools.find_packages(),
install_requires=[
"jupyter_server>=1.6,<2"
],
zip_safe=False,
include_package_data=True,
python_requires=">=3.6",
platforms="Linux, Mac OS X, Windows",
keywords=["Jupyter", "JupyterLab", "JupyterLab3"],
classifiers=[
"License :: OSI Approved :: BSD License",
"Programming Language :: Python",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.6",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Framework :: Jupyter",
"Framework :: Jupyter :: JupyterLab",
"Framework :: Jupyter :: JupyterLab :: 3",
"Framework :: Jupyter :: JupyterLab :: Extensions",
"Framework :: Jupyter :: JupyterLab :: Extensions :: Prebuilt",
],
install_requires=requires
)

setuptools.setup(
version="0.3.0",
**setup_dict
)
try:
from jupyter_packaging import (
wrap_installers,
npm_builder,
get_data_files
)
post_develop = npm_builder(
build_cmd="install:extension", source_dir="src", build_dir=lab_path
)
setup_args["cmdclass"] = wrap_installers(post_develop=post_develop, ensured_targets=ensured_targets)
setup_args["data_files"] = get_data_files(data_files_spec)
except ImportError as e:
import logging
logging.basicConfig(format="%(levelname)s: %(message)s")
logging.warning("Build tool `jupyter-packaging` is missing. Install it with pip or conda.")
if not ("--name" in sys.argv or "--version" in sys.argv):
raise e

if __name__ == "__main__":
setuptools.setup(**setup_args)
Loading