Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Web UI #7

Merged
merged 19 commits into from
Aug 26, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
20 changes: 14 additions & 6 deletions docs/data-providing-service.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import os
import json
from functools import partial
from typing import List, Tuple
from typing import Tuple

import numpy as np
from hypha_rpc import connect_to_server
Expand Down Expand Up @@ -58,10 +59,17 @@ def upload_image_to_s3():
async def register_service(
server_url: str,
token: str,
image_folder: str,
annotations_folder: str,
supported_file_types: List[str],
images_path: str,
supported_file_types_json: str,
):
# Check if the images folder exists
# if not os.path.isdir(images_path):
# raise FileNotFoundError("Images path not found: " + images_path)
annotations_path = os.path.join(images_path, "annotations")

# Decode the JSON string to a Python tuple
supported_file_types = tuple(json.loads(supported_file_types_json))

# Connect to the server link
server = await connect_to_server({"server_url": server_url, "token": token})

Expand All @@ -78,10 +86,10 @@ async def register_service(
# get a random image from the dataset
# returns the image as a numpy image
"get_random_image": partial(
get_random_image, image_folder, tuple(supported_file_types)
get_random_image, images_path, supported_file_types
),
# save the annotation mask
# pass the filename of the image, the new filename, the features and the image shape
"save_annotation": partial(save_annotation, annotations_folder),
"save_annotation": partial(save_annotation, annotations_path),
}
)
38 changes: 29 additions & 9 deletions docs/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@
const serviceFile = "data-providing-service.py";
const pluginUrl = "https://raw.githubusercontent.com/bioimage-io/bioimageio-colab/main/plugins/bioimageio-colab-annotator.imjoy.html";
let workerPromise;
let workerManager;

function App() {
const [user, setUser] = useState({});
Expand All @@ -136,7 +137,7 @@
useEffect(() => {
// Create a new Pyodide worker
workerPromise = new Promise((resolve, reject) => {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I used a promise here, so we can defer the loading process, only wait for it when the user click deploy annotation. You can see how Promise works.

const workerManager = new PyodideWorkerManager();
workerManager = new PyodideWorkerManager();
workerManager.createWorker().then(worker => {
resolve(worker);
}).catch(error => {
Expand Down Expand Up @@ -193,13 +194,22 @@

const handleLogin = async () => {
const token = await login();
const server = await hyphaWebsocketClient.connectToServer({
"server_url": serverUrl,
"token": token,
});
setHyphaVersion(server.config.hyphaVersion);
setUser(server.config.user);
console.log("Logged in as:", server.config.user);
try {
const server = await hyphaWebsocketClient.connectToServer({
"server_url": serverUrl,
"token": token,
});
setHyphaVersion(server.config.hyphaVersion);
setUser(server.config.user);
console.log("Logged in as:", server.config.user);
} catch (error) {
console.error("Error connecting to server:", error);
// Clear token and tokenExpiry
localStorage.setItem("token", "");
localStorage.setItem("tokenExpiry", "");
// Retry login
handleLogin();
}
};

const updateFileList = async (dirHandle, setFileList, setLoading) => {
Expand Down Expand Up @@ -241,6 +251,13 @@
}
}, [imageFolderHandle]);

const joinPaths = (...paths) => {
return paths
.map(path => path.replace(/\\/g, '/')) // Normalize backslashes to forward slashes
.map(path => path.replace(/\/+$/, '')) // Remove trailing slashes
.join('/');
}

const deployAnnotationSession = async () => {
// Check if user is logged in
if (!user.email) {
Expand All @@ -265,8 +282,11 @@
const code = await fetch(`./${serviceFile}`).then(response => response.text());
await runCode(code);
// Register the service
const imagesPath = joinPaths(workerManager.mountPoint, imageFolderHandle.name);
nilsmechtel marked this conversation as resolved.
Show resolved Hide resolved
console.log("Images path:", imagesPath);
const supportedFileTypesJson = JSON.stringify(supportedFileTypes).replace(/"/g, '\\"');
const outputs = await runCode(
`await register_service("${serverUrl}", "${token}", "/mnt", "/mnt/annotations", "${supportedFileTypes}")`
`await register_service("${serverUrl}", "${token}", "${imagesPath}", "${supportedFileTypesJson}")`
);
// Find an output which contains type=service
const serviceOutput = outputs.find(output => output.type === "service");
Expand Down
Loading