diff --git a/etc/jupyter/jupyter_server_config.d/jupytercad.json b/etc/jupyter/jupyter_server_config.d/jupytercad.json deleted file mode 100644 index 2c626d73..00000000 --- a/etc/jupyter/jupyter_server_config.d/jupytercad.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "ServerApp": { - "jpserver_extensions": { - "jupytercad": true - } - } -} diff --git a/install.json b/install.json deleted file mode 100644 index ea9b9658..00000000 --- a/install.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "packageManager": "python", - "packageName": "jupytercad", - "uninstallInstructions": "Use your Python package manager (pip, conda, etc.) to uninstall the package jupytercad" -} diff --git a/jupytercad/__init__.py b/jupytercad/__init__.py deleted file mode 100644 index e1dc03e0..00000000 --- a/jupytercad/__init__.py +++ /dev/null @@ -1,8 +0,0 @@ -from ._version import __version__ # noqa -from .cadapp import CadApp - -from .notebook import * # noqa - - -def _jupyter_server_extension_points(): - return [{"module": __name__, "app": CadApp}] diff --git a/jupytercad/cadapp/__init__.py b/jupytercad/cadapp/__init__.py deleted file mode 100644 index f5b652d6..00000000 --- a/jupytercad/cadapp/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from .cadapp import CadApp, main # noqa diff --git a/jupytercad/cadapp/cadapp.py b/jupytercad/cadapp/cadapp.py deleted file mode 100644 index 0e9efdc7..00000000 --- a/jupytercad/cadapp/cadapp.py +++ /dev/null @@ -1,77 +0,0 @@ -import json -import os - -import tornado -from jupyter_server.base.handlers import APIHandler, JupyterHandler -from jupyter_server.extension.handler import ( - ExtensionHandlerJinjaMixin, - ExtensionHandlerMixin, -) -from jupyterlab_server import LabServerApp - -from .._version import __version__ -from .utils import get_page_config - -HERE = os.path.dirname(__file__) - - -class CADHandler(ExtensionHandlerJinjaMixin, ExtensionHandlerMixin, JupyterHandler): - """Handle requests between the main app page and notebook server.""" - - def get(self): - """Get the main page for the application's interface.""" - page_config = get_page_config(self.base_url, self.name) - page_config["token"] = self.settings["token"] - return self.write( - self.render_template( - "index.html", - static=self.static_url, - base_url=self.base_url, - token=self.settings["token"], - page_config=page_config, - ) - ) - - -class BackendCheckHandler(APIHandler): - @tornado.web.authenticated - def post(self): - body = self.get_json_body() - backend = body.get("backend") - if backend == "FreeCAD": - fc_installed = True - try: - pass - except ImportError: - fc_installed = False - self.finish(json.dumps({"installed": fc_installed})) - elif backend == "JCAD": - self.finish(json.dumps({"installed": True})) - else: - self.finish(json.dumps({"installed": False})) - - -class CadApp(LabServerApp): - extension_url = "/cad" - default_url = "/cad" - app_url = "/cad" - load_other_extensions = True - name = "cad" - app_name = "JupyterCAD" - static_dir = os.path.join(HERE, "static") - templates_dir = os.path.join(HERE, "templates") - app_version = __version__ - app_settings_dir = os.path.join(HERE, "static", "application_settings") - schemas_dir = os.path.join(HERE, "schemas") - themes_dir = os.path.join(HERE, "themes") - user_settings_dir = os.path.join(HERE, "static", "user_settings") - workspaces_dir = os.path.join(HERE, "static", "workspaces") - - def initialize_handlers(self): - """Add cad handler to Lab Server's handler list.""" - self.handlers.append(("/cad", CADHandler)) - self.handlers.append(("/cad/backend-check", BackendCheckHandler)) - super().initialize_handlers() - - -main = CadApp.launch_instance diff --git a/jupytercad/cadapp/templates/index.html b/jupytercad/cadapp/templates/index.html deleted file mode 100644 index ae6f30ef..00000000 --- a/jupytercad/cadapp/templates/index.html +++ /dev/null @@ -1,52 +0,0 @@ - - - - {{page_config['appName'] | e}} - - - - - - {# Copy so we do not modify the page_config with updates. #} - {% set page_config_full = page_config.copy() %} - - {# Set a dummy variable - we just want the side effect of the update. #} - {% set _ = page_config_full.update(baseUrl=base_url, wsUrl=ws_url) %} - - - - - - - - diff --git a/jupytercad/cadapp/utils.py b/jupytercad/cadapp/utils.py deleted file mode 100644 index 2b302784..00000000 --- a/jupytercad/cadapp/utils.py +++ /dev/null @@ -1,35 +0,0 @@ -from .._version import __version__ -from jupyter_server.utils import url_path_join -from jupyterlab_server.config import get_page_config as gpc -from jupyter_server.config_manager import recursive_update -from jupyter_core.paths import jupyter_path - - -def get_page_config(base_url, app_name): - page_config = { - "appVersion": __version__, - "baseUrl": base_url, - "terminalsAvailable": False, - "fullStaticUrl": url_path_join(base_url, "static", app_name), - "fullLabextensionsUrl": url_path_join(base_url, "lab", "extensions"), - "fullSettingsUrl": url_path_join(base_url, "lab", "api", "settings"), - "settingsUrl": url_path_join(base_url, "lab", "api", "settings"), - "themesUrl": "/lab/api/themes", - "appUrl": "/lab", - "frontendUrl": url_path_join(base_url, app_name), - } - - labextensions_path = jupyter_path("labextensions") - recursive_update( - page_config, - gpc(labextensions_path), - ) - required_extensions = [ - "@jupytercad/jupytercad-lab", - "@jupyter/collaboration-extension", - ] - federated_extensions = page_config["federated_extensions"] - page_config["federated_extensions"] = [ - x for x in federated_extensions if x["name"] in required_extensions - ] - return page_config diff --git a/jupytercad/jcad_ydoc.py b/jupytercad/jcad_ydoc.py deleted file mode 100644 index bf93dc71..00000000 --- a/jupytercad/jcad_ydoc.py +++ /dev/null @@ -1,69 +0,0 @@ -import json -from typing import Any, Callable -from functools import partial - -import y_py as Y -from jupyter_ydoc.ybasedoc import YBaseDoc - - -class YJCad(YBaseDoc): - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - self._ysource = self._ydoc.get_text("source") - self._yobjects = self._ydoc.get_array("objects") - self._yoptions = self._ydoc.get_map("options") - self._ymeta = self._ydoc.get_map("metadata") - - def version(self) -> str: - return "0.1.0" - - def get(self) -> str: - """ - Returns the content of the document. - :return: Document's content. - :rtype: Any - """ - objects = json.loads(self._yobjects.to_json()) - options = json.loads(self._yoptions.to_json()) - meta = json.loads(self._ymeta.to_json()) - return json.dumps( - dict(objects=objects, options=options, metadata=meta), indent=2 - ) - - def set(self, value: str) -> None: - """ - Sets the content of the document. - :param value: The content of the document. - :type value: Any - """ - valueDict = json.loads(value) - newObj = [] - for obj in valueDict["objects"]: - newObj.append(Y.YMap(obj)) - with self._ydoc.begin_transaction() as t: - length = len(self._yobjects) - self._yobjects.delete_range(t, 0, length) - # workaround for https://github.com/y-crdt/ypy/issues/126: - # self._yobjects.extend(t, newObj) - for o in newObj: - self._yobjects.append(t, o) - self._yoptions.update(t, valueDict["options"].items()) - self._ymeta.update(t, valueDict["metadata"].items()) - - def observe(self, callback: Callable[[str, Any], None]): - self.unobserve() - self._subscriptions[self._ystate] = self._ystate.observe( - partial(callback, "state") - ) - self._subscriptions[self._ysource] = self._ysource.observe( - partial(callback, "source") - ) - self._subscriptions[self._yobjects] = self._yobjects.observe_deep( - partial(callback, "objects") - ) - self._subscriptions[self._yoptions] = self._yoptions.observe_deep( - partial(callback, "options") - ) - self._subscriptions[self._ymeta] = self._ymeta.observe_deep( - partial(callback, "meta") - ) diff --git a/pyproject.toml b/pyproject.toml index 0b512213..b5631a89 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,52 +1,15 @@ -[build-system] -build-backend = "hatchling.build" -requires = [ - "hatchling>=1.4.0", - "hatch-nodejs-version", - "jupyterlab>=4.0.0", - "datamodel-code-generator", -] - [project] -name = "jupytercad" +name = "jupytercad-root" readme = "README.md" license = { file = "LICENSE" } -requires-python = ">=3.7" -dependencies = [ - "jupyter_server>=2.0.6", - "jupyterlab>=4,<5", - "jupyter_collaboration>=1.0.0a9,<2", - "ypywidgets>=0.4.1,<0.5.0", - "yjs-widgets>=0.3.4,<0.4", - "comm>=0.1.2,<0.2.0", - "pydantic>=2,<3", -] -classifiers = [ - "License :: OSI Approved :: BSD License", - "Programming Language :: Python", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.7", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", - "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: 3.11", - "Framework :: Jupyter", - "Framework :: Jupyter :: JupyterLab", - "Framework :: Jupyter :: JupyterLab :: 3", - "Framework :: Jupyter :: JupyterLab :: Extensions", - "Framework :: Jupyter :: JupyterLab :: Extensions :: Prebuilt", -] -dynamic = ["version", "description", "authors", "urls", "keywords"] - -[project.entry-points.jupyter_ydoc] -jcad = "jupytercad.jcad_ydoc:YJCad" -FCStd = "jupytercad.fcstd_ydoc:YFCStd" +version = "0.3.3" [tool.jupyter-releaser.options] version-cmd = "python scripts/bump-version.py" python_packages = [ - "jupyverse:fps-jupytercad", - ".:jupytercad:fps-jupytercad" + "python/jupytercad-app:jupytercad_app", + "python/jupytercad-core:jupytercad_core", + "python/jupytercad-lab:jupytercad_lab", ] [tool.jupyter-releaser.hooks] @@ -60,6 +23,3 @@ before-build-python = ["jlpm clean:all"] [tool.check-wheel-contents] ignore = ["W002"] - -[project.scripts] -jupyter-cad = "jupytercad.cadapp:main" diff --git a/python/jupytercad-app/jupytercad_app/cadapp.py b/python/jupytercad-app/jupytercad_app/cadapp.py index 63aaff3f..d909933c 100644 --- a/python/jupytercad-app/jupytercad_app/cadapp.py +++ b/python/jupytercad-app/jupytercad_app/cadapp.py @@ -1,8 +1,6 @@ -import json import os -import tornado -from jupyter_server.base.handlers import APIHandler, JupyterHandler +from jupyter_server.base.handlers import JupyterHandler from jupyter_server.extension.handler import ( ExtensionHandlerJinjaMixin, ExtensionHandlerMixin, @@ -37,24 +35,6 @@ def get(self): ) -class BackendCheckHandler(APIHandler): - @tornado.web.authenticated - def post(self): - body = self.get_json_body() - backend = body.get("backend") - if backend == "FreeCAD": - fc_installed = True - try: - pass - except ImportError: - fc_installed = False - self.finish(json.dumps({"installed": fc_installed})) - elif backend == "JCAD": - self.finish(json.dumps({"installed": True})) - else: - self.finish(json.dumps({"installed": False})) - - class CadApp(LabServerApp): extension_url = "/cad" default_url = "/cad" @@ -74,7 +54,6 @@ class CadApp(LabServerApp): def initialize_handlers(self): """Add cad handler to Lab Server's handler list.""" self.handlers.append(("/cad", CADHandler)) - self.handlers.append(("/cad/backend-check", BackendCheckHandler)) super().initialize_handlers() diff --git a/python/jupytercad-core/jupyter-config/server-config/jupytercad_core.json b/python/jupytercad-core/jupyter-config/server-config/jupytercad_core.json deleted file mode 100644 index bd6dedce..00000000 --- a/python/jupytercad-core/jupyter-config/server-config/jupytercad_core.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "ServerApp": { - "jpserver_extensions": { - "jupytercad_core": true - } - } -} diff --git a/python/jupytercad-core/jupytercad_core/__init__.py b/python/jupytercad-core/jupytercad_core/__init__.py index 06129263..65ae1f0c 100644 --- a/python/jupytercad-core/jupytercad_core/__init__.py +++ b/python/jupytercad-core/jupytercad_core/__init__.py @@ -8,25 +8,7 @@ warnings.warn("Importing 'jupytercad_core' outside a proper installation.") __version__ = "dev" -from .handlers import setup_handlers def _jupyter_labextension_paths(): return [{"src": "labextension", "dest": "@jupytercad/jupytercad-core"}] - - -def _jupyter_server_extension_points(): - return [{"module": "jupytercad_core"}] - - -def _load_jupyter_server_extension(server_app): - """Registers the API handler to receive HTTP requests from the frontend extension. - - Parameters - ---------- - server_app: jupyterlab.labapp.LabApp - JupyterLab application instance - """ - setup_handlers(server_app.web_app) - name = "jupytercad_core" - server_app.log.info(f"Registered {name} server extension") diff --git a/python/jupytercad-core/jupytercad_core/handlers.py b/python/jupytercad-core/jupytercad_core/handlers.py deleted file mode 100644 index 74d237c4..00000000 --- a/python/jupytercad-core/jupytercad_core/handlers.py +++ /dev/null @@ -1,25 +0,0 @@ -import json - -from jupyter_server.base.handlers import APIHandler -from jupyter_server.utils import url_path_join -import tornado - - -class RouteHandler(APIHandler): - # 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 get(self): - self.finish( - json.dumps({"data": "This is /jupytercad-core/get-example endpoint!"}) - ) - - -def setup_handlers(web_app): - host_pattern = ".*$" - - base_url = web_app.settings["base_url"] - route_pattern = url_path_join(base_url, "jupytercad-core", "get-example") - handlers = [(route_pattern, RouteHandler)] - web_app.add_handlers(host_pattern, handlers) diff --git a/python/jupytercad-core/pyproject.toml b/python/jupytercad-core/pyproject.toml index 6102fc44..49e3c527 100644 --- a/python/jupytercad-core/pyproject.toml +++ b/python/jupytercad-core/pyproject.toml @@ -46,7 +46,6 @@ exclude = [".github", "binder"] [tool.hatch.build.targets.wheel.shared-data] "jupytercad_core/labextension" = "share/jupyter/labextensions/@jupytercad/jupytercad-core" "install.json" = "share/jupyter/labextensions/@jupytercad/jupytercad-core/install.json" -"jupyter-config/server-config" = "etc/jupyter/jupyter_server_config.d" [tool.hatch.build.hooks.version] path = "jupytercad_core/_version.py" diff --git a/python/jupytercad-lab/jupyter-config/server-config/jupytercad_lab.json b/python/jupytercad-lab/jupyter-config/server-config/jupytercad_lab.json deleted file mode 100644 index aa253672..00000000 --- a/python/jupytercad-lab/jupyter-config/server-config/jupytercad_lab.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "ServerApp": { - "jpserver_extensions": { - "jupytercad_lab": true - } - } -} diff --git a/python/jupytercad-lab/jupytercad_lab/__init__.py b/python/jupytercad-lab/jupytercad_lab/__init__.py index 0d20641e..684c9a7c 100644 --- a/python/jupytercad-lab/jupytercad_lab/__init__.py +++ b/python/jupytercad-lab/jupytercad_lab/__init__.py @@ -8,25 +8,7 @@ warnings.warn("Importing 'jupytercad_lab' outside a proper installation.") __version__ = "dev" -from .handlers import setup_handlers def _jupyter_labextension_paths(): return [{"src": "labextension", "dest": "@jupytercad/jupytercad-lab"}] - - -def _jupyter_server_extension_points(): - return [{"module": "jupytercad_lab"}] - - -def _load_jupyter_server_extension(server_app): - """Registers the API handler to receive HTTP requests from the frontend extension. - - Parameters - ---------- - server_app: jupyterlab.labapp.LabApp - JupyterLab application instance - """ - setup_handlers(server_app.web_app) - name = "jupytercad_lab" - server_app.log.info(f"Registered {name} server extension") diff --git a/python/jupytercad-lab/jupytercad_lab/handlers.py b/python/jupytercad-lab/jupytercad_lab/handlers.py deleted file mode 100644 index 1b3b37d6..00000000 --- a/python/jupytercad-lab/jupytercad_lab/handlers.py +++ /dev/null @@ -1,25 +0,0 @@ -import json - -from jupyter_server.base.handlers import APIHandler -from jupyter_server.utils import url_path_join -import tornado - - -class RouteHandler(APIHandler): - # 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 get(self): - self.finish( - json.dumps({"data": "This is /jupytercad-lab/get-example endpoint!"}) - ) - - -def setup_handlers(web_app): - host_pattern = ".*$" - - base_url = web_app.settings["base_url"] - route_pattern = url_path_join(base_url, "jupytercad-lab", "get-example") - handlers = [(route_pattern, RouteHandler)] - web_app.add_handlers(host_pattern, handlers) diff --git a/python/jupytercad-lab/pyproject.toml b/python/jupytercad-lab/pyproject.toml index a461cac5..435e6a10 100644 --- a/python/jupytercad-lab/pyproject.toml +++ b/python/jupytercad-lab/pyproject.toml @@ -53,7 +53,6 @@ exclude = [".github", "binder"] [tool.hatch.build.targets.wheel.shared-data] "jupytercad_lab/labextension" = "share/jupyter/labextensions/@jupytercad/jupytercad-lab" "install.json" = "share/jupyter/labextensions/@jupytercad/jupytercad-lab/install.json" -"jupyter-config/server-config" = "etc/jupyter/jupyter_server_config.d" [tool.hatch.build.hooks.version] path = "jupytercad_lab/_version.py" diff --git a/jupyverse/COPYING.md b/python/jupyverse/COPYING.md similarity index 100% rename from jupyverse/COPYING.md rename to python/jupyverse/COPYING.md diff --git a/jupyverse/README.md b/python/jupyverse/README.md similarity index 100% rename from jupyverse/README.md rename to python/jupyverse/README.md diff --git a/jupyverse/fps_jupytercad/__init__.py b/python/jupyverse/fps_jupytercad/__init__.py similarity index 100% rename from jupyverse/fps_jupytercad/__init__.py rename to python/jupyverse/fps_jupytercad/__init__.py diff --git a/jupyverse/fps_jupytercad/main.py b/python/jupyverse/fps_jupytercad/main.py similarity index 100% rename from jupyverse/fps_jupytercad/main.py rename to python/jupyverse/fps_jupytercad/main.py diff --git a/jupyverse/fps_jupytercad/models.py b/python/jupyverse/fps_jupytercad/models.py similarity index 100% rename from jupyverse/fps_jupytercad/models.py rename to python/jupyverse/fps_jupytercad/models.py diff --git a/jupyverse/fps_jupytercad/py.typed b/python/jupyverse/fps_jupytercad/py.typed similarity index 100% rename from jupyverse/fps_jupytercad/py.typed rename to python/jupyverse/fps_jupytercad/py.typed diff --git a/jupyverse/fps_jupytercad/routes.py b/python/jupyverse/fps_jupytercad/routes.py similarity index 100% rename from jupyverse/fps_jupytercad/routes.py rename to python/jupyverse/fps_jupytercad/routes.py diff --git a/jupyverse/pyproject.toml b/python/jupyverse/pyproject.toml similarity index 100% rename from jupyverse/pyproject.toml rename to python/jupyverse/pyproject.toml diff --git a/jupyverse/scripts/bump-version.py b/python/jupyverse/scripts/bump-version.py similarity index 100% rename from jupyverse/scripts/bump-version.py rename to python/jupyverse/scripts/bump-version.py diff --git a/scripts/dev-install.py b/scripts/dev-install.py index 706a2c9d..518db2e3 100644 --- a/scripts/dev-install.py +++ b/scripts/dev-install.py @@ -14,7 +14,7 @@ def install_dev(): build_js = "jlpm build" python_package_prefix = "python" - python_packages = ["jupytercad-core", "jupytercad-lab"] + python_packages = ["jupytercad-core", "jupytercad-lab", "jupytercad-app"] execute(install_build_deps) execute(install_js_deps) @@ -23,9 +23,10 @@ def install_dev(): execute(f"pip uninstall {py_package} -y") execute("jlpm clean:all", cwd=root_path / "python" / py_package) execute(f"pip install -e {python_package_prefix}/{py_package}") - execute( - f"jupyter labextension develop {python_package_prefix}/{py_package} --overwrite" - ) + if py_package != "jupytercad-app": + execute( + f"jupyter labextension develop {python_package_prefix}/{py_package} --overwrite" + ) if __name__ == "__main__": diff --git a/setup.py b/setup.py deleted file mode 100644 index b6c66813..00000000 --- a/setup.py +++ /dev/null @@ -1,2 +0,0 @@ -# setup.py shim for use with applications that require it. -__import__("setuptools").setup()