Skip to content

Commit 3a6878a

Browse files
committed
simplify setup (./start.sh only script)
1 parent c2aade3 commit 3a6878a

File tree

11 files changed

+1280
-158
lines changed

11 files changed

+1280
-158
lines changed

README.md

Lines changed: 17 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -1,96 +1,32 @@
11
# pytc-client
22

3-
## Docker installation instructions
3+
## Quickstart (uv workflow)
44

5-
```bash
6-
# Pull the image (tag 0.0.1 -- subject to change in future versions)
7-
docker pull xbalbinus/pytc-client:0.0.1
8-
# Expose ports to run the backend servers on Docker
9-
docker run -it -p 4242:4242 -p 4243:4243 -p 4244:4244 -p 6006:6006 --shm-size=8g xbalbinus/pytc-client:0.0.1
10-
```
5+
**Prerequisites**
6+
- [git](https://git-scm.com/)
7+
- [uv](https://docs.astral.sh/uv/) (bundles Python and virtualenv management)
8+
- [Node.js](https://nodejs.org/) 18+ (includes npm)
119

12-
## Installation
13-
0. Create a Virtual Environment via. Conda
10+
Clone the repository and run the bootstrap script once to install everything (Python 3.11 environment, pytorch_connectomics checkout, npm packages):
1411

1512
```bash
16-
conda create -n pytc python=3.9
17-
conda activate pytc
18-
conda install pytorch torchvision cudatoolkit=11.3 -c pytorch
13+
./scripts/bootstrap.sh # macOS / Linux
14+
scripts\bootstrap.ps1 # Windows (PowerShell)
1915
```
2016

21-
Alternatively, dependencies can be installed with native Python via. the following:
17+
Launch the full stack (both FastAPI services + Electron client) with a single command:
2218

2319
```bash
24-
# Create a venv
25-
python -m venv .venv
26-
# if running in windows, replace the line above with '.\.venv\Scripts\activate.bat'
27-
source .venv/bin/activate
28-
29-
# Install dependencies
30-
pip install torch torchvision cuda-python
20+
./start.sh # macOS / Linux
21+
start.bat # Windows (CMD)
3122
```
3223

33-
In the rare event that your device does not support CUDA, you may run the following respectively:
34-
35-
```bash
36-
# If using a conda environment
37-
conda create -n pytc python=3.9
38-
conda activate pytc
39-
conda install pytorch torchvision
40-
41-
# If installing via native python
42-
python -m venv .venv
43-
source .venv/bin/activate
44-
# if running in windows, replace the line above with '.\.venv\Scripts\activate.bat'
45-
pip install torch torchvision
46-
```
47-
48-
1. Client
49-
```bash
50-
cd client
51-
npm install
52-
npm run build
53-
```
54-
55-
2. API Server:
56-
```bash
57-
cd server_api
58-
pip install -r requirements.txt
59-
```
24+
The launcher keeps the API services running while Electron is open and cleans them up when you exit.
6025

61-
3. Pytc-connectomics:
26+
## Alternate Setups
6227

63-
In root folder,
64-
```bash
65-
# The setup script will automatically download pytorch_connectomics at commit 20ccfde (version 1.0)
66-
./setup_pytorch_connectomics.sh
67-
cd pytorch_connectomics
68-
pip install --editable .
69-
```
70-
71-
Alternatively, you can run this manually:
72-
```bash
73-
git clone https://github.com/zudi-lin/pytorch_connectomics.git
74-
cd pytorch_connectomics
75-
git checkout 20ccfde
76-
pip install --editable .
77-
```
78-
79-
## Run Project
80-
### To run
81-
```bash
82-
# if running on mac or linux:
83-
./start.sh
84-
85-
# if running on windows:
86-
./start.bat
87-
88-
```
89-
In a separate terminal
90-
```bash
91-
cd client
92-
npm run electron
93-
```
28+
- **Docker**: `docker pull xbalbinus/pytc-client:0.0.1` followed by `docker run -it -p 4242:4242 -p 4243:4243 -p 4244:4244 -p 6006:6006 --shm-size=8g xbalbinus/pytc-client:0.0.1`
29+
- **Manual Python environment**: still supported—create/activate your own virtualenv, run `pip install -r server_api/requirements.txt`, execute `setup_pytorch_connectomics.sh`, and install the package with `pip install -e pytorch_connectomics`.
9430

95-
Below is a link to a video demo: showing how to set up and run the app:
96-
[video demo](https://www.loom.com/share/45c09b36bf37408fb3e5a9172e427deb?sid=2777bf8f-a705-4d47-b17a-adf882994168)
31+
## Video Demo
32+
[Video walkthrough](https://www.loom.com/share/45c09b36bf37408fb3e5a9172e427deb?sid=2777bf8f-a705-4d47-b17a-adf882994168)

pyproject.toml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
[project]
2+
name = "pytc-client"
3+
version = "0.1.0"
4+
description = "PyTC Client backend services"
5+
requires-python = ">=3.9,<3.12"
6+
dependencies = [
7+
"fastapi==0.119.0",
8+
"uvicorn==0.38.0",
9+
"python-multipart==0.0.20",
10+
"neuroglancer==2.38",
11+
"imageio==2.37.0",
12+
"tensorboard==2.20.0",
13+
"tensorboard-data-server==0.7.2",
14+
"psutil>=5.9.0",
15+
]

pytorch_connectomics

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
Subproject commit 584129712da685d40b4c26ab9ca26f40802d7536
1+
Subproject commit 20ccfde6f85868351b00d7b795d4cf89a251d6be

scripts/bootstrap.ps1

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
param()
2+
3+
$ErrorActionPreference = 'Stop'
4+
5+
$scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
6+
$rootDir = Split-Path $scriptDir
7+
$clientDir = Join-Path $rootDir 'client'
8+
$pytcDir = Join-Path $rootDir 'pytorch_connectomics'
9+
10+
function RequireCommand([string]$command, [string]$message) {
11+
if (-not (Get-Command $command -ErrorAction SilentlyContinue)) {
12+
Write-Error $message
13+
}
14+
}
15+
16+
RequireCommand 'uv' 'uv is required. Install it from https://docs.astral.sh/uv/'
17+
RequireCommand 'npm' 'npm is required to install the Electron client.'
18+
RequireCommand 'git' 'git is required to download pytorch_connectomics.'
19+
20+
Write-Host 'Synchronizing Python environment with uv...'
21+
uv sync --python 3.11 --directory $rootDir
22+
23+
Write-Host 'Preparing pytorch_connectomics dependency...'
24+
if (Test-Path (Join-Path $pytcDir '.git')) {
25+
Push-Location $pytcDir
26+
git fetch origin *> $null
27+
$currentCommit = (git rev-parse HEAD) -replace '\s', ''
28+
$targetCommit = '20ccfde'
29+
if ($currentCommit -ne $targetCommit) {
30+
git checkout $targetCommit
31+
}
32+
Pop-Location
33+
} else {
34+
git clone 'https://github.com/zudi-lin/pytorch_connectomics.git' $pytcDir
35+
Push-Location $pytcDir
36+
git checkout '20ccfde'
37+
Pop-Location
38+
}
39+
40+
Write-Host 'Installing pytorch_connectomics into the uv environment...'
41+
uv pip install --directory $rootDir --editable $pytcDir
42+
43+
Write-Host 'Installing frontend dependencies...'
44+
Push-Location $clientDir
45+
npm install
46+
Pop-Location
47+
48+
Write-Host 'Bootstrap complete. Use scripts\dev.ps1 or start.bat to launch the app.'

scripts/bootstrap.sh

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
#!/usr/bin/env bash
2+
3+
set -euo pipefail
4+
5+
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
6+
CLIENT_DIR="${ROOT_DIR}/client"
7+
8+
if ! command -v uv >/dev/null 2>&1; then
9+
echo "uv is required. Install it from https://docs.astral.sh/uv/." >&2
10+
exit 1
11+
fi
12+
13+
if ! command -v npm >/dev/null 2>&1; then
14+
echo "npm is required to install the Electron client." >&2
15+
exit 1
16+
fi
17+
18+
echo "Synchronizing Python environment with uv..."
19+
uv sync --python 3.11 --directory "${ROOT_DIR}"
20+
21+
echo "Preparing pytorch_connectomics dependency..."
22+
"${ROOT_DIR}/setup_pytorch_connectomics.sh"
23+
24+
if [ -d "${ROOT_DIR}/pytorch_connectomics" ]; then
25+
echo "Installing pytorch_connectomics into the uv environment..."
26+
uv pip install --directory "${ROOT_DIR}" --editable "${ROOT_DIR}/pytorch_connectomics"
27+
fi
28+
29+
echo "Installing frontend dependencies..."
30+
pushd "${CLIENT_DIR}" >/dev/null
31+
npm install
32+
popd >/dev/null
33+
34+
echo "Bootstrap complete. Use ./scripts/dev.sh or ./start.sh to launch the app."

scripts/dev.ps1

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
param()
2+
3+
$ErrorActionPreference = 'Stop'
4+
5+
$scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
6+
$rootDir = Split-Path $scriptDir
7+
$clientDir = Join-Path $rootDir 'client'
8+
9+
function RequireCommand([string]$command, [string]$message) {
10+
if (-not (Get-Command $command -ErrorAction SilentlyContinue)) {
11+
Write-Error $message
12+
}
13+
}
14+
15+
RequireCommand 'uv' 'uv is required. Run scripts\bootstrap.ps1 first.'
16+
RequireCommand 'npm' 'npm is required to launch the Electron client.'
17+
18+
Write-Host 'Starting API server...'
19+
$apiProcess = Start-Process uv -ArgumentList @('run','--directory', $rootDir, 'python', 'server_api/main.py') -NoNewWindow -PassThru
20+
21+
Write-Host 'Starting PyTC server...'
22+
$pyProcess = Start-Process uv -ArgumentList @('run','--directory', $rootDir, 'python', 'server_pytc/main.py') -NoNewWindow -PassThru
23+
24+
Push-Location $clientDir
25+
try {
26+
Write-Host 'Launching Electron client...'
27+
npm run electron
28+
} finally {
29+
Pop-Location
30+
if ($apiProcess -and -not $apiProcess.HasExited) {
31+
$apiProcess.Kill()
32+
}
33+
if ($pyProcess -and -not $pyProcess.HasExited) {
34+
$pyProcess.Kill()
35+
}
36+
}

scripts/dev.sh

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
#!/usr/bin/env bash
2+
3+
set -euo pipefail
4+
5+
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
6+
CLIENT_DIR="${ROOT_DIR}/client"
7+
8+
if ! command -v uv >/dev/null 2>&1; then
9+
echo "uv is required. Run scripts/bootstrap.sh first." >&2
10+
exit 1
11+
fi
12+
13+
if ! command -v npm >/dev/null 2>&1; then
14+
echo "npm is required to launch the Electron client." >&2
15+
exit 1
16+
fi
17+
18+
cleanup() {
19+
local exit_code=$?
20+
if [[ -n "${API_PID:-}" ]] && ps -p "${API_PID}" >/dev/null 2>&1; then
21+
kill "${API_PID}" >/dev/null 2>&1 || true
22+
fi
23+
if [[ -n "${PYTC_PID:-}" ]] && ps -p "${PYTC_PID}" >/dev/null 2>&1; then
24+
kill "${PYTC_PID}" >/dev/null 2>&1 || true
25+
fi
26+
wait || true
27+
exit "${exit_code}"
28+
}
29+
30+
trap cleanup EXIT INT TERM
31+
32+
echo "Starting API server..."
33+
uv run --directory "${ROOT_DIR}" python server_api/main.py &
34+
API_PID=$!
35+
36+
echo "Starting PyTC server..."
37+
uv run --directory "${ROOT_DIR}" python server_pytc/main.py &
38+
PYTC_PID=$!
39+
40+
echo "Launching Electron client..."
41+
pushd "${CLIENT_DIR}" >/dev/null
42+
npm run electron
43+
popd >/dev/null

setup_pytorch_connectomics.sh

Lines changed: 51 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,66 @@
1-
#!/bin/bash
1+
#!/usr/bin/env bash
22

33
# Setup script for pytorch_connectomics
44
# Downloads the repository at commit 20ccfde (version 1.0)
55

6-
set -e
6+
set -euo pipefail
77

88
PYTORCH_CONNECTOMICS_COMMIT="20ccfde"
99
REPO_URL="https://github.com/zudi-lin/pytorch_connectomics.git"
1010
PYTORCH_CONNECTOMICS_DIR="pytorch_connectomics"
1111

12-
echo "Setting up pytorch_connectomics at commit ${PYTORCH_CONNECTOMICS_COMMIT}"
12+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
13+
cd "${SCRIPT_DIR}"
1314

14-
# Remove existing directory if it exists
15-
if [ -d "${PYTORCH_CONNECTOMICS_DIR}" ]; then
16-
echo "Removing existing ${PYTORCH_CONNECTOMICS_DIR} directory"
17-
rm -rf "${PYTORCH_CONNECTOMICS_DIR}"
15+
if ! command -v git >/dev/null 2>&1; then
16+
echo "git is required to download pytorch_connectomics." >&2
17+
exit 1
1818
fi
1919

20-
# Clone the repository
21-
echo "Cloning pytorch_connectomics repository..."
22-
git clone "${REPO_URL}" "${PYTORCH_CONNECTOMICS_DIR}"
20+
FORCE_REFRESH=0
21+
while [[ $# -gt 0 ]]; do
22+
case "$1" in
23+
--force)
24+
FORCE_REFRESH=1
25+
shift
26+
;;
27+
*)
28+
echo "Unknown argument: $1" >&2
29+
exit 1
30+
;;
31+
esac
32+
done
2333

24-
# Change to the directory and checkout the specific commit
25-
cd "${PYTORCH_CONNECTOMICS_DIR}"
26-
echo "Checking out commit ${PYTORCH_CONNECTOMICS_COMMIT}..."
27-
git checkout "${PYTORCH_CONNECTOMICS_COMMIT}"
34+
echo "Ensuring pytorch_connectomics is available at commit ${PYTORCH_CONNECTOMICS_COMMIT}"
2835

29-
# Return to parent directory
30-
cd ..
36+
if [ -d "${PYTORCH_CONNECTOMICS_DIR}/.git" ]; then
37+
echo "Existing pytorch_connectomics checkout detected."
38+
pushd "${PYTORCH_CONNECTOMICS_DIR}" >/dev/null
3139

32-
echo "pytorch_connectomics setup complete!"
33-
echo "To install, run: cd ${PYTORCH_CONNECTOMICS_DIR} && pip install --editable ."
40+
if [ "${FORCE_REFRESH}" -eq 1 ]; then
41+
echo "Force refreshing repository..."
42+
git fetch origin
43+
git reset --hard "${PYTORCH_CONNECTOMICS_COMMIT}"
44+
else
45+
git fetch origin >/dev/null 2>&1 || true
46+
CURRENT_COMMIT="$(git rev-parse HEAD 2>/dev/null || echo "")"
47+
if [ "${CURRENT_COMMIT}" != "${PYTORCH_CONNECTOMICS_COMMIT}" ]; then
48+
echo "Checking out required commit ${PYTORCH_CONNECTOMICS_COMMIT}..."
49+
git checkout "${PYTORCH_CONNECTOMICS_COMMIT}"
50+
else
51+
echo "Repository already at required commit."
52+
fi
53+
fi
54+
55+
popd >/dev/null
56+
else
57+
echo "Cloning pytorch_connectomics repository..."
58+
git clone "${REPO_URL}" "${PYTORCH_CONNECTOMICS_DIR}"
59+
pushd "${PYTORCH_CONNECTOMICS_DIR}" >/dev/null
60+
echo "Checking out commit ${PYTORCH_CONNECTOMICS_COMMIT}..."
61+
git checkout "${PYTORCH_CONNECTOMICS_COMMIT}"
62+
popd >/dev/null
63+
fi
64+
65+
echo "pytorch_connectomics setup complete."
66+
echo "To install manually, run: pip install --editable ${PYTORCH_CONNECTOMICS_DIR}"

0 commit comments

Comments
 (0)