Skip to content

Commit

Permalink
Merge branch 'chatbot_extension' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
nilsmechtel committed Aug 19, 2024
2 parents 76c0894 + 61266f3 commit 4beffe6
Show file tree
Hide file tree
Showing 29 changed files with 1,738 additions and 331 deletions.
35 changes: 35 additions & 0 deletions .github/workflows/docker-publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
name: Build and Publish Docker Image

on:
push:
branches:
- main # Trigger the workflow on pushes to the main branch
pull_request:
branches:
- main # Trigger the workflow on pull requests to the main branch

jobs:
build-and-push:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/[email protected]
with:
fetch-depth: 2

- name: Log in to the Container registry
uses: docker/[email protected]
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Build and push Docker image (latest tag)
uses: docker/[email protected]
with:
context: .
file: Dockerfile
push: true
tags: ghcr.io/${{ github.repository }}:latest
labels: |
org.opencontainers.image.source=${{ github.server_url }}/${{ github.repository }}
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ __pycache__/
*.egg-info/
build/
dist/
docs/
user_docs/
tests/cache
tests/generated_json_schemas
Expand Down
40 changes: 40 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Use an image with Python 3.11
FROM python:3.11-slim

# Set the working directory
WORKDIR /app/

# Create a non-root user
RUN groupadd -r bioimageio_colab && useradd -r -g bioimageio_colab bioimageio_colab

# Install necessary system packages
RUN apt-get update && apt-get install -y \
curl \
jq \
&& rm -rf /var/lib/apt/lists/*

# Upgrade pip
RUN pip install --upgrade pip

# Copy the requirements file for SAM to the docker environment
COPY ./requirements.txt /app/requirements.txt
COPY ./requirements-sam.txt /app/requirements-sam.txt

# Install the required packages for SAM
RUN pip install -r /app/requirements-sam.txt

# Copy the python script to the docker environment
COPY ./bioimageio_colab/register_sam_service.py /app/register_sam_service.py

# Change ownership of the application directory to the non-root user
RUN chown -R bioimageio_colab:bioimageio_colab /app/

# Fetch the Hypha server version and reinstall or upgrade hypha-rpc to the matching version
RUN HYPHA_VERSION=$(curl -s https://hypha.aicell.io/config.json | jq -r '.hypha_version') && \
pip install --upgrade "hypha-rpc<=$HYPHA_VERSION"

# Switch to the non-root user
USER bioimageio_colab

# Register the segmentation model as a hypha service
ENTRYPOINT ["python", "register_sam_service.py"]
File renamed without changes.
File renamed without changes.
118 changes: 118 additions & 0 deletions bioimageio_colab/create_workspace.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
import argparse
from hypha_rpc import connect_to_server, login
import asyncio


async def create_workspace_token(args):
# Get a user login token
token = await login({"server_url": args.server_url})

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

# Check if the workspace already exists
user_workspaces = await server.list_workspaces()
exists = any(
[args.workspace_name == workspace["name"] for workspace in user_workspaces]
)

# Create a workspace
if not exists or args.overwrite:
workspace = await server.create_workspace(
{
"name": args.workspace_name,
"description": args.description,
"owners": args.owners,
"allow_list": args.allow_list,
"deny_list": args.deny_list,
"visibility": "public", # public/protected
"persistent": True, # keeps the workspace alive even after a server restart
},
overwrite=args.overwrite,
)
# Check if the workspace was created
assert any(
[
args.workspace_name == workspace["name"]
for workspace in await server.list_workspaces()
]
)
print(f"Workspace created: {workspace['name']}")
else:
print(f"Workspace already exists: {args.workspace_name}")

# Connect to the workspace
server = await connect_to_server(
{
"server_url": args.server_url,
"token": token,
"workspace": args.workspace_name,
}
)

# List workspace services
services = await server.list_services()
if len(services) == 0:
print("No services in workspace")
else:
print("Services in workspace:")
for service in services:
print(f"- {service['name']}")

if __name__ == "__main__":
parser = argparse.ArgumentParser(
description="Create the BioImageIO Colab workspace."
)
parser.add_argument(
"--server_url",
default="https://hypha.aicell.io",
type=str,
help="URL of the Hypha server",
)
parser.add_argument(
"--workspace_name",
default="bioimageio-colab",
type=str,
help="Name of the workspace",
)
parser.add_argument(
"--description",
default="The BioImageIO Colab workspace for serving interactive segmentation models.",
type=str,
help="Description of the workspace",
)
parser.add_argument(
"--owners",
nargs="+",
default=[],
type=str,
help="User emails that own the workspace", # user email of workspace creator is added automatically
)
parser.add_argument(
"--allow_list",
nargs="+",
default=[],
type=str,
help="User emails allowed access to the workspace",
)
parser.add_argument(
"--deny_list",
nargs="+",
default=[],
type=str,
help="User emails denied access to the workspace",
)
parser.add_argument(
"--overwrite",
action="store_true",
default=False,
help="Overwrite the workspace if it already exists",
)

args = parser.parse_args()
asyncio.run(create_workspace_token(args))
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@
import numpy as np
import requests
import shutil
from imjoy_rpc.hypha import connect_to_server
from hypha_rpc import connect_to_server
from kaibu_utils import features_to_mask
from tifffile import imread, imwrite

from bioimageio_colab_server.hypha_data_store import HyphaDataStore
from bioimageio_colab.hypha_data_store import HyphaDataStore

logger = getLogger(__name__)
logger.setLevel("INFO")
Expand Down Expand Up @@ -84,26 +84,31 @@ def download_labels(ds, data_folder):


async def start_server(
data_url: str, path2data: str = "./data", outpath: str = "./kaibu_annotations"
path2data: str = "./data",
outpath: str = "./kaibu_annotations",
data_url: str = None,
):
"""
Start the SAM annotation server.
When multiple people open the link, they can join a common workspace as an ImJoy client
When multiple people open the link, they can join a common workspace as an hypha client
"""
# Check if the data is available
path2data = os.path.abspath(path2data)
if not os.path.exists(path2data):
# Create the path
os.makedirs(path2data)
# Download the data
save_path = os.path.join(path2data, data_url.split("/")[-1])
download_zip(data_url, save_path)
# Unzip the data
unzip_file(save_path, path2data)
# Remove the zip file
os.remove(save_path)
logger.info(f"Removed {save_path}")
if data_url is not None:
# Check if the data is available
if not os.path.exists(path2data):
# Create the path
os.makedirs(path2data)
# Download the data
save_path = os.path.join(path2data, data_url.split("/")[-1])
download_zip(data_url, save_path)
# Unzip the data
unzip_file(save_path, path2data)
# Remove the zip file
os.remove(save_path)
logger.info(f"Removed {save_path}")
else:
logger.info(f"Data already exists at {path2data}")

# Create the output paths
path2source = os.path.abspath(os.path.join(outpath, "source"))
Expand All @@ -112,7 +117,7 @@ async def start_server(
os.makedirs(path2label, exist_ok=True)

# Connect to the server link
server_url = "https://ai.imjoy.io"
server_url = "https://hypha.aicell.io"
server = await connect_to_server({"server_url": server_url})

# Upload to hypha.
Expand All @@ -127,7 +132,10 @@ async def start_server(
{
"name": "Collaborative Annotation",
"id": "bioimageio-colab-annotation",
"config": {"visibility": "public", "run_in_executor": True}, # make protected
"config": {
"visibility": "public", # TODO: make protected
"run_in_executor": True,
},
# Exposed functions:
# get a random image from the dataset
# returns the image as a numpy image
Expand All @@ -142,13 +150,12 @@ async def start_server(
}
)
annotation_sid = svc["id"]
model_sid = "oNwLbCSSNbiWrpr7h85F9f/ardFE2rx8wFB69JbbUGFfp:bioimageio-colab-model"
config_str = f'{{"server_url": "{server_url}", "annotation_service_id": "{annotation_sid}", "model_service_id": "{model_sid}", "token": "{token}"}}'
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 = (
"https://imjoy.io/lite?plugin=https://raw.githubusercontent.com/bioimage-io/bioimageio-colab/kubernetes/plugins/bioimageio-colab-annotator.imjoy.html&config="
"https://imjoy.io/lite?plugin=https://raw.githubusercontent.com/bioimage-io/bioimageio-colab/chatbot_extension/plugins/bioimageio-colab-annotator.imjoy.html&config="
+ encoded_config
)
print("-" * 80)
Expand All @@ -161,6 +168,8 @@ async def start_server(
)
print("-" * 80)

return annotator_url


if __name__ == "__main__":
import asyncio
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,8 +112,8 @@ def remove(self, obj_id: str):
return True
raise IndexError("Not found: " + obj_id)

async def test_data_store(server_url="https://ai.imjoy.io"):
from imjoy_rpc.hypha import connect_to_server, login
async def test_data_store(server_url="https://hypha.aicell.io"):
from hypha_rpc import connect_to_server, login
token = await login({"server_url": server_url})
server = await connect_to_server({"server_url": server_url, "token": token})

Expand Down
Loading

0 comments on commit 4beffe6

Please sign in to comment.