Skip to content

Commit

Permalink
Merge pull request #1 from jupytercad/update-export-jcad
Browse files Browse the repository at this point in the history
Add JCAD export endpoint
  • Loading branch information
trungleduc authored May 7, 2024
2 parents bac86b2 + 17e623a commit d2fbf79
Show file tree
Hide file tree
Showing 16 changed files with 297 additions and 133 deletions.
1 change: 0 additions & 1 deletion .copier-answers.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,3 @@ project_short_description: A JupyterCAD extension for OpenVSP
python_name: jupytercad_openvsp
repository: https://github.com/jupytercad/jupytercad-openvsp
test: false

113 changes: 56 additions & 57 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,78 +15,77 @@ jobs:
runs-on: ubuntu-latest

steps:
- name: Checkout
uses: actions/checkout@v4
- name: Checkout
uses: actions/checkout@v4

- name: Base Setup
uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1
- name: Base Setup
uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1

- name: Install dependencies
run: python -m pip install -U "jupyterlab>=4.0.0,<5"
- name: Install dependencies
run: python -m pip install -U "jupyterlab>=4.0.0,<5"

- name: Lint the extension
run: |
set -eux
jlpm
jlpm run lint:check
- name: Lint the extension
run: |
set -eux
jlpm
jlpm run lint:check
- name: Build the extension
run: |
set -eux
python -m pip install .[test]
- name: Build the extension
run: |
set -eux
python -m pip install .[test]
jupyter server extension list
jupyter server extension list 2>&1 | grep -ie "jupytercad_openvsp.*OK"
jupyter server extension list
jupyter server extension list 2>&1 | grep -ie "jupytercad_openvsp.*OK"
jupyter labextension list
jupyter labextension list 2>&1 | grep -ie "@jupytercad/jupytercad_openvsp.*OK"
python -m jupyterlab.browser_check
jupyter labextension list
jupyter labextension list 2>&1 | grep -ie "@jupytercad/jupytercad-openvsp.*OK"
python -m jupyterlab.browser_check
- name: Package the extension
run: |
set -eux
- name: Package the extension
run: |
set -eux
pip install build
python -m build
pip uninstall -y "jupytercad_openvsp" jupyterlab
pip install build
python -m build
pip uninstall -y "jupytercad_openvsp" jupyterlab
- name: Upload extension packages
uses: actions/upload-artifact@v4
with:
name: extension-artifacts
path: dist/jupytercad_openvsp*
if-no-files-found: error
- name: Upload extension packages
uses: actions/upload-artifact@v4
with:
name: extension-artifacts
path: dist/jupytercad_openvsp*
if-no-files-found: error

test_isolated:
needs: build
runs-on: ubuntu-latest

steps:
- name: Install Python
uses: actions/setup-python@v5
with:
python-version: '3.9'
architecture: 'x64'
- uses: actions/download-artifact@v4
with:
name: extension-artifacts
- name: Install and Test
run: |
set -eux
# Remove NodeJS, twice to take care of system and locally installed node versions.
sudo rm -rf $(which node)
sudo rm -rf $(which node)
pip install "jupyterlab>=4.0.0,<5" jupytercad_openvsp*.whl
jupyter server extension list
jupyter server extension list 2>&1 | grep -ie "jupytercad_openvsp.*OK"
jupyter labextension list
jupyter labextension list 2>&1 | grep -ie "jupytercad_openvsp.*OK"
python -m jupyterlab.browser_check --no-browser-test
- name: Install Python
uses: actions/setup-python@v5
with:
python-version: '3.9'
architecture: 'x64'
- uses: actions/download-artifact@v4
with:
name: extension-artifacts
- name: Install and Test
run: |
set -eux
# Remove NodeJS, twice to take care of system and locally installed node versions.
sudo rm -rf $(which node)
sudo rm -rf $(which node)
pip install "jupyterlab>=4.0.0,<5" jupytercad_openvsp*.whl
jupyter server extension list
jupyter server extension list 2>&1 | grep -ie "jupytercad_openvsp.*OK"
jupyter labextension list
jupyter labextension list 2>&1 | grep -ie "@jupytercad/jupytercad-openvsp.*OK"
python -m jupyterlab.browser_check --no-browser-test
check_links:
name: Check Links
Expand Down
5 changes: 2 additions & 3 deletions .github/workflows/check-release.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
name: Check Release
on:
push:
branches: ["main"]
branches: ['main']
pull_request:
branches: ["*"]
branches: ['*']

concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
Expand All @@ -20,7 +20,6 @@ jobs:
- name: Check Release
uses: jupyter-server/jupyter_releaser/.github/actions/check-release@v2
with:

token: ${{ secrets.GITHUB_TOKEN }}

- name: Upload Distributions
Expand Down
16 changes: 8 additions & 8 deletions .github/workflows/prep-release.yml
Original file line number Diff line number Diff line change
@@ -1,26 +1,26 @@
name: "Step 1: Prep Release"
name: 'Step 1: Prep Release'
on:
workflow_dispatch:
inputs:
version_spec:
description: "New Version Specifier"
default: "next"
description: 'New Version Specifier'
default: 'next'
required: false
branch:
description: "The branch to target"
description: 'The branch to target'
required: false
post_version_spec:
description: "Post Version Specifier"
description: 'Post Version Specifier'
required: false
# silent:
# description: "Set a placeholder in the changelog and don't publish the release."
# required: false
# type: boolean
since:
description: "Use PRs with activity since this date or git reference"
description: 'Use PRs with activity since this date or git reference'
required: false
since_last_stable:
description: "Use PRs with activity since the last stable git tag"
description: 'Use PRs with activity since the last stable git tag'
required: false
type: boolean
jobs:
Expand All @@ -41,6 +41,6 @@ jobs:
since: ${{ github.event.inputs.since }}
since_last_stable: ${{ github.event.inputs.since_last_stable }}

- name: "** Next Step **"
- name: '** Next Step **'
run: |
echo "Optional): Review Draft Release: ${{ steps.prep-release.outputs.release_url }}"
12 changes: 6 additions & 6 deletions .github/workflows/publish-release.yml
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
name: "Step 2: Publish Release"
name: 'Step 2: Publish Release'
on:
workflow_dispatch:
inputs:
branch:
description: "The target branch"
description: 'The target branch'
required: false
release_url:
description: "The URL of the draft GitHub release"
description: 'The URL of the draft GitHub release'
required: false
steps_to_skip:
description: "Comma separated list of steps to skip"
description: 'Comma separated list of steps to skip'
required: false

jobs:
Expand Down Expand Up @@ -44,13 +44,13 @@ jobs:
token: ${{ secrets.ADMIN_GITHUB_TOKEN }}
release_url: ${{ steps.populate-release.outputs.release_url }}

- name: "** Next Step **"
- name: '** Next Step **'
if: ${{ success() }}
run: |
echo "Verify the final release"
echo ${{ steps.finalize-release.outputs.release_url }}
- name: "** Failure Message **"
- name: '** Failure Message **'
if: ${{ failure() }}
run: |
echo "Failed to Publish the Draft Release Url:"
Expand Down
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -119,4 +119,4 @@ dmypy.json

# Yarn cache
.yarn/
.jupyter_ystore.db
.jupyter_ystore.db
56 changes: 56 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
ci:
# pre-commit.ci will open PRs updating our hooks once a month
autoupdate_schedule: monthly
# skip any check that needs internet access
autofix_prs: true
exclude: '.*\.jcad$'
repos:
# Autoformat and linting, misc. details
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.5.0
hooks:
- id: forbid-new-submodules
- id: end-of-file-fixer
exclude: galata/.*-snapshots
- id: check-case-conflict
- id: requirements-txt-fixer
- id: check-added-large-files
args: ['--maxkb=5000']
- id: check-case-conflict
- id: check-toml
- id: check-yaml
- id: debug-statements
- id: check-builtin-literals
- id: trailing-whitespace
exclude: .bumpversion.cfg

# Autoformat: Python code
- repo: https://github.com/psf/black
rev: 23.12.1
hooks:
- id: black

- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.1.9
hooks:
- id: ruff
args: ['--fix']

- repo: https://github.com/pre-commit/mirrors-prettier
rev: v4.0.0-alpha.8
hooks:
- id: prettier
args: ['--no-error-on-unmatched-pattern']

- repo: https://github.com/pre-commit/mirrors-eslint
rev: v9.0.0-alpha.0
hooks:
- id: eslint
files: \.tsx?$
types: [file]
additional_dependencies:
- '[email protected]'
- '@typescript-eslint/[email protected]'
- '@typescript-eslint/[email protected]'
- '[email protected]'
- '[email protected]'
1 change: 1 addition & 0 deletions .yarnrc.yml
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
nodeLinker: node-modules
enableImmutableInstalls: false
10 changes: 3 additions & 7 deletions jupytercad_openvsp/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,18 @@
# in editable mode with pip. It is highly recommended to install
# the package from a stable release or in editable mode: https://pip.pypa.io/en/stable/topics/local-project-installs/#editable-installs
import warnings

warnings.warn("Importing 'jupytercad_openvsp' outside a proper installation.")
__version__ = "dev"
from .handlers import setup_handlers


def _jupyter_labextension_paths():
return [{
"src": "labextension",
"dest": "@jupytercad/jupytercad-openvsp"
}]
return [{"src": "labextension", "dest": "@jupytercad/jupytercad-openvsp"}]


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


def _load_jupyter_server_extension(server_app):
Expand Down
51 changes: 40 additions & 11 deletions jupytercad_openvsp/handlers.py
Original file line number Diff line number Diff line change
@@ -1,24 +1,53 @@
import json
from pathlib import Path

from jupyter_server.base.handlers import APIHandler
from jupyter_server.utils import url_path_join
from jupyter_server.utils import url_path_join, ApiPath, to_os_path
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
from jupytercad_openvsp.loader import vsp3_to_stl


class JCadExportHandler(APIHandler):
@tornado.web.authenticated
def get(self):
self.finish(json.dumps({
"data": "This is /jupytercad-openvsp/get-example endpoint!"
}))
def post(self):
body = self.get_json_body()

# Get filename removing the drive prefix
file_name = body["path"].split(":")[1]
export_name = body["newName"]

root_dir = Path(self.contents_manager.root_dir).resolve()
file_name = Path(to_os_path(ApiPath(file_name), str(root_dir)))

with open(file_name, "r") as fobj:
file_content = fobj.read()

stl_content = vsp3_to_stl(file_content)
jcad = dict(
objects=[
dict(
name=Path(export_name).stem,
visible=True,
shape="Part::Any",
parameters=dict(Content=stl_content, Type="STL"),
)
],
metadata={},
options={},
outputs={},
)

with open(Path(file_name).parents[0] / export_name, "w") as fobj:
fobj.write(json.dumps(jcad, indent=2))

self.finish(json.dumps({"done": True}))


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

base_url = web_app.settings["base_url"]
route_pattern = url_path_join(base_url, "jupytercad-openvsp", "get-example")
handlers = [(route_pattern, RouteHandler)]
route_pattern = url_path_join(base_url, "jupytercad", "export-ovsp")
handlers = [(route_pattern, JCadExportHandler)]
web_app.add_handlers(host_pattern, handlers)
Loading

0 comments on commit d2fbf79

Please sign in to comment.