Skip to content

Commit

Permalink
run script to register data providing service
Browse files Browse the repository at this point in the history
  • Loading branch information
nilsmechtel committed Aug 20, 2024
1 parent 6554778 commit 4d3bd61
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 43 deletions.
91 changes: 53 additions & 38 deletions docs/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -63,12 +63,12 @@
<script type="text/babel" data-presets="env,react">
const { useState, useEffect } = React;

const PYTHON_FILE_NAME = 'provide_images.py';
const REGISTER_SERVICE_FILE = 'services.py';

function App() {
const [serverURL, setServerURL] = useState("wss://hypha.aicell.io/ws");
const [pyodideWorker, setPyodideWorker] = useState(null);
const [code, setCode] = useState("");
const [pyodideOutput, setPyodideOutput] = useState([]);
const [user, setUser] = useState({});
const [imageFolderHandle, setImageFolderHandle] = useState(null);
const [imageList, setImageList] = useState([]);
Expand All @@ -77,7 +77,7 @@
const [isLoadingWorker, setIsLoadingWorker] = useState(true);
const [isLoadingImages, setIsLoadingImages] = useState(false);
const [isLoadingAnnotations, setIsLoadingAnnotations] = useState(false);
const [annotationURL, setAnnotationURL] = useState("");
const [annotationURL, setAnnotationURL] = useState("placeholder");
const [copyFeedback, setCopyFeedback] = useState("");
const [activeTab, setActiveTab] = useState("Local Deployment");

Expand All @@ -89,17 +89,28 @@
}).catch(error => {
console.error("Error creating Pyodide worker:", error);
});

fetch(`./${PYTHON_FILE_NAME}`)
.then(response => response.text())
.then(text => {
setCode(text);
})
.catch(error => {
console.error(`Error loading ${PYTHON_FILE_NAME}:`, error);
});
}, []);

const runCode = async (code) => {
if (pyodideWorker) {
console.log("Running code:\n-------------\n", code); // TODO: Remove this line
try {
const result = await pyodideWorker.runScript(code);
handleResult(result);
} catch (error) {
console.error("Error running code:", error);
}
} else {
console.log("Pyodide worker not ready");
}
};

const handleResult = (result) => {
const stdout = result.filter(r => r.type === 'stdout').map(r => r.content).join("");
const stderr = result.filter(r => r.type === 'stderr').map(r => r.content).join("");
setPyodideOutput([stdout, stderr].filter(Boolean));
};

const loginCallback = (context) => {
window.open(context.login_url);
}
Expand Down Expand Up @@ -160,40 +171,32 @@
}
};

const runCode = async () => {
if (pyodideWorker) {
const result = await pyodideWorker.runScript(code);
handleResult(result);
} else {
console.log("Pyodide worker not ready");
}
};

const handleResult = (result) => {
const stdout = result.filter(r => r.type === 'stdout').map(r => r.content).join("");
const stderr = result.filter(r => r.type === 'stderr').map(r => r.content).join("");
setOutput([stdout, stderr].filter(Boolean));
};
// const checkAnnotationURL = async () => {
// const intervalId = setInterval(() => {
// const url = localStorage.getItem('annotationURL');
// if (url) {
// setAnnotationURL(url);
// clearInterval(intervalId); // Stop checking once the URL is available
// }
// }, 1000);
// };

const deployAnnotationSession = async () => {
if (imageFolderHandle) {
try {
const annotationsFolder = await imageFolderHandle.getDirectoryHandle('annotations', { create: true });
setAnnotationsFolderHandle(annotationsFolder);
await updateFileList(annotationsFolder, setAnnotationsList, setIsLoadingAnnotations); // Update annotations list
await updateFileList(annotationsFolder, setAnnotationsList, setIsLoadingAnnotations);
console.log("Created annotations folder:", annotationsFolder.name);
} catch (error) {
console.error("Error creating annotations folder:", error);
}

// checkAnnotationURL(); // Start checking for Annotation URL every 1000ms

// Run code to start annotation session
try {
// await runCode();
// TODO: get annotator_url from stdout
// Placeholder for setting annotationURL
setAnnotationURL("http://example.com/annotation-session-url"); // Replace with actual URL
} catch (error) {
console.error("Error running Python code:", error);
}
const code = await fetch(`./${REGISTER_SERVICE_FILE}`).then(response => response.text());
await runCode(code);
}
};

Expand Down Expand Up @@ -229,6 +232,7 @@
user={user}
activeTab={activeTab}
onTabClick={setActiveTab}
annotationURL={annotationURL} // Just for testing, remove later on
/>
<div className="flex-1 p-4">
<h2 className="text-2xl font-bold mb-4" style={{ height: '2rem', overflow: 'hidden' }}>
Expand Down Expand Up @@ -273,9 +277,9 @@ <h2 className="text-2xl font-bold mb-4" style={{ height: '2rem', overflow: 'hidd
<div className="text-xl font-semibold mr-2">3.</div>
<button
id="share-url-button"
className={`${annotationsFolderHandle ? "bg-purple" : "bg-disabled-button"} text-white px-4 py-2 rounded-md`}
className={`${annotationURL ? "bg-purple" : "bg-disabled-button"} text-white px-4 py-2 rounded-md`}
onClick={shareAnnotationURL}
disabled={!annotationsFolderHandle}
disabled={!annotationURL}
>
{copyFeedback || "Share Annotation URL"}
</button>
Expand Down Expand Up @@ -363,7 +367,7 @@ <h2 className="text-xl font-semibold">Number of Annotations: ({annotationsList.l
);
}

function Sidebar({ onLogin, user, activeTab, onTabClick }) {
function Sidebar({ onLogin, user, activeTab, onTabClick, annotationURL }) {
return (
<div className="bg-blue w-64 text-white p-4 relative">
<h1 className="text-xl font-semibold mb-4 text-center">Navigation</h1>
Expand Down Expand Up @@ -405,6 +409,17 @@ <h1 className="text-xl font-semibold mb-4 text-center">Navigation</h1>
<a href="#" className="text-white">Browse Deployments</a>
</li>
</ul>

{annotationURL && (
// Just for testing, remove later on
<>
<div className="separator"></div>
<span className="text-white py-2 rounded-md">
Annotation URL: {annotationURL}
</span>
</>
)}

</div>
);
}
Expand Down
2 changes: 1 addition & 1 deletion docs/pyodide-worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ importScripts(`${indexURL}pyodide.js`);
self.pyodide = await loadPyodide({ indexURL })
await self.pyodide.loadPackage("micropip");
const micropip = self.pyodide.pyimport("micropip");
await micropip.install(['numpy', 'hypha-rpc', 'pyodide-http', 'imageio', 'pillow']);
await micropip.install(['numpy', 'hypha-rpc', 'pyodide-http', 'imageio', 'pillow', 'kaibu-utils==0.1.14', 'tifffile==2024.7.24']);
// NOTE: We intentionally avoid runPythonAsync here because we don't want this to pre-load extra modules like matplotlib.
self.pyodide.runPython(setupCode)
self.postMessage({loading: true}) // Inform the main thread that we finished loading.
Expand Down
24 changes: 20 additions & 4 deletions docs/provide_images.py → docs/services.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
PLUGIN_URL = "https://raw.githubusercontent.com/bioimage-io/bioimageio-colab/chatbot_extension/plugins/bioimageio-colab-annotator.imjoy.html"
PATH_TO_DATA = "/mnt/"
PATH_TO_ANNOTATIONS = os.path.join(PATH_TO_DATA, "annotations")
os.makedirs(PATH_TO_ANNOTATIONS, exist_ok=True)
os.makedirs(PATH_TO_ANNOTATIONS, exist_ok=True) # Make sure the annotations folder exists


def list_image_files():
Expand Down Expand Up @@ -63,7 +63,7 @@ def upload_image_to_s3():
raise NotImplementedError


async def register_service(callback):
async def register_service():
# Connect to the server link
server = await connect_to_server({"server_url": SERVER_URL})

Expand All @@ -89,14 +89,30 @@ async def register_service(callback):
}
)

# Create the annotator URL
annotation_sid = svc["id"]
config_str = f'{{"server_url": "{SERVER_URL}", "annotation_service_id": "{annotation_sid}", "token": "{token}"}}'
encoded_config = urllib.parse.quote(
config_str, safe="/", encoding=None, errors=None
)
annotator_url = f"https://imjoy.io/lite?plugin={PLUGIN_URL}&config={encoded_config}"
callback(annotator_url)
print("Annotator URL:", annotator_url)

# Option 1: Return the annotator URL to stdout
print(annotator_url)

# Option 2: Save the annotator URL to a file
with open("/mnt/annotator_url.txt", "w") as f:
f.write(annotator_url)
# Doesn't show up in mounted folder

# Option 3: Save the annotator URL to the local storage
# js.localStorage.setItem("annotator_url", annotator_url)

# Option 4: Send the annotator URL to the main thread
# js.self.postMessage({"type": "annotator_url", "value": annotator_url})

# Option 5: Send the annotator URL via hypha service
# requires the registration of a service in the main thread


# Start the service
Expand Down

0 comments on commit 4d3bd61

Please sign in to comment.