Skip to content

Commit

Permalink
Merge pull request #957 from thewtex/python-output-path
Browse files Browse the repository at this point in the history
Python output path
  • Loading branch information
thewtex authored Sep 29, 2023
2 parents 7b05e3c + e171721 commit 44dcbc9
Show file tree
Hide file tree
Showing 22 changed files with 340 additions and 130 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
// Generated file. To retain edits, remove this comment.

import { readImageFile, copyImage } from 'itk-wasm'
import { writeImageArrayBuffer, copyImage } from 'itk-wasm'
import { readImageFile } from 'itk-wasm'
import { writeImageArrayBuffer } from 'itk-wasm'
import { copyImage } from 'itk-wasm'
import * as compareImages from '../../../dist/bundles/compare-images.js'
import compareDoubleImagesLoadSampleInputs, { usePreRun } from "./compare-double-images-load-sample-inputs.js"

Expand Down Expand Up @@ -147,19 +148,21 @@ class CompareDoubleImagesController {
const url = new URL(document.location)
url.search = params
window.history.replaceState({ functionName: 'compareDoubleImages' }, '', url)
await preRun()
}
await preRun()
}
}

const tabGroup = document.querySelector('sl-tab-group')
tabGroup.addEventListener('sl-tab-show', onSelectTab)
document.addEventListener('DOMContentLoaded', () => {
function onInit() {
const params = new URLSearchParams(window.location.search)
if (params.has('functionName') && params.get('functionName') === 'compareDoubleImages') {
tabGroup.show('compareDoubleImages-panel')
preRun()
}
})
}
onInit()

const runButton = document.querySelector('#compareDoubleImagesInputs sl-button[name="run"]')
runButton.addEventListener('click', async (event) => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
// Generated file. To retain edits, remove this comment.

import { readImageFile, copyImage } from 'itk-wasm'
import { writeImageArrayBuffer, copyImage } from 'itk-wasm'
import { readImageFile } from 'itk-wasm'
import { writeImageArrayBuffer } from 'itk-wasm'
import { copyImage } from 'itk-wasm'
import * as compareImages from '../../../dist/bundles/compare-images.js'
import vectorMagnitudeLoadSampleInputs, { usePreRun } from "./vector-magnitude-load-sample-inputs.js"

Expand Down Expand Up @@ -88,19 +89,21 @@ class VectorMagnitudeController {
const url = new URL(document.location)
url.search = params
window.history.replaceState({ functionName: 'vectorMagnitude' }, '', url)
await preRun()
}
await preRun()
}
}

const tabGroup = document.querySelector('sl-tab-group')
tabGroup.addEventListener('sl-tab-show', onSelectTab)
document.addEventListener('DOMContentLoaded', () => {
function onInit() {
const params = new URLSearchParams(window.location.search)
if (params.has('functionName') && params.get('functionName') === 'vectorMagnitude') {
tabGroup.show('vectorMagnitude-panel')
preRun()
}
})
}
onInit()

const runButton = document.querySelector('#vectorMagnitudeInputs sl-button[name="run"]')
runButton.addEventListener('click', async (event) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,19 +94,21 @@ class CompressStringifyController {
const url = new URL(document.location)
url.search = params
window.history.replaceState({ functionName: 'compressStringify' }, '', url)
await preRun()
}
await preRun()
}
}

const tabGroup = document.querySelector('sl-tab-group')
tabGroup.addEventListener('sl-tab-show', onSelectTab)
document.addEventListener('DOMContentLoaded', () => {
function onInit() {
const params = new URLSearchParams(window.location.search)
if (params.has('functionName') && params.get('functionName') === 'compressStringify') {
tabGroup.show('compressStringify-panel')
preRun()
}
})
}
onInit()

const runButton = document.querySelector('#compressStringifyInputs sl-button[name="run"]')
runButton.addEventListener('click', async (event) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ compressStringify.setPipelinesBaseUrl(pipelinesBaseUrl)
const pipelineWorkerUrl: string | URL | null = new URL('/web-workers/pipeline.worker.js', document.location.origin).href
compressStringify.setPipelineWorkerUrl(pipelineWorkerUrl)

import './compress-stringify-controller.js'
import './parse-string-decompress-controller.js'

const params = new URLSearchParams(window.location.search)
if (!params.has('functionName')) {
Expand All @@ -18,3 +16,5 @@ if (!params.has('functionName')) {
url.search = params
window.history.replaceState({ functionName: 'compressStringify' }, '', url)
}
import './compress-stringify-controller.js'
import './parse-string-decompress-controller.js'
Original file line number Diff line number Diff line change
Expand Up @@ -84,19 +84,21 @@ class ParseStringDecompressController {
const url = new URL(document.location)
url.search = params
window.history.replaceState({ functionName: 'parseStringDecompress' }, '', url)
await preRun()
}
await preRun()
}
}

const tabGroup = document.querySelector('sl-tab-group')
tabGroup.addEventListener('sl-tab-show', onSelectTab)
document.addEventListener('DOMContentLoaded', () => {
function onInit() {
const params = new URLSearchParams(window.location.search)
if (params.has('functionName') && params.get('functionName') === 'parseStringDecompress') {
tabGroup.show('parseStringDecompress-panel')
preRun()
}
})
}
onInit()

const runButton = document.querySelector('#parseStringDecompressInputs sl-button[name="run"]')
runButton.addEventListener('click', async (event) => {
Expand Down
2 changes: 1 addition & 1 deletion packages/core/python/itkwasm/itkwasm/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"""itkwasm: Python interface to itk-wasm WebAssembly modules."""

__version__ = "1.0b141"
__version__ = "1.0b142"

from .interface_types import InterfaceTypes
from .image import Image, ImageType
Expand Down
4 changes: 2 additions & 2 deletions packages/core/python/itkwasm/itkwasm/pyodide.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ def to_py(js_proxy):
# int, etc
return js_proxy

def to_js(py):
def to_js(py, **kwargs):
import pyodide
import js
if isinstance(py, list):
Expand Down Expand Up @@ -222,4 +222,4 @@ def to_js(py):
text_file_dict['data'] = data
return pyodide.ffi.to_js(text_file_dict, dict_converter=js.Object.fromEntries)

return pyodide.ffi.to_js(py)
return pyodide.ffi.to_js(py, **kwargs)
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Generated file. To retain edits, remove this comment.

import { writeImageArrayBuffer, copyImage } from 'itk-wasm'
import { writeImageArrayBuffer } from 'itk-wasm'
import { copyImage } from 'itk-wasm'
import * as dicom from '../../../dist/bundles/dicom.js'
import applyPresentationStateToImageLoadSampleInputs, { usePreRun } from "./apply-presentation-state-to-image-load-sample-inputs.js"

Expand Down Expand Up @@ -133,19 +134,21 @@ class ApplyPresentationStateToImageController {
const url = new URL(document.location)
url.search = params
window.history.replaceState({ functionName: 'applyPresentationStateToImage' }, '', url)
await preRun()
}
await preRun()
}
}

const tabGroup = document.querySelector('sl-tab-group')
tabGroup.addEventListener('sl-tab-show', onSelectTab)
document.addEventListener('DOMContentLoaded', () => {
function onInit() {
const params = new URLSearchParams(window.location.search)
if (params.has('functionName') && params.get('functionName') === 'applyPresentationStateToImage') {
tabGroup.show('applyPresentationStateToImage-panel')
preRun()
}
})
}
onInit()

const runButton = document.querySelector('#applyPresentationStateToImageInputs sl-button[name="run"]')
runButton.addEventListener('click', async (event) => {
Expand Down
12 changes: 6 additions & 6 deletions packages/dicom/typescript/test/browser/demo-app/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,6 @@ dicom.setPipelinesBaseUrl(pipelinesBaseUrl)
const pipelineWorkerUrl: string | URL | null = new URL('/web-workers/pipeline.worker.js', document.location.origin).href
dicom.setPipelineWorkerUrl(pipelineWorkerUrl)

import './apply-presentation-state-to-image-controller.js'
import './read-dicom-encapsulated-pdf-controller.js'
import './structured-report-to-html-controller.js'
import './structured-report-to-text-controller.js'
import './read-dicom-tags-controller.js'
import './read-image-dicom-file-series-controller.js'

const params = new URLSearchParams(window.location.search)
if (!params.has('functionName')) {
Expand All @@ -22,3 +16,9 @@ if (!params.has('functionName')) {
url.search = params
window.history.replaceState({ functionName: 'applyPresentationStateToImage' }, '', url)
}
import './apply-presentation-state-to-image-controller.js'
import './read-dicom-encapsulated-pdf-controller.js'
import './structured-report-to-html-controller.js'
import './structured-report-to-text-controller.js'
import './read-dicom-tags-controller.js'
import './read-image-dicom-file-series-controller.js'
Original file line number Diff line number Diff line change
Expand Up @@ -92,19 +92,21 @@ class ReadDicomTagsController {
const url = new URL(document.location)
url.search = params
window.history.replaceState({ functionName: 'readDicomTags' }, '', url)
await preRun()
}
await preRun()
}
}

const tabGroup = document.querySelector('sl-tab-group')
tabGroup.addEventListener('sl-tab-show', onSelectTab)
document.addEventListener('DOMContentLoaded', () => {
function onInit() {
const params = new URLSearchParams(window.location.search)
if (params.has('functionName') && params.get('functionName') === 'readDicomTags') {
tabGroup.show('readDicomTags-panel')
preRun()
}
})
}
onInit()

const runButton = document.querySelector('#readDicomTagsInputs sl-button[name="run"]')
runButton.addEventListener('click', async (event) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -164,19 +164,21 @@ class StructuredReportToTextController {
const url = new URL(document.location)
url.search = params
window.history.replaceState({ functionName: 'structuredReportToText' }, '', url)
await preRun()
}
await preRun()
}
}

const tabGroup = document.querySelector('sl-tab-group')
tabGroup.addEventListener('sl-tab-show', onSelectTab)
document.addEventListener('DOMContentLoaded', () => {
function onInit() {
const params = new URLSearchParams(window.location.search)
if (params.has('functionName') && params.get('functionName') === 'structuredReportToText') {
tabGroup.show('structuredReportToText-panel')
preRun()
}
})
}
onInit()

const runButton = document.querySelector('#structuredReportToTextInputs sl-button[name="run"]')
runButton.addEventListener('click', async (event) => {
Expand Down
12 changes: 12 additions & 0 deletions src/bindgen/input-array-check.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
function inputArrayCheck(interfaceJson) {
interfaceJson.inputs.forEach((input) => {
const isArray = input.itemsExpectedMax > 1
if (isArray) {
console.error('Positional multi-value inputs are currently not supported -- please use an option instead')
console.error(`Violating option: ${input.name}`)
process.exit(1)
}
})
}

export default inputArrayCheck
16 changes: 15 additions & 1 deletion src/bindgen/python/dispatch-function-module.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import functionModuleImports from './function-module-imports.js'
import functionModuleArgs from './function-module-args.js'
import functionModuleDocstring from './function-module-docstring.js'
import functionModuleReturnType from './function-module-return-type.js'
import interfaceJsonTypeToInterfaceType from '../interface-json-type-to-interface-type.js'

function dispatchFunctionModule(interfaceJson, pypackage, modulePath) {
const functionName = snakeCase(interfaceJson.name)
Expand All @@ -24,9 +25,22 @@ from itkwasm import (
const docstring = functionModuleDocstring(interfaceJson)

let functionArgsToPass = ""
interfaceJson['inputs'].forEach((value) => {
interfaceJson.inputs.forEach((value) => {
functionArgsToPass += `${snakeCase(value.name)}, `
})
interfaceJson.outputs.forEach((output) => {
if (interfaceJsonTypeToInterfaceType.has(output.type)) {
const interfaceType = interfaceJsonTypeToInterfaceType.get(output.type)
switch (interfaceType) {
case "TextFile":
case "BinaryFile":
functionArgsToPass += `${snakeCase(output.name)}, `
break
default:
//
}
}
})
interfaceJson['parameters'].forEach((value) => {
if (value.name === "memory-io" || value.name === "version") {
return
Expand Down
17 changes: 14 additions & 3 deletions src/bindgen/python/emscripten/emscripten-function-module.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,7 @@ import writeIfOverrideNotPresent from '../../write-if-override-not-present.js'

function emscriptenFunctionModule(interfaceJson, pypackage, modulePath) {
const functionName = snakeCase(interfaceJson.name)
let moduleContent = `# Generated file. Do not edit.
from pathlib import Path
let moduleContent = `from pathlib import Path
import os
from typing import Dict, Tuple, Optional, List, Any
Expand Down Expand Up @@ -49,6 +47,19 @@ from itkwasm import (
args += `to_js(${snakeCase(input.name)}), `
}
})
interfaceJson.outputs.forEach((output) => {
if (interfaceJsonTypeToInterfaceType.has(output.type)) {
const interfaceType = interfaceJsonTypeToInterfaceType.get(output.type)
switch (interfaceType) {
case "TextFile":
case "BinaryFile":
args += `to_js(${snakeCase(output.name)}), `
break
default:
//
}
}
})

let addKwargs = ''
interfaceJson.parameters.forEach((parameter) => {
Expand Down
11 changes: 11 additions & 0 deletions src/bindgen/python/function-module-args.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,16 @@ function functionModuleArgs(interfaceJson) {
const pythonType = interfaceJsonTypeToPythonType.get(canonical)
functionArgs += ` ${snakeCase(value.name)}: ${pythonType},\n`
})
const outputFiles = interfaceJson.outputs.filter(o => { return o.type.includes('FILE') })
outputFiles.forEach((output) => {
const isArray = output.itemsExpectedMax > 1
const optionName = `${output.name}`
if (isArray) {
functionArgs += ` ${snakeCase(optionName)}: List[str],\n`
} else {
functionArgs += ` ${snakeCase(optionName)}: str,\n`
}
})
interfaceJson['parameters'].forEach((value) => {
if (value.name === "memory-io" || value.name === "version") {
return
Expand Down Expand Up @@ -45,6 +55,7 @@ function functionModuleArgs(interfaceJson) {
}
}
})

return functionArgs
}

Expand Down
15 changes: 15 additions & 0 deletions src/bindgen/python/function-module-docstring.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,18 @@ function functionModuleDocstring(interfaceJson) {
docstring += `\n :param ${snakeCase(value.name)}: ${description}\n`
docstring += ` :type ${snakeCase(value.name)}: ${pythonType}\n`
})
const outputFiles = interfaceJson.outputs.filter(o => { return o.type.includes('FILE') })
outputFiles.forEach((output) => {
const isArray = output.itemsExpectedMax > 1
const optionName = `${output.name}`
const description = output.description.replaceAll('\n', ' ')
docstring += `\n :param ${snakeCase(optionName)}: ${description}\n`
if (isArray) {
docstring += ` :type ${snakeCase(optionName)}: List[str]\n`
} else {
docstring += ` :type ${snakeCase(optionName)}: str\n`
}
})
interfaceJson['parameters'].forEach((value) => {
if (value.name === "memory-io" || value.name === "version") {
return
Expand All @@ -25,6 +37,9 @@ function functionModuleDocstring(interfaceJson) {
})
const jsonOutputs = interfaceJson['outputs']
jsonOutputs.forEach((value) => {
if (value.type.includes('FILE')) {
return
}
const description = value.description.replaceAll('\n', ' ')
const canonical = canonicalType(value.type)
const pythonType = interfaceJsonTypeToPythonType.get(canonical)
Expand Down
Loading

0 comments on commit 44dcbc9

Please sign in to comment.