diff --git a/.gitignore b/.gitignore index d78fcd47e..4d4e978fc 100644 --- a/.gitignore +++ b/.gitignore @@ -75,6 +75,7 @@ test/pipelines/input-output-json-pipeline/emscripten-build/ test/pipelines/input-output-json-pipeline/wasi-build/ test/pipelines/bindgen-interface-types-pipeline/python/ test/pipelines/bindgen-interface-types-pipeline/wasi-build/ +test/pipelines/bindgen-interface-types-pipeline/python-web-demo cypress/screenshots/ cypress/videos/ diff --git a/docs/introduction/packages.md b/docs/introduction/packages.md index aac92bbc8..9f61e1efd 100644 --- a/docs/introduction/packages.md +++ b/docs/introduction/packages.md @@ -6,8 +6,8 @@ request](https://github.com/InsightSoftwareConsortium/itk-wasm/compare) to add i | Repository | Description | Links | |-----------------------------|:---------------------------------------------:|:----------------------:| -| [@itk-wasm/compress-stringify][compress-stringify-repo] |
*Zstandard compression and decompression and base64 encoding and decoding in WebAssembly.* | ![js][js-logo] ![ts][ts-logo]
[💻 Demo][compress-stringify-demo-js]
[🕮 Docs][compress-stringify-docs-js]
[📦 Package][compress-stringify-package-js]

![py][py-logo]
[💻 Demo][compress-stringify-demo-py]
[🕮 Docs][compress-stringify-docs-py]
[📦 Package][compress-stringify-package-py] | -| [@itk-wasm/dicom][dicom-repo] |
*Read files and images related to DICOM file format.* | ![js][js-logo] ![ts][ts-logo]
[💻 Demo][dicom-demo-js]
[🕮 Docs][dicom-docs-js]
[📦 Package][dicom-package-js]

![py][py-logo]
[🕮 Docs][dicom-docs-py]
[📦 Package][dicom-package-py] | +| [@itk-wasm/compress-stringify][compress-stringify-repo] |
*Zstandard compression and decompression and base64 encoding and decoding in WebAssembly.* | ![js][js-logo] ![ts][ts-logo]
[👨‍💻 Demo][compress-stringify-demo-js]
[🕮 Docs][compress-stringify-docs-js]
[📦 Package][compress-stringify-package-js]

![py][py-logo]
[👨‍💻 Demo][compress-stringify-demo-py]
[🕮 Docs][compress-stringify-docs-py]
[📦 Package][compress-stringify-package-py] | +| [@itk-wasm/dicom][dicom-repo] |
*Read files and images related to DICOM file format.* | ![js][js-logo] ![ts][ts-logo]
[👨‍💻 Demo][dicom-demo-js]
[🕮 Docs][dicom-docs-js]
[📦 Package][dicom-package-js]

![py][py-logo]
[🕮 Docs][dicom-docs-py]
[📦 Package][dicom-package-py] | [js-logo]: /_static/javascript-logo.svg [ts-logo]: /_static/typescript-logo.svg diff --git a/package.json b/package.json index 0930c8e7e..a34c3a242 100644 --- a/package.json +++ b/package.json @@ -63,6 +63,7 @@ "test:cliTest": "node src/itk-wasm-cli.js -b wasi-build -s ./test/pipelines/stdout-stderr-pipeline test", "test:cliBindgen:typescript": "node src/itk-wasm-cli.js -b emscripten-build -s ./test/pipelines/bindgen-interface-types-pipeline bindgen --package-version 1.0.0 --package-name @itk-wasm/bindgen-interface-types-test --package-description \"Exercise interface types for bindgen\"", "test:cliBindgen:python": "node src/itk-wasm-cli.js -b wasi-build -s ./test/pipelines/bindgen-interface-types-pipeline bindgen --interface python --package-version 1.0.0 --package-name itkwasm-bindgen-interface-types-test --package-description \"Exercise interface types for bindgen\"", + "test:cliBindgen:python-web-demo": "node src/itk-wasm-cli.js -b wasi-build -s ./test/pipelines/bindgen-interface-types-pipeline bindgen --interface python-web-demo --package-version 1.0.0 --package-name itkwasm-bindgen-interface-types-test --package-description \"Exercise interface types for bindgen\"", "test:browser": "karma start ./karma.conf.cjs", "test:browser:debug": "karma start ./karma.conf.cjs --no-single-run", "test:browser:debug:cypress": "start-server-and-test start http-get://localhost:8083 cypress:open", diff --git a/packages/compress-stringify/python/itkwasm-compress-stringify/README.md b/packages/compress-stringify/python/itkwasm-compress-stringify/README.md index 30e691d0c..1193f54bc 100644 --- a/packages/compress-stringify/python/itkwasm-compress-stringify/README.md +++ b/packages/compress-stringify/python/itkwasm-compress-stringify/README.md @@ -4,7 +4,7 @@ Zstandard compression and decompression and base64 encoding and decoding in WebAssembly. -[💻 **Live API Demo** ✨](https://itk-compress-stringify-py-app.on.fleek.co/) +[👨‍💻‍ **Live API Demo** ✨](https://itk-compress-stringify-py-app.on.fleek.co/) [🕮 **Documentation** 📚](https://itk-wasm-compress-stringify-python-docs.on.fleek.co/) diff --git a/packages/compress-stringify/typescript/README.md b/packages/compress-stringify/typescript/README.md index c47aee128..4ecb0202c 100644 --- a/packages/compress-stringify/typescript/README.md +++ b/packages/compress-stringify/typescript/README.md @@ -4,7 +4,7 @@ > Zstandard compression and decompression and base64 encoding and decoding in WebAssembly. -[💻 **Live API Demo** ✨](https://itk-compress-stringify-app.on.fleek.co/ ':include :type=iframe width=100% height=800px') +[👨‍💻 **Live API Demo** ✨](https://itk-compress-stringify-app.on.fleek.co/ ':include :type=iframe width=100% height=800px') [🕮 **Documentation** 📚](https://itk-compress-stringify-docs.on.fleek.co/) diff --git a/src/bindgen/python-web-demo/input-parameters-python.js b/src/bindgen/python-web-demo/input-parameters-python.js index 417ec9fa1..d6fb7cc4d 100644 --- a/src/bindgen/python-web-demo/input-parameters-python.js +++ b/src/bindgen/python-web-demo/input-parameters-python.js @@ -7,6 +7,7 @@ function inputParametersPython(functionName, indent, parameter, required) { const parameterName = snakeCase(parameter.name) const inputIdentifier = `${parameterName}_element` switch (parameter.type) { + case 'INPUT_TEXT_FILE': case 'INPUT_TEXT_FILE:FILE': case 'INPUT_TEXT_STREAM': initResult += `${indent} ${inputIdentifier} = js.document.querySelector('#${functionName}-inputs input[name=${parameter.name}-file]')\n` @@ -19,6 +20,7 @@ function inputParametersPython(functionName, indent, parameter, required) { methodResult += `${indent} ${parameterName}_element = js.document.getElementById("${functionName}-${parameterName}-details")\n` methodResult += `${indent} ${parameterName}_element.innerHTML = f"
{${parameterName}_str[:50] + ' ...'}
"\n\n` break + case 'INPUT_BINARY_FILE': case 'INPUT_BINARY_FILE:FILE': case 'INPUT_BINARY_STREAM': initResult += `${indent} ${inputIdentifier} = js.document.querySelector('#${functionName}-inputs input[name=${parameter.name}-file]')\n` @@ -53,6 +55,48 @@ function inputParametersPython(functionName, indent, parameter, required) { methodResult += `${indent}def on_${parameterName}_change(self, event):\n` methodResult += `${indent} self.model.${modelProperty}['${parameterName}'] = int(self.${inputIdentifier}.value)\n\n` break + case 'INPUT_JSON': + initResult += `${indent} ${inputIdentifier} = js.document.querySelector('#${functionName}-inputs sl-input[name=${parameter.name}-file]')\n` + initResult += `${indent} self.${inputIdentifier} = ${inputIdentifier}\n` + initResult += `${indent} add_event_listener(${inputIdentifier}, 'sl-change', self.on_${parameterName}_change)\n\n` + methodResult += `${indent}async def on_${parameterName}_change(self, event):\n` + methodResult += `${indent} files = event.target.files\n` + methodResult += `${indent} array_buffer = await files.item(0).arrayBuffer()\n` + methodResult += `${indent} ${parameterName}_str = array_buffer.to_string()\n` + methodResult += `${indent} ${parameterName}_value = json.loads(${parameterName}_str)\n` + methodResult += `${indent} self.model.${modelProperty}['${parameterName}'] = ${parameterName}_value\n` + methodResult += `${indent} ${parameterName}_element = js.document.getElementById("${functionName}-${parameterName}-details")\n` + methodResult += `${indent} ${parameterName}_element.innerHTML = f"
{js.escapeHtml(js.JSON.stringify(${parameterName}_value), js.interfaceTypeJsonReplacer, 2)}}
"\n` + methodResult += `${indent} ${parameterName}_element.disabled = False\n\n` + break + case 'INPUT_IMAGE': + // todo + result += `${indent}const ${inputIdentifier} = document.querySelector('#${functionName}Inputs input[name=${parameter.name}-file]')\n` + result += `${indent}${inputIdentifier}.addEventListener('change', async (event) => {\n` + result += `${indent}${indent}const dataTransfer = event.dataTransfer\n` + result += `${indent}${indent}const files = event.target.files || dataTransfer.files\n\n` + result += `${indent}${indent}const { image, webWorker } = await readImageFile(null, files[0])\n` + result += `${indent}${indent}webWorker.terminate()\n` + result += `${indent}${indent}model.${modelProperty}.set("${parameterName}", image)\n` + result += `${indent}${indent}const details = document.getElementById("${functionName}-${parameter.name}-details")\n` + result += `${indent}${indent}details.innerHTML = \`
$\{globalThis.escapeHtml(JSON.stringify(image, globalThis.interfaceTypeJsonReplacer, 2))}
\`\n` + result += `${indent}${indent}details.disabled = false\n` + result += `${indent}})\n\n` + break + case 'INPUT_MESH': + // todo + result += `${indent}const ${inputIdentifier} = document.querySelector('#${functionName}Inputs input[name=${parameter.name}-file]')\n` + result += `${indent}${inputIdentifier}.addEventListener('change', async (event) => {\n` + result += `${indent}${indent}const dataTransfer = event.dataTransfer\n` + result += `${indent}${indent}const files = event.target.files || dataTransfer.files\n\n` + result += `${indent}${indent}const { mesh, webWorker } = await readMeshFile(null, files[0])\n` + result += `${indent}${indent}webWorker.terminate()\n` + result += `${indent}${indent}model.${modelProperty}.set("${parameterName}", mesh)\n` + result += `${indent}${indent}const details = document.getElementById("${functionName}-${parameter.name}-details")\n` + result += `${indent}${indent}details.innerHTML = \`
$\{globalThis.escapeHtml(JSON.stringify(mesh, globalThis.interfaceTypeJsonReplacer, 2))}
\`\n` + result += `${indent}${indent}details.disabled = false\n` + result += `${indent}})\n\n` + break default: console.error(`Unexpected interface type: ${parameter.type}`) process.exit(1) diff --git a/src/bindgen/python-web-demo/interface-function-python.js b/src/bindgen/python-web-demo/interface-function-python.js index 116cff729..e35c2d686 100644 --- a/src/bindgen/python-web-demo/interface-function-python.js +++ b/src/bindgen/python-web-demo/interface-function-python.js @@ -16,6 +16,7 @@ function interfaceFunctionPython(packageName, interfaceJson, outputPath) { let result = `from dataclasses import dataclass from typing import Any, Dict +import json import numpy as np diff --git a/src/bindgen/typescript/resources/demo-app/index.html b/src/bindgen/typescript/resources/demo-app/index.html index 8ba0b3007..c3b3c68ad 100644 --- a/src/bindgen/typescript/resources/demo-app/index.html +++ b/src/bindgen/typescript/resources/demo-app/index.html @@ -21,6 +21,7 @@

@bindgenPackageName@

@bindgenPackageDescription@ +

👨‍💻 Live API Demo ✨