- This repository provides a Flask-based SAM adapter for WEBKNOSSOS quick select.
- The service exposes
/healthzand/predictions/sam2_hiera_b. - It supports real SAM2 inference and a heuristic fallback mode.
- The codebase is small, typed, and intentionally simple; keep changes minimal and local.
app.py: Flask entrypoints, request handling, logging, HTTP error mapping.config.py: environment-driven immutable settings.parser.py: binary protocol parsing, validation, and mask serialization.inference.py: inference orchestration, fallback behavior, normalization.model.py: lazy SAM2 model loading and predictor integration.tests/test_parser.py: unit tests for binary request parsing.Dockerfile: runtime image and production command.docker-compose.yml: standalone adapter stack.docker-compose.webknossos.yml: WEBKNOSSOS overlay wiring.
- No repo-level Cursor rules were found in
.cursor/rules/. - No
.cursorrulesfile was found. - No Copilot instructions were found at
.github/copilot-instructions.md. - If any of those files are added later, treat them as authoritative additions to this document.
- Recommended local setup from the parent directory:
python -m venv .venv. .venv/bin/activatepip install -r sam_adaper/requirements.txt- Run package-based commands from
/mnt/c/code, not from insidesam_adaper, when imports usesam_adaper.*. - GPU-backed SAM2 needs the
sam2dependency fromrequirements.txtand accessible model weights. - For smoke testing without model weights, set
SAM_ADAPTER_INFERENCE_MODE=heuristic.
- There is no separate Python build step such as
setup.py,pyproject.toml, or wheel packaging. - Main container build:
docker build -t webknossos-sam-adapter -f sam_adaper/Dockerfile sam_adaper- Standalone compose build and run:
cd /mnt/c/code/sam_adaper && docker compose up -d --build- WEBKNOSSOS overlay build and run:
cd /mnt/c/code/sam_adaper && PUBLIC_HOST=your-host.example LETSENCRYPT_EMAIL=you@example.com docker compose -f ../webknossos/tools/hosting/docker-compose.yml -f docker-compose.webknossos.yml up -d --build- Production-style local server command from the repo root:
gunicorn -w 1 -b 0.0.0.0:8080 sam_adaper.app:app --timeout 300
- Development server from
/mnt/c/code: python -m sam_adaper.app- Health check:
curl http://localhost:8080/healthz- Heuristic mode:
SAM_ADAPTER_INFERENCE_MODE=heuristic python -m sam_adaper.app- Force CPU if needed:
SAM_ADAPTER_FORCE_CPU=true python -m sam_adaper.app
- The repository currently uses the standard library
unittestframework. - Full test suite from
/mnt/c/code: python -m unittest discover -s sam_adaper/tests- Alternative explicit module invocation:
python -m unittest sam_adaper.tests.test_parser- Run a single test class:
python -m unittest sam_adaper.tests.test_parser.ParserTest- Run a single test method:
python -m unittest sam_adaper.tests.test_parser.ParserTest.test_parse_point_request- Current tests require installed dependencies such as
numpy. - In the current environment, test discovery fails until dependencies are installed.
- No linter is configured in the repository.
- No formatter configuration file is present.
- No type checker configuration file is present.
- Do not assume
ruff,flake8,black,isort,mypy, orpytestare project standards unless you add them intentionally. - If you need a lightweight validation step without changing tooling, use:
python -m compileall sam_adaper- If you introduce new tooling, update this file and keep the configuration checked into the repo.
- Prefer small unit tests for parser and normalization logic.
- Add regression tests when fixing protocol parsing or shape validation bugs.
- Keep tests deterministic and CPU-only unless GPU coverage is explicitly needed.
- For inference paths, isolate logic that can be tested without loading SAM2 weights.
- Avoid introducing tests that require external services unless they are clearly marked integration tests.
- Use
from __future__ import annotationsat the top of Python modules, matching the existing files. - Group imports in this order: standard library, third-party, local package imports.
- Separate import groups with a single blank line.
- Prefer explicit relative imports within the package, e.g.
from .parser import SamRequest. - Avoid wildcard imports.
- Import only what the module actually uses.
- Follow existing PEP 8 style with 4-space indentation.
- Keep functions and classes separated by a single blank line block consistent with the current files.
- Use trailing commas and multi-line formatting when lines become long or readability improves.
- Keep log statements readable; break argument lists across lines instead of cramming them into one line.
- Preserve the repository's simple, standard-library-friendly style over heavy abstractions.
- Add type hints on public functions, methods, and important internal helpers.
- Prefer modern built-in generics such as
tuple[int, int]anddict[str, Any]. - Use
np.ndarrayfor array return types and parameters where shape-specific aliases are unnecessary. - Use dataclasses for immutable structured data such as
Settings,SamRequest, andInferenceMetadata. - Prefer
frozen=Truedataclasses for configuration or metadata objects that should not mutate. - Use
Anysparingly and only at library boundaries where third-party objects are effectively untyped.
- Use
snake_casefor functions, methods, variables, and module names. - Use
PascalCasefor classes. - Use
UPPER_SNAKE_CASEfor module-level constants such as protocol codes and limits. - Choose names that reflect protocol semantics precisely, e.g.
shape_x,interaction_type,used_fallback. - Keep helper names descriptive rather than abbreviated.
- Represent client/request validation failures with domain-specific exceptions such as
ParserError. - Represent model initialization failures with a dedicated exception such as
ModelLoadError. - Convert known request problems into explicit HTTP responses with suitable status codes.
- Log exceptions with context before returning
500responses. - Re-raise exceptions when fallback is disabled rather than silently swallowing them.
- Avoid broad
except Exceptionunless it is guarding an outer boundary and either logs or re-raises.
- Use module-level loggers via
logging.getLogger(__name__). - Keep logs operationally useful: include interaction type, shape, backend, fallback usage, and duration.
- Log malformed requests at warning level.
- Log unexpected inference failures with stack traces via
logger.exception(...). - Avoid noisy debug logging unless it adds concrete troubleshooting value.
- Keep route handlers thin; delegate parsing and inference to dedicated modules.
- Return
flask.Responseobjects explicitly for binary and error responses. - Use
jsonify(...)for JSON health/status payloads. - Preserve the existing endpoint paths; WEBKNOSSOS depends on them.
- Do not change response MIME types casually; binary responses must remain
application/octet-stream.
- Treat the binary request protocol as strict and validate early.
- Keep
structformats explicit and centralized. - Validate payload length, dimensions, prompt bounds, and supported element classes before processing.
- Reject malformed inputs with clear error messages.
- Preserve the current image memory layout assumptions unless the protocol changes.
- When changing protocol behavior, update tests first or in the same change.
- Use NumPy vectorization where it keeps the code clear.
- Preserve the repository's axis conventions carefully; the code intentionally transposes between
(x, y, z)and(h, w)views. - Keep output masks as
np.uint8before serialization. - Validate shapes explicitly when crossing boundaries with external model outputs.
- Prefer
astype(..., copy=False)and contiguous conversion only where needed.
- Keep SAM2 loading lazy and thread-safe.
- Do not load the model at import time.
- Maintain the current lock-based initialization pattern when changing model setup.
- Keep heuristic fallback available for smoke tests and degraded operation.
- Avoid coupling testable business logic directly to GPU-only code.
- Read runtime configuration from environment variables through
Settings. - Keep defaults conservative and aligned with the current Docker and README examples.
- Use small helpers like
_get_boolfor parsing env vars consistently. - Prefer adding new settings in
config.pyrather than scatteringos.getenv(...)calls across modules.
- Keep edits small and focused; this is a compact service.
- Prefer extending existing modules over creating new layers for minor behavior changes.
- Update
README.md,AGENTS.md, and tests when behavior or commands change. - If you add linting, typing, or test tooling, document exact commands here.
- Preserve compatibility with the documented Docker and WEBKNOSSOS workflows.