Skip to content

Commit ff4de20

Browse files
committed
docs: merge JOSS manuscript and tidy scripts
1 parent 5fd12e3 commit ff4de20

File tree

20 files changed

+354
-367
lines changed

20 files changed

+354
-367
lines changed

CITATION.cff

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
cff-version: 1.2.0
22
message: "If you use this software, please cite it as below."
3-
title: "VideoAnnotator: a toolkit for automated and manual video annotation in behavioral research"
3+
title: "VideoAnnotator: an extensible, reproducible toolkit for automated video annotation in behavioral research"
44
authors:
55
- family-names: Addyman
66
given-names: Caspar

Makefile

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# VideoAnnotator v1.2.0 - Modern Development Workflow
1+
# VideoAnnotator - Modern Development Workflow
22
# Uses uv for fast, reliable package management
33

44
PY := uv run
@@ -7,7 +7,7 @@ UV := export PATH="$$HOME/.local/bin:$$PATH" && uv
77
# Default target
88
.PHONY: help
99
help:
10-
@echo "VideoAnnotator v1.2.0 - Development Commands"
10+
@echo "VideoAnnotator - Development Commands"
1111
@echo ""
1212
@echo "Setup:"
1313
@echo " install Install dependencies with uv"
@@ -115,11 +115,11 @@ build: clean
115115
# API server commands
116116
.PHONY: server
117117
server:
118-
$(PY) python api_server.py
118+
$(PY) videoannotator server --host 0.0.0.0 --port 18011
119119

120120
.PHONY: server-dev
121121
server-dev:
122-
$(PY) uvicorn api_server:app --host 0.0.0.0 --port 18011 --reload
122+
$(PY) videoannotator server --host 0.0.0.0 --port 18011 --reload --dev
123123

124124
# PyTorch CUDA installation helper
125125
.PHONY: install-torch-cuda

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ uv run videoannotator setup-db --admin-email you@example.com --admin-username yo
6767

6868
```bash
6969
# Start the API server
70-
uv run python api_server.py
70+
uv run videoannotator server --host 0.0.0.0 --port 18011
7171
# Use the API key printed by `setup-db` (or the server's first-start output)
7272

7373
# Process your first video (in another terminal)
@@ -242,7 +242,7 @@ cd VideoAnnotator
242242
uv sync
243243

244244
# Start processing
245-
uv run python api_server.py
245+
uv run videoannotator server --host 0.0.0.0 --port 18011
246246
```
247247

248248
### **Method 2: Docker (Production)**

api_server.py

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,27 @@
11
#!/usr/bin/env python3
2-
"""
3-
VideoAnnotator API Server v1.2.0
2+
"""VideoAnnotator API server compatibility wrapper.
3+
4+
This repository's primary entrypoint is the `videoannotator` CLI.
45
5-
This is the standalone API server that can be run independently to serve
6-
the VideoAnnotator REST API with database persistence.
6+
This file is kept for backwards compatibility with older docs and workflows.
77
88
Usage:
9-
python api_server.py # Start server on port 18011
10-
python api_server.py --port 18011 # Start on custom port
11-
uvicorn api_server:app --reload # Development mode with auto-reload
9+
uv run python api_server.py # Start server on port 18011
10+
uv run python api_server.py --port 18011 # Start on custom port
11+
uv run uvicorn api_server:app --reload # Development mode (auto-reload)
1212
13-
# Or use the CLI (recommended):
14-
uv run python -m src.cli server # Uses same underlying API
13+
Recommended:
14+
uv run videoannotator server --host 0.0.0.0 --port 18011
1515
"""
1616

1717
import argparse
1818
import sys
1919

2020
import uvicorn
2121

22-
# Import the main API application
23-
from src.api.main import create_app
24-
from src.utils.logging_config import get_logger, setup_videoannotator_logging
22+
from videoannotator.api.main import create_app
23+
from videoannotator.utils.logging_config import get_logger, setup_videoannotator_logging
24+
from videoannotator.version import __version__
2525

2626

2727
def setup_logging(level: str = "INFO", logs_dir: str = "logs"):
@@ -37,7 +37,9 @@ def setup_logging(level: str = "INFO", logs_dir: str = "logs"):
3737

3838
def main():
3939
"""Main entry point for the API server."""
40-
parser = argparse.ArgumentParser(description="VideoAnnotator API Server v1.2.0")
40+
parser = argparse.ArgumentParser(
41+
description=f"VideoAnnotator API Server v{__version__}"
42+
)
4143
parser.add_argument(
4244
"--host", default="0.0.0.0", help="Host to bind to (default: 0.0.0.0)"
4345
)
@@ -71,7 +73,7 @@ def main():
7173

7274
# Display startup information
7375
print("=" * 60)
74-
print("[START] VideoAnnotator API Server v1.2.0")
76+
print(f"[START] VideoAnnotator API Server v{__version__}")
7577
print("=" * 60)
7678
print(f"[INFO] Server starting on http://{args.host}:{args.port}")
7779
print(f"[INFO] API Documentation: http://{args.host}:{args.port}/docs")
@@ -103,7 +105,7 @@ def main():
103105
sys.exit(1)
104106

105107

106-
# Create the FastAPI app instance for direct import
108+
# Create the FastAPI app instance for direct import.
107109
# This allows: uvicorn api_server:app --reload
108110
app = create_app()
109111

docker-compose.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ services:
8181
capabilities: [gpu]
8282
ports:
8383
- "18011:18011" # FastAPI server (host 18011)
84-
command: ["uv", "run", "python", "api_server.py", "--log-level", "info"]
84+
command: ["uv", "run", "videoannotator", "server", "--host", "0.0.0.0", "--port", "18011"]
8585
profiles:
8686
- dev-gpu
8787

docs/installation/INSTALLATION.md

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -181,8 +181,8 @@ print('All core dependencies installed!')
181181
"
182182

183183
# Test the API server
184-
uv run python api_server.py
185-
# Should start server on http://localhost:8000
184+
uv run videoannotator server --host 0.0.0.0 --port 18011
185+
# Should start server on http://localhost:18011
186186
```
187187

188188
## Development Commands
@@ -191,7 +191,7 @@ Once installed, use these commands for development:
191191

192192
```bash
193193
# Start API server
194-
uv run python api_server.py
194+
uv run videoannotator server --host 0.0.0.0 --port 18011
195195

196196
# Run linting and formatting
197197
uv run ruff check .
@@ -203,8 +203,10 @@ uv run mypy src
203203
# Run tests
204204
uv run pytest
205205

206-
# Start API server
207-
uv run python -m src.cli server
206+
# CLI help
207+
uv run videoannotator --help
208+
209+
# API server (compatibility wrapper)
208210
uv run python api_server.py
209211
```
210212

@@ -300,8 +302,8 @@ After installation:
300302
- See `docs/usage/GETTING_STARTED.md` for usage examples
301303
- Check `docs/development/` for development workflows
302304
- Review `configs/` for configuration options
303-
- Use `uv run python -m src.cli --help` to test the CLI
304-
- Use `uv run python api_server.py` to start the server
305+
- Use `uv run videoannotator --help` to test the CLI
306+
- Use `uv run videoannotator server --host 0.0.0.0 --port 18011` to start the server
305307

306308
## Performance Tips
307309

docs/installation/troubleshooting.md

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -154,10 +154,10 @@ taskkill /PID <PID> /F
154154
```bash
155155
# Set custom port
156156
export API_PORT=18012
157-
uv run python api_server.py
157+
uv run videoannotator server --host 0.0.0.0 --port 18012
158158

159159
# Or in code
160-
uvicorn api.main:app --port 18012
160+
uvicorn videoannotator.api.main:app --port 18012
161161
```
162162

163163
---
@@ -408,7 +408,7 @@ lsof custom_storage/jobs.db
408408
```bash
409409
# Stop server (Ctrl+C)
410410
# Start fresh
411-
uv run python api_server.py
411+
uv run videoannotator server --host 0.0.0.0 --port 18011
412412
```
413413

414414
**4. Use write-ahead logging** (WAL mode):
@@ -441,7 +441,7 @@ mv custom_storage/jobs_recovered.db custom_storage/jobs.db
441441
```bash
442442
rm custom_storage/jobs.db
443443
# Database will be recreated on next API start
444-
uv run python api_server.py
444+
uv run videoannotator server --host 0.0.0.0 --port 18011
445445
```
446446

447447
**Prevention**: Regular backups:
@@ -500,7 +500,7 @@ echo $AUTH_REQUIRED # Should be "true" or empty (defaults to true)
500500

501501
**2. Get your API key**:
502502
```bash
503-
uv run python get_api_key.py
503+
uv run python scripts/auth/get_api_key.py
504504
```
505505

506506
**3. Use API key in requests**:
@@ -513,8 +513,7 @@ curl -X GET "http://localhost:18011/api/v1/jobs" \
513513

514514
**4. Disable authentication for local testing** (not recommended for production):
515515
```bash
516-
export AUTH_REQUIRED=false
517-
uv run python api_server.py
516+
uv run videoannotator server --dev --host 0.0.0.0 --port 18011
518517
```
519518

520519
See [Authentication Guide](../security/authentication.md) for details.
@@ -532,7 +531,7 @@ See [Authentication Guide](../security/authentication.md) for details.
532531
**1. Verify server is running**:
533532
```bash
534533
# Check process
535-
ps aux | grep "api.main"
534+
ps aux | grep "videoannotator.api.main" | grep -v grep
536535

537536
# Check port
538537
netstat -an | grep 18011
@@ -542,7 +541,7 @@ lsof -i :18011
542541

543542
**2. Start server if not running**:
544543
```bash
545-
uv run python api_server.py
544+
uv run videoannotator server --host 0.0.0.0 --port 18011
546545
```
547546

548547
**3. Check firewall** (if accessing remotely):
@@ -561,8 +560,7 @@ netsh advfirewall firewall add rule name="VideoAnnotator" dir=in action=allow pr
561560

562561
Server should bind to `0.0.0.0` for external access:
563562
```python
564-
# In api_server.py
565-
uvicorn.run("api.main:app", host="0.0.0.0", port=18011)
563+
uvicorn.run("videoannotator.api.main:app", host="0.0.0.0", port=18011)
566564
```
567565

568566
---
@@ -725,8 +723,7 @@ grep "POST /api/v1/jobs" logs/videoannotator.log
725723
Set environment variable for verbose output:
726724

727725
```bash
728-
export LOG_LEVEL=DEBUG
729-
uv run python api_server.py
726+
uv run python api_server.py --log-level debug
730727
```
731728

732729
Or modify `src/utils/logging_config.py`:

docs/joss.md

Lines changed: 3 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -1,89 +1,7 @@
11
---
2-
title: "VideoAnnotator: an extensible, reproducible toolkit for automated and manual video annotation in behavioral research"
3-
tags:
4-
- Python
5-
- video analysis
6-
- behavioral science
7-
- reproducibility
8-
- machine learning
9-
authors:
10-
- name: Caspar Addyman
11-
orcid: https://orcid.org/0000-0003-0001-9548
12-
affiliation: 1
13-
- name: Jeremiah Ishaya
14-
affiliation: 1
15-
- name: Irene Uwerikowe
16-
affiliation: 1
17-
- name: Daniel Stamate
18-
affiliation: 2
19-
- name: Jamie Lachman
20-
affiliation: 3
21-
- name: Mark Tomlinson
22-
affiliation: 1
23-
affiliations:
24-
- name: Institute for Life Course Health Research (ILCHR), Stellenbosch University, South Africa
25-
index: 1
26-
- name: Department of Computing, Goldsmiths, University of London, United Kingdom
27-
index: 2
28-
- name: Department of Social Policy and Intervention (DISP), University of Oxford, United Kingdom
29-
index: 3
30-
date: 18 December 2025
31-
bibliography: paper.bib
2+
title: "JOSS manuscript"
323
---
334

34-
# Summary
5+
The canonical JOSS manuscript for VideoAnnotator is maintained in `paper/paper.md` with its references in `paper/paper.bib`.
356

36-
**VideoAnnotator** is an open-source Python toolkit for _automated and manual annotation of video_, designed for behavioral, social, and health research at scale. It provides:
37-
38-
- a pluggable pipeline that wraps commonly used detectors (e.g., **OpenFace 3**, **DeepFace**) for face, action‐unit, affect, gaze, speech and motion features;
39-
- a **FastAPI** service for local or server deployment;
40-
- **Docker** images for fully reproducible execution with GPU support where available;
41-
- a clear data contract for inputs/outputs (JSON/CSV/Parquet), timestamped tracks, and provenance metadata suitable for downstream modeling and review.
42-
43-
The toolkit targets researchers who need _auditable, explainable feature timelines_ (e.g., smiles, gaze‐on/off, vocal activity, proximity), while remaining domain‐agnostic for use in psychology, HCI, education research, clinical observation, sports science, or any scenario where video behaviors must be measured consistently.
44-
45-
# Statement of need
46-
47-
Across behavioral sciences, observational methods remain the gold standard for assessing rich interpersonal phenomena, but manual coding is costly, subjective, and difficult to scale. Prior work on parenting–child interaction assessment, for example, highlights both the value of holistic constructs and the practical limits of human macro-coding (training burden, reliability drift, cultural variance) when datasets grow beyond small lab cohorts. These concerns generalize to many video-based fields (therapy sessions, classroom interactions, telehealth triage), where the measurement gap—lack of scalable, standardized, and transparent coding—constrains progress.
48-
49-
**VideoAnnotator** addresses this need by (i) standardizing access to modern open models for faces, pose, and voice; (ii) emitting **timestamped micro-events** that are inspectable and auditable; and (iii) packaging the whole stack for reproducible, resource-constrained deployment (laptops, on-prem servers, or cloud GPUs). The library does _not_ prescribe a single theory of behavior; rather, it provides the _feature scaffolding_ upon which diverse constructs or downstream models can be built (e.g., sensitivity, synchrony, rapport), with outputs suitable for both qualitative review and quantitative ML.
50-
51-
# Functionality
52-
53-
- **Pipelines & plugins.** Modular wrappers for detectors (face/affect, keypoints, diarization/transcripts) chained into pipelines via declarative YAML/JSON configs. New detectors can be added with small adapter classes.
54-
- **Annotations as first-class data.** Event schemas for segments, point events, and tracks (with confidences), plus per-stage provenance and hashes for audit.
55-
- **Batch & service modes.** Run from CLI for batch processing, or as a **FastAPI** service to integrate into lab workflows, notebooks, or web apps.
56-
- **Reproducible runs.** Dockerfiles/compose recipes and pinned environments for CPU/GPU, designed to minimize “works on my machine” bugs.
57-
- **Privacy-aware processing.** Intended to run locally/on-prem; supports redaction steps (e.g., face blurring tracks) as optional pipeline stages.
58-
- **Interoperability.** Outputs align with common tabular formats and can be visualized in the companion _Video Annotation Viewer_ (separate submission).
59-
60-
# Illustrative use cases
61-
62-
- **Education/HCI:** quantifying joint attention and participation in classroom videos.
63-
- **Clinical & therapy:** triaging sessions by indicators such as engagement or agitation.
64-
- **Team interaction / sports:** timing of gaze, gestures, or proximity changes in drills.
65-
- **Developmental science:** producing objective micro-codes that later map to global constructs in a transparent, two-stage analysis.
66-
67-
# Design & architecture
68-
69-
VideoAnnotator exposes:
70-
71-
1. **`annotate()` API & CLI** to run configured pipelines over folders or manifests.
72-
2. **Detectors layer** (e.g., wrappers for OpenFace 3, DeepFace, pose/landmarks, ASR/diarization) with consistent batching and GPU utilization.
73-
3. **Event store** building timestamped tracks with confidences and per-stage provenance.
74-
4. **FastAPI service** exposing health, queue, and processing endpoints for integration.
75-
5. **Dockerized runtimes** (CPU/GPU) with pinned models and test fixtures.
76-
77-
# Quality control
78-
79-
We provide minimal smoke tests for pipeline execution, schema validation for outputs, and example configs with short clips to verify end-to-end operation. Reproducibility is validated by hashing the pipeline configuration, model versions, and container image used for each run (included in the metadata footer of outputs).
80-
81-
# Statement of limitations
82-
83-
- The toolkit depends on upstream detectors; accuracy/cultural generalizability reflect those models and recording conditions (lighting, angle, mic).
84-
- Inference on long videos may require GPU resources for real-time/near real-time performance.
85-
- Ethical deployment (consent, data governance, redaction) remains the responsibility of adopters; the library offers hooks to implement these steps.
86-
87-
# Acknowledgements
88-
89-
We thank colleagues in developmental science and global health for formative discussions on scalable, interpretable video measurement, including prior analyses of macro-coding, measurement scalability, and const
7+
This file is intentionally kept as a pointer to avoid divergence between multiple manuscript copies.

findimports.py

Lines changed: 0 additions & 33 deletions
This file was deleted.

0 commit comments

Comments
 (0)