A newer version of the Streamlit SDK is available: 1.56.0
π Deployment Guide: Pneumonia Annotation Tool
This guide explains how to deploy the annotation app to Hugging Face Spaces (recommended, free) or Streamlit Community Cloud.
π Prerequisites
- GitHub account
- Hugging Face account (free) β huggingface.co
- Your annotation app files
π Step 1: Prepare Your Project Structure
Create a new folder with the following structure:
pneumonia-annotation-tool/
βββ app.py # Your main Streamlit app (renamed)
βββ requirements.txt # Python dependencies
βββ README.md # Project description
βββ .gitignore # Files to ignore
βββ packages.txt # System dependencies (optional)
βββ sample_images/ # Sample X-ray images for demo (optional)
βββ sample_xray.jpg
1.1 Copy and rename your app
cp annotation_app.py app.py
1.2 Create requirements.txt
streamlit>=1.28.0
streamlit-drawable-canvas>=0.9.3
opencv-python-headless>=4.8.0
numpy>=1.24.0
pandas>=2.0.0
Pillow>=10.0.0
β οΈ Use
opencv-python-headlessinstead ofopencv-pythonfor cloud deployment!
1.3 Create .gitignore
# Python
__pycache__/
*.py[cod]
*.so
.Python
env/
venv/
.venv/
# IDE
.vscode/
.idea/
# Data (don't upload patient data!)
data/Pacientes/
*.png
*.jpg
!sample_images/*.jpg
# OS
.DS_Store
Thumbs.db
1.4 Create README.md
---
title: Pneumonia Consolidation Annotation Tool
emoji: π«
colorFrom: blue
colorTo: green
sdk: streamlit
sdk_version: 1.28.0
app_file: app.py
pinned: false
---
# π« Pneumonia Consolidation Annotation Tool
A Streamlit application for radiologists to annotate pneumonia consolidations
on chest X-rays, supporting multilobar annotations with different colors.
## Features
- π¨ Draw directly on X-ray images
- π« Multiple consolidation sites with unique colors
- π Zoom & pan for detailed annotation
- πΎ Save masks and metadata
- π Inter-rater agreement (Dice, IoU)
π€ Option A: Deploy to Hugging Face Spaces (Recommended)
Step 1: Create a Hugging Face Account
Go to huggingface.co and sign up (free).
Step 2: Create a New Space
- Click your profile β New Space
- Fill in:
- Space name:
pneumonia-annotation-tool - License: Choose one (e.g., MIT)
- SDK: Select Streamlit
- Visibility: Public or Private
- Space name:
- Click Create Space
Step 3: Upload Files
Option A: Via Web Interface
- Go to your Space β Files tab
- Click Add file β Upload files
- Upload:
app.py,requirements.txt,README.md
Option B: Via Git (recommended)
# Clone your Space
git clone https://huggingface.co/spaces/YOUR_USERNAME/pneumonia-annotation-tool
cd pneumonia-annotation-tool
# Copy your files
cp /path/to/annotation_app.py app.py
cp /path/to/requirements.txt .
cp /path/to/README.md .
# Add and push
git add .
git commit -m "Initial deployment"
git push
Step 4: Modify App for Cloud
Edit app.py to change the default patients path:
# Change this line in the sidebar:
patients_path = st.sidebar.text_input(
"Patients Folder Path",
value="./uploaded_images", # Changed from ../data/Pacientes
help="Upload images or specify folder path",
)
Step 5: Add Image Upload Feature
Add this code after the patients_path input to allow users to upload their own images:
# Add file uploader for cloud deployment
st.sidebar.header("π€ Upload Images")
uploaded_files = st.sidebar.file_uploader(
"Upload X-ray Images",
type=["jpg", "jpeg", "png"],
accept_multiple_files=True,
)
if uploaded_files:
upload_dir = Path("./uploaded_images/patient_upload")
upload_dir.mkdir(parents=True, exist_ok=True)
for uf in uploaded_files:
with open(upload_dir / uf.name, "wb") as f:
f.write(uf.getbuffer())
st.sidebar.success(f"β
Uploaded {len(uploaded_files)} images!")
Step 6: Wait for Build
Hugging Face will automatically build and deploy. Check the Logs tab if there are errors.
π Your app will be live at: https://huggingface.co/spaces/YOUR_USERNAME/pneumonia-annotation-tool
βοΈ Option B: Deploy to Streamlit Community Cloud
Step 1: Push to GitHub
# Create a new GitHub repository
# Then push your code:
git init
git add .
git commit -m "Initial commit"
git branch -M main
git remote add origin https://github.com/YOUR_USERNAME/pneumonia-annotation-tool.git
git push -u origin main
Step 2: Deploy on Streamlit Cloud
- Go to share.streamlit.io
- Sign in with GitHub
- Click New app
- Select:
- Repository:
YOUR_USERNAME/pneumonia-annotation-tool - Branch:
main - Main file path:
app.py
- Repository:
- Click Deploy
π Your app will be live at: https://your-app-name.streamlit.app
π€ Handling Patient Images
For Privacy/HIPAA Compliance:
β οΈ NEVER upload real patient data to public cloud services!
Options for Images:
| Method | Best For |
|---|---|
| File Upload Widget | Users upload their own images at runtime |
| Private Space | Hugging Face private Spaces (requires Pro) |
| Self-hosted | Run on your own server with patient data |
| Sample Images | Include anonymized/synthetic samples for demo |
Adding Sample Images for Demo
- Create
sample_images/folder in your repo - Add anonymized or synthetic X-ray images
- Update the default path:
patients_path = st.sidebar.text_input(
"Patients Folder Path",
value="./sample_images",
)
π§ Complete Modified app.py for Cloud
Here are the key modifications needed for cloud deployment:
1. Add imports at the top:
import os
from pathlib import Path
2. Replace the patients path section with:
# ββ Sidebar: patients path βββββββββββββββββββββββββββββββββββββββββ
st.sidebar.header("π Patient Data")
# File uploader for cloud deployment
st.sidebar.subheader("π€ Upload X-rays")
uploaded_files = st.sidebar.file_uploader(
"Upload chest X-ray images",
type=["jpg", "jpeg", "png"],
accept_multiple_files=True,
help="Upload JPG/PNG chest X-ray images to annotate"
)
# Create upload directory
upload_dir = Path("./uploaded_images/uploads")
upload_dir.mkdir(parents=True, exist_ok=True)
if uploaded_files:
for uf in uploaded_files:
file_path = upload_dir / uf.name
with open(file_path, "wb") as f:
f.write(uf.getbuffer())
st.sidebar.success(f"β
{len(uploaded_files)} image(s) ready!")
patients_path = st.sidebar.text_input(
"Images Folder Path",
value="./uploaded_images",
help="Folder containing images (or use uploader above)",
)
3. Update get_all_patient_images function:
def get_all_patient_images(base_path):
"""Scan folders and collect all JPG/PNG images with annotation status."""
base = Path(base_path)
patient_images = []
if not base.exists():
return patient_images
# Get all subdirectories (including 'uploads')
folders = [base] + [f for f in base.iterdir() if f.is_dir()]
for folder in folders:
img_files = sorted(
list(folder.glob("*.jpg")) +
list(folder.glob("*.JPG")) +
list(folder.glob("*.jpeg")) +
list(folder.glob("*.png"))
)
for img in img_files:
if "_mask" in img.name: # Skip mask files
continue
mask_path = img.parent / f"{img.stem}_mask.png"
meta_path = img.parent / f"{img.stem}_annotation.json"
patient_images.append({
"patient_id": folder.name,
"image_path": img,
"image_name": img.name,
"mask_path": mask_path,
"metadata_path": meta_path,
"annotated": mask_path.exists(),
})
return patient_images
π Quick Deployment Checklist
- Rename
annotation_app.pyβapp.py - Create
requirements.txtwithopencv-python-headless - Create
README.mdwith Hugging Face metadata - Add file upload widget for cloud users
- Update default paths for cloud environment
- Remove/anonymize any patient data
- Test locally with
streamlit run app.py - Push to GitHub or Hugging Face
- Verify deployment and check logs
π Troubleshooting
"No module named cv2"
β Use opencv-python-headless in requirements.txt
"Permission denied" errors
β Use relative paths (./uploaded_images) not absolute paths
App crashes on large images
β Add memory limit handling or resize images on upload
Slow startup
β Reduce dependencies, use @st.cache_data for heavy computations
π Support
- Hugging Face Docs: huggingface.co/docs/hub/spaces
- Streamlit Docs: docs.streamlit.io
- Streamlit Community: discuss.streamlit.io
Created for the Pneumonia Consolidation Annotation Tool - Hospital Alma MΓ‘ter