ethoscopy 2.0__tar.gz → 2.0.3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. ethoscopy-2.0.3/.claude/settings.local.json +25 -0
  2. ethoscopy-2.0.3/.codecov.yml +26 -0
  3. ethoscopy-2.0.3/.github/workflows/ci.yml +151 -0
  4. ethoscopy-2.0.3/.github/workflows/release.yml +74 -0
  5. ethoscopy-2.0.3/.gitignore +11 -0
  6. ethoscopy-2.0.3/.pre-commit-config.yaml +62 -0
  7. ethoscopy-2.0.3/CLAUDE.md +111 -0
  8. ethoscopy-2.0.3/Docker/.claude/settings.local.json +19 -0
  9. ethoscopy-2.0.3/Docker/.env +39 -0
  10. ethoscopy-2.0.3/Docker/.env.keycloak +39 -0
  11. ethoscopy-2.0.3/Docker/Dockerfile +108 -0
  12. ethoscopy-2.0.3/Docker/README.md +85 -0
  13. ethoscopy-2.0.3/Docker/config/jupyterhub.sqlite +0 -0
  14. ethoscopy-2.0.3/Docker/config/jupyterhub_cookie_secret +1 -0
  15. ethoscopy-2.0.3/Docker/docker-compose.yml +25 -0
  16. ethoscopy-2.0.3/Docker/install_r_packages.r +75 -0
  17. ethoscopy-2.0.3/Docker/jupyterhub_data/jupyterhub-proxy.pid +1 -0
  18. ethoscopy-2.0.3/Docker/jupyterhub_data/jupyterhub.sqlite +0 -0
  19. ethoscopy-2.0.3/Docker/jupyterhub_data/jupyterhub_config.py +54 -0
  20. ethoscopy-2.0.3/Docker/jupyterhub_data/jupyterhub_cookie_secret +1 -0
  21. ethoscopy-2.0/README.md → ethoscopy-2.0.3/PKG-INFO +92 -4
  22. ethoscopy-2.0.3/QWEN.md +88 -0
  23. ethoscopy-2.0/PKG-INFO → ethoscopy-2.0.3/README.md +52 -29
  24. ethoscopy-2.0.3/TESTING.md +275 -0
  25. ethoscopy-2.0.3/_config.yml +1 -0
  26. ethoscopy-2.0.3/pyproject.toml +63 -0
  27. ethoscopy-2.0.3/pytest.ini +22 -0
  28. ethoscopy-2.0.3/run_tests.py +76 -0
  29. ethoscopy-2.0.3/setup.py +39 -0
  30. {ethoscopy-2.0 → ethoscopy-2.0.3}/src/ethoscopy/__init__.py +20 -20
  31. {ethoscopy-2.0 → ethoscopy-2.0.3}/src/ethoscopy/analyse.py +318 -242
  32. {ethoscopy-2.0 → ethoscopy-2.0.3}/src/ethoscopy/behavpy.py +31 -15
  33. {ethoscopy-2.0 → ethoscopy-2.0.3}/src/ethoscopy/behavpy_HMM_class.py +24 -14
  34. {ethoscopy-2.0 → ethoscopy-2.0.3}/src/ethoscopy/behavpy_class.py +24 -14
  35. {ethoscopy-2.0 → ethoscopy-2.0.3}/src/ethoscopy/behavpy_core.py +1152 -642
  36. {ethoscopy-2.0 → ethoscopy-2.0.3}/src/ethoscopy/behavpy_draw.py +1162 -531
  37. {ethoscopy-2.0 → ethoscopy-2.0.3}/src/ethoscopy/behavpy_periodogram_class.py +24 -14
  38. {ethoscopy-2.0 → ethoscopy-2.0.3}/src/ethoscopy/behavpy_plotly.py +2527 -1230
  39. {ethoscopy-2.0 → ethoscopy-2.0.3}/src/ethoscopy/behavpy_seaborn.py +1881 -704
  40. ethoscopy-2.0.3/src/ethoscopy/load.py +954 -0
  41. ethoscopy-2.0.3/src/ethoscopy/metadata_db.py +422 -0
  42. {ethoscopy-2.0 → ethoscopy-2.0.3}/src/ethoscopy/misc/circadian_bars.py +58 -32
  43. {ethoscopy-2.0 → ethoscopy-2.0.3}/src/ethoscopy/misc/general_functions.py +41 -33
  44. {ethoscopy-2.0 → ethoscopy-2.0.3}/src/ethoscopy/misc/get_HMM.py +9 -9
  45. {ethoscopy-2.0 → ethoscopy-2.0.3}/src/ethoscopy/misc/get_tutorials.py +15 -11
  46. {ethoscopy-2.0 → ethoscopy-2.0.3}/src/ethoscopy/misc/hmm_functions.py +43 -38
  47. {ethoscopy-2.0 → ethoscopy-2.0.3}/src/ethoscopy/misc/periodogram_functions.py +139 -99
  48. {ethoscopy-2.0 → ethoscopy-2.0.3}/src/ethoscopy/misc/validate_datetime.py +16 -11
  49. ethoscopy-2.0.3/tests/__init__.py +3 -0
  50. ethoscopy-2.0.3/tests/conftest.py +247 -0
  51. ethoscopy-2.0.3/tests/data/README.md +13 -0
  52. ethoscopy-2.0.3/tests/data/test_ethoscope.db +0 -0
  53. ethoscopy-2.0.3/tests/test_analyse.py +438 -0
  54. ethoscopy-2.0.3/tests/test_baseline_enhancements.py +452 -0
  55. ethoscopy-2.0.3/tests/test_behavpy.py +408 -0
  56. ethoscopy-2.0.3/tests/test_behavpy_core_simple.py +298 -0
  57. ethoscopy-2.0.3/tests/test_compatibility_classes.py +285 -0
  58. ethoscopy-2.0.3/tests/test_general_functions.py +135 -0
  59. ethoscopy-2.0.3/tests/test_get_tutorials.py +136 -0
  60. ethoscopy-2.0.3/tests/test_load.py +431 -0
  61. ethoscopy-2.0.3/tests/test_load_comprehensive.py +782 -0
  62. ethoscopy-2.0.3/tests/test_load_optimizations.py +635 -0
  63. ethoscopy-2.0.3/tutorial_notebook/1_Overview_tutorial.ipynb +1837 -0
  64. ethoscopy-2.0.3/tutorial_notebook/2_HMM_tutorial.ipynb +827 -0
  65. ethoscopy-2.0.3/tutorial_notebook/3_Circadian_tutorial.ipynb +1766 -0
  66. ethoscopy-2.0.3/tutorial_notebook/4_Navigating_db_tutorial.ipynb +415 -0
  67. ethoscopy-2.0.3/tutorial_notebook/5_Ethoscopy_catch22_tutorial.ipynb +1149 -0
  68. ethoscopy-2.0.3/tutorial_notebook/6_Ethoscopy_to_hctsa_tutorial.ipynb +468 -0
  69. ethoscopy-2.0.3/tutorial_notebook/ethoscope_db.csv +16801 -0
  70. ethoscopy-2.0.3/tutorial_notebook/jones_et_al_metadata.csv +8721 -0
  71. ethoscopy-2.0.3/tutorial_notebook/notebook_paper.ipynb +206 -0
  72. ethoscopy-2.0/pyproject.toml +0 -28
  73. ethoscopy-2.0/src/ethoscopy/load.py +0 -551
  74. ethoscopy-2.0/src/ethoscopy/metadata_db.py +0 -380
  75. ethoscopy-2.0/src/ethoscopy/misc/tutorial_data/4_states_F_WT.pkl +0 -0
  76. ethoscopy-2.0/src/ethoscopy/misc/tutorial_data/4_states_M_WT.pkl +0 -0
  77. ethoscopy-2.0/src/ethoscopy/misc/tutorial_data/circadian_data.pkl +0 -0
  78. ethoscopy-2.0/src/ethoscopy/misc/tutorial_data/circadian_meta.pkl +0 -0
  79. ethoscopy-2.0/src/ethoscopy/misc/tutorial_data/overview_data.pkl +0 -0
  80. ethoscopy-2.0/src/ethoscopy/misc/tutorial_data/overview_meta.pkl +0 -0
  81. {ethoscopy-2.0 → ethoscopy-2.0.3}/LICENSE +0 -0
  82. {ethoscopy-2.0 → ethoscopy-2.0.3}/src/ethoscopy/misc/__init__.py +0 -0
@@ -0,0 +1,25 @@
1
+ {
2
+ "permissions": {
3
+ "allow": [
4
+ "Bash(git add:*)",
5
+ "Bash(git commit:*)",
6
+ "Bash(python:*)",
7
+ "Bash(ls:*)",
8
+ "Bash(find:*)",
9
+ "Bash(docker exec ethoscope-lab ls -la \"/mnt/ethoscope_results/26634d78becf48628fe5d9ffc67fae04/ETHOSCOPE_266/2025-07-29_19-12-16/2025-07-29_19-12-16_26634d78becf48628fe5d9ffc67fae04.db\")",
10
+ "Bash(docker exec:*)",
11
+ "Bash(source:*)",
12
+ "Bash(git push:*)",
13
+ "Bash(mkdir:*)",
14
+ "Bash(cp:*)",
15
+ "Bash(sqlite3:*)",
16
+ "Bash(black:*)",
17
+ "Bash(grep:*)",
18
+ "Bash(pip install:*)",
19
+ "Bash(git stash pop:*)",
20
+ "Bash(git checkout:*)",
21
+ "Bash(git tag:*)"
22
+ ],
23
+ "deny": []
24
+ }
25
+ }
@@ -0,0 +1,26 @@
1
+ coverage:
2
+ range: 50..90
3
+ round: down
4
+ precision: 2
5
+
6
+ status:
7
+ project:
8
+ default:
9
+ target: auto
10
+ threshold: 1%
11
+ base: auto
12
+ patch:
13
+ default:
14
+ target: auto
15
+ threshold: 1%
16
+ base: auto
17
+
18
+ comment:
19
+ layout: "reach, diff, flags, files"
20
+ behavior: default
21
+
22
+ ignore:
23
+ - "tests/"
24
+ - "tutorial_notebook/"
25
+ - "setup.py"
26
+ - "run_tests.py"
@@ -0,0 +1,151 @@
1
+ name: CI/CD Pipeline
2
+
3
+ on:
4
+ push:
5
+ branches: [ main, develop ]
6
+ pull_request:
7
+ branches: [ main ]
8
+ schedule:
9
+ # Run tests daily at 6 AM UTC
10
+ - cron: '0 6 * * *'
11
+
12
+ jobs:
13
+ test:
14
+ runs-on: ubuntu-latest
15
+ strategy:
16
+ matrix:
17
+ python-version: ['3.10', '3.11', '3.12']
18
+
19
+ steps:
20
+ - uses: actions/checkout@v4
21
+
22
+ - name: Set up Python ${{ matrix.python-version }}
23
+ uses: actions/setup-python@v4
24
+ with:
25
+ python-version: ${{ matrix.python-version }}
26
+
27
+ - name: Cache pip dependencies
28
+ uses: actions/cache@v3
29
+ with:
30
+ path: ~/.cache/pip
31
+ key: ${{ runner.os }}-pip-${{ hashFiles('pyproject.toml') }}
32
+ restore-keys: |
33
+ ${{ runner.os }}-pip-
34
+
35
+ - name: Install dependencies
36
+ run: |
37
+ python -m pip install --upgrade pip
38
+ pip install -e ".[dev]"
39
+ pip install pytest-cov pytest-xdist pytest-mock
40
+
41
+ - name: Lint with ruff
42
+ run: |
43
+ pip install ruff
44
+ ruff check src/
45
+
46
+ - name: Format check with black
47
+ run: |
48
+ pip install black
49
+ black --check src/ tests/
50
+
51
+ - name: Run unit tests
52
+ run: |
53
+ python -m pytest tests/ -v --cov=ethoscopy --cov-report=xml --cov-report=term-missing -m "unit"
54
+
55
+ - name: Run integration tests
56
+ run: |
57
+ python -m pytest tests/ -v -m "integration"
58
+
59
+ - name: Upload coverage reports to Codecov
60
+ uses: codecov/codecov-action@v5
61
+ with:
62
+ token: ${{ secrets.CODECOV_TOKEN }}
63
+ slug: gilestrolab/ethoscopy
64
+
65
+ test-notebooks:
66
+ runs-on: ubuntu-latest
67
+ needs: test
68
+
69
+ steps:
70
+ - uses: actions/checkout@v4
71
+
72
+ - name: Set up Python 3.11
73
+ uses: actions/setup-python@v4
74
+ with:
75
+ python-version: '3.11'
76
+
77
+ - name: Install dependencies
78
+ run: |
79
+ python -m pip install --upgrade pip
80
+ pip install -e ".[dev]"
81
+ pip install nbval jupyter
82
+
83
+ - name: Test notebooks
84
+ run: |
85
+ pytest --nbval-lax tutorial_notebook/*.ipynb -v
86
+ continue-on-error: true # Notebooks may fail due to data dependencies
87
+
88
+ build:
89
+ runs-on: ubuntu-latest
90
+ needs: [test, test-notebooks]
91
+
92
+ steps:
93
+ - uses: actions/checkout@v4
94
+
95
+ - name: Set up Python 3.11
96
+ uses: actions/setup-python@v4
97
+ with:
98
+ python-version: '3.11'
99
+
100
+ - name: Install build dependencies
101
+ run: |
102
+ python -m pip install --upgrade pip
103
+ pip install build twine
104
+
105
+ - name: Build package
106
+ run: |
107
+ python -m build
108
+
109
+ - name: Check package
110
+ run: |
111
+ twine check dist/*
112
+
113
+ - name: Upload build artifacts
114
+ uses: actions/upload-artifact@v4
115
+ with:
116
+ name: dist-files
117
+ path: dist/
118
+
119
+ security-scan:
120
+ runs-on: ubuntu-latest
121
+
122
+ steps:
123
+ - uses: actions/checkout@v4
124
+
125
+ - name: Set up Python 3.11
126
+ uses: actions/setup-python@v4
127
+ with:
128
+ python-version: '3.11'
129
+
130
+ - name: Install dependencies
131
+ run: |
132
+ python -m pip install --upgrade pip
133
+ pip install bandit safety
134
+
135
+ - name: Run security scan with bandit
136
+ run: |
137
+ bandit -r src/ -f json -o bandit-report.json
138
+ continue-on-error: true
139
+
140
+ - name: Run safety check
141
+ run: |
142
+ safety check --json --output safety-report.json
143
+ continue-on-error: true
144
+
145
+ - name: Upload security reports
146
+ uses: actions/upload-artifact@v4
147
+ with:
148
+ name: security-reports
149
+ path: |
150
+ bandit-report.json
151
+ safety-report.json
@@ -0,0 +1,74 @@
1
+ name: Release to PyPI
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+ push:
7
+ tags:
8
+ - 'v*.*.*'
9
+
10
+ jobs:
11
+ test:
12
+ runs-on: ubuntu-latest
13
+ strategy:
14
+ matrix:
15
+ python-version: ['3.10', '3.11', '3.12']
16
+
17
+ steps:
18
+ - uses: actions/checkout@v4
19
+
20
+ - name: Set up Python ${{ matrix.python-version }}
21
+ uses: actions/setup-python@v4
22
+ with:
23
+ python-version: ${{ matrix.python-version }}
24
+
25
+ - name: Install dependencies
26
+ run: |
27
+ python -m pip install --upgrade pip
28
+ pip install -e ".[dev]"
29
+ pip install pytest-cov
30
+
31
+ - name: Run tests
32
+ run: |
33
+ python -m pytest tests/ -v --cov=ethoscopy -m "not slow"
34
+
35
+ build-and-publish:
36
+ needs: test
37
+ runs-on: ubuntu-latest
38
+
39
+ steps:
40
+ - uses: actions/checkout@v4
41
+
42
+ - name: Set up Python 3.11
43
+ uses: actions/setup-python@v4
44
+ with:
45
+ python-version: '3.11'
46
+
47
+ - name: Install build dependencies
48
+ run: |
49
+ python -m pip install --upgrade pip
50
+ pip install build twine
51
+
52
+ - name: Build package
53
+ run: |
54
+ python -m build
55
+
56
+ - name: Check package
57
+ run: |
58
+ twine check dist/*
59
+
60
+ - name: Publish to Test PyPI
61
+ if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/')
62
+ env:
63
+ TWINE_USERNAME: __token__
64
+ TWINE_PASSWORD: ${{ secrets.TEST_PYPI_API_TOKEN }}
65
+ run: |
66
+ twine upload --repository testpypi dist/*
67
+
68
+ - name: Publish to PyPI
69
+ if: github.event_name == 'release'
70
+ env:
71
+ TWINE_USERNAME: __token__
72
+ TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }}
73
+ run: |
74
+ twine upload dist/*
@@ -0,0 +1,11 @@
1
+ *.txt
2
+ *.pyc
3
+ *venv
4
+ dist/
5
+ *vscode
6
+ __pycache__/
7
+ ethoscopy.egg-info/
8
+ .gitignore
9
+ *.pkl
10
+ .python-version
11
+ tmp
@@ -0,0 +1,62 @@
1
+ repos:
2
+ # General file checks
3
+ - repo: https://github.com/pre-commit/pre-commit-hooks
4
+ rev: v5.0.0
5
+ hooks:
6
+ - id: trailing-whitespace
7
+ files: \.(py|yml|yaml|md|txt)$
8
+ - id: end-of-file-fixer
9
+ files: \.(py|yml|yaml|md|txt)$
10
+ - id: check-yaml
11
+ - id: check-toml
12
+ - id: check-merge-conflict
13
+ - id: check-added-large-files
14
+ args: ['--maxkb=1000']
15
+ - id: debug-statements
16
+ files: ^(src/|tests/).*\.py$
17
+ - id: check-ast
18
+ files: ^(src/|tests/).*\.py$
19
+
20
+ # Black - Code formatting
21
+ - repo: https://github.com/psf/black
22
+ rev: 24.10.0
23
+ hooks:
24
+ - id: black
25
+ args: [--line-length=88]
26
+ files: ^(src/|tests/).*\.py$
27
+
28
+ # Ruff - Linting and code analysis
29
+ - repo: https://github.com/astral-sh/ruff-pre-commit
30
+ rev: v0.8.4
31
+ hooks:
32
+ - id: ruff
33
+ args: [--fix, --exit-non-zero-on-fix]
34
+ files: ^src/.*\.py$
35
+ - id: ruff-format
36
+ files: ^(src/|tests/).*\.py$
37
+
38
+ # Import sorting
39
+ - repo: https://github.com/pycqa/isort
40
+ rev: 5.13.2
41
+ hooks:
42
+ - id: isort
43
+ args: [--profile, black, --line-length=88]
44
+ files: ^(src/|tests/).*\.py$
45
+
46
+ - repo: local
47
+ hooks:
48
+ - id: pytest-unit
49
+ name: pytest-unit
50
+ entry: .venv/bin/python -m pytest tests/ -m "unit" -v
51
+ language: system
52
+ pass_filenames: false
53
+ always_run: true
54
+ stages: [commit]
55
+
56
+ - id: pytest-fast
57
+ name: pytest-fast
58
+ entry: .venv/bin/python -m pytest tests/ -m "not slow" -v --tb=short
59
+ language: system
60
+ pass_filenames: false
61
+ always_run: true
62
+ stages: [push]
@@ -0,0 +1,111 @@
1
+ # CLAUDE.md
2
+
3
+ This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
+
5
+ ## Project Overview
6
+
7
+ Ethoscopy is a Python data analysis toolbox for behavioral time series data from Ethoscope (Drosophila monitoring system). It's built as a specialized pandas DataFrame subclass that maintains linked metadata and provides analysis/visualization tools for circadian rhythms, sleep patterns, and behavioral states using HMM.
8
+
9
+ ## Development Environment
10
+
11
+ ### Python Environment
12
+ - **Use Python 3.10+** (project requires >=3.10,<4.0)
13
+ - **Always use virtual environment** (`.venv` as mentioned in user's global instructions)
14
+ - **Install in development mode**: `pip install -e .`
15
+
16
+ ### Package Management
17
+ - Uses **pyproject.toml** for modern Python packaging (not setup.py for production)
18
+ - **Hatchling** as build backend
19
+ - **Rye** for dependency management (managed = true in pyproject.toml)
20
+
21
+ ### Key Dependencies
22
+ - Core: pandas >=2.2.2, numpy >=2.0.0
23
+ - Visualization: plotly >=5.22.0, seaborn >=0.13.2
24
+ - Analysis: hmmlearn >=0.3.2, astropy >=6.1, pywavelets >=1.6.0
25
+ - Dev: ipykernel for Jupyter notebook support
26
+
27
+ ## Build and Development Commands
28
+
29
+ ### Installation
30
+ ```bash
31
+ # Install in development mode
32
+ pip install -e .
33
+
34
+ # For Jupyter notebook development
35
+ pip install -e ".[dev]"
36
+ ```
37
+
38
+ ### Testing
39
+ - **No formal test suite found** - project relies on Jupyter notebooks for validation
40
+ - Use the tutorial notebooks in `tutorial_notebook/` for testing functionality
41
+ - Run notebooks: `jupyter notebook tutorial_notebook/`
42
+
43
+ ### Docker Environment
44
+ - **Docker available** for JupyterHub deployment
45
+ - Build: `JUPYTER_HUB_TAG=5.3.0 ETHOSCOPE_LAB_TAG=1.0 docker compose build`
46
+ - Run: `docker compose up -d` (from Docker/ directory)
47
+
48
+ ## Architecture and Code Structure
49
+
50
+ ### Core Architecture
51
+ - **behavpy_core**: Base DataFrame subclass with core functionality (xmv, curate, summary)
52
+ - **behavpy**: Main user-facing class for backward compatibility
53
+ - **Canvas System**: Supports both 'plotly' and 'seaborn' for visualization backends
54
+
55
+ ### Key Components
56
+ 1. **Data Loading** (`load.py`): FTP download, ethoscope database loading, metadata linking
57
+ 2. **Analysis** (`analyse.py`): Sleep annotation, velocity detection, stimulus response
58
+ 3. **Visualization**: Split between plotly (`behavpy_plotly.py`) and seaborn (`behavpy_seaborn.py`)
59
+ 4. **Specialized Classes**:
60
+ - `behavpy_HMM_class.py`: Hidden Markov Model analysis
61
+ - `behavpy_periodogram_class.py`: Circadian rhythm analysis
62
+ 5. **Utilities** (`misc/`): General functions, validation, tutorial data
63
+
64
+ ### Data Structure
65
+ - **Dual DataFrame design**: Main data + linked metadata via shared 'id' column
66
+ - **Metadata cleaning**: Automatically removes columns like 'path', 'file_name', 'file_size', 'machine_id'
67
+ - **Index requirement**: Data must have 'id' as index name
68
+
69
+ ### Import Pattern
70
+ ```python
71
+ import ethoscopy as etho
72
+ df = etho.behavpy(data, metadata, check=True, canvas='plotly', palette='Set2')
73
+ ```
74
+
75
+ ## Key Design Patterns
76
+
77
+ ### Version 2.0 Migration
78
+ - **Backward compatible** with pre-2.0 pickled data
79
+ - **Unified class structure**: All analysis under single `behavpy()` class
80
+ - **Canvas selection**: Choose between plotly/seaborn at initialization
81
+ - **New concat function**: Use `etho.concat()` instead of `behavpy_object.concat()`
82
+
83
+ ### Plotting Architecture
84
+ - **Dual backend support**: Plotly (interactive) vs Seaborn (static)
85
+ - **Built-in statistical processing**: Z-score normalization, bootstrapping for plotly
86
+ - **Seaborn backend**: Uses seaborn's internal statistics
87
+ - **Performance consideration**: Plotly can create large notebook files
88
+
89
+ ### Analysis Capabilities
90
+ - **Sleep detection**: Movement-based sleep annotation
91
+ - **Circadian analysis**: Periodograms (Lomb-Scargle, Fourier, Wavelet)
92
+ - **HMM behavioral states**: Using hmmlearn with visualization tools
93
+ - **Data curation**: Dead specimen removal, interpolation, filtering
94
+
95
+ ## Development Guidelines
96
+
97
+ ### Code Organization
98
+ - **src/ethoscopy/**: Main package code
99
+ - **tutorial_notebook/**: Jupyter notebooks for testing and examples
100
+ - **Docker/**: JupyterHub deployment configuration
101
+ - **Keep files under 500 lines** (per user's global instructions)
102
+
103
+ ### Testing Approach
104
+ - **Use Jupyter notebooks** for validation and testing
105
+ - **Tutorial notebooks serve as integration tests**
106
+ - **Always test with both canvas options** (plotly/seaborn)
107
+
108
+ ### Documentation
109
+ - **Docstrings**: Google style required for all functions
110
+ - **Tutorial notebooks**: Primary documentation method
111
+ - **README.md**: Keep updated with installation and basic usage
@@ -0,0 +1,19 @@
1
+ {
2
+ "permissions": {
3
+ "allow": [
4
+ "Bash(ls:*)",
5
+ "Bash(git checkout:*)",
6
+ "Bash(docker images:*)",
7
+ "Read(//tmp/**)",
8
+ "Bash(JUPYTER_HUB_TAG=5.3.0 ETHOSCOPE_LAB_TAG=1.1 docker compose build:*)",
9
+ "Bash(tee:*)",
10
+ "Bash(docker compose:*)",
11
+ "Bash(find:*)",
12
+ "Bash(sqlite3:*)",
13
+ "Bash(python3:*)",
14
+ "Bash(docker exec:*)",
15
+ "Bash(docker cp:*)"
16
+ ],
17
+ "deny": []
18
+ }
19
+ }
@@ -0,0 +1,39 @@
1
+ # Keycloak OAuth Configuration for JupyterHub
2
+ # To use: cp .env.keycloak .env && docker compose restart
3
+
4
+ # Image versions
5
+ JUPYTER_HUB_TAG=5.3.0
6
+ ETHOSCOPE_LAB_TAG=1.1
7
+
8
+ # Authentication
9
+ AUTHENTICATOR_CLASS=generic
10
+ DUMMY_PASSWORD=ethoscope
11
+
12
+ # User configuration
13
+ ALLOWED_USERS=amadabhushi,ggilestro,mjoyce,lguo,labguest1,labguest2,labguest3,labguest4,labguest5,labguest6,labguest7,ethoscopelab
14
+ ADMIN_USERS=ggilestro
15
+
16
+ # User/Group IDs (must match your host system)
17
+ UID=1000
18
+ GID=1000
19
+
20
+ # Keycloak OAuth Settings
21
+ OAUTH_CLIENT_ID=jupyter-lab
22
+ OAUTH_CLIENT_SECRET=pBUaqP6b8bO5IamJ7jw4lD3l5EyKJaKq
23
+ OAUTH_CALLBACK_URL=https://jupyter.lab.gilest.ro/hub/oauth_callback
24
+
25
+ # Keycloak endpoints (realm: gilestro-lab)
26
+ OAUTH_AUTHORIZE_URL=https://auth.gilest.ro/realms/gilestro-lab/protocol/openid-connect/auth
27
+ OAUTH_TOKEN_URL=https://auth.gilest.ro/realms/gilestro-lab/protocol/openid-connect/token
28
+ OAUTH_USERDATA_URL=https://auth.gilest.ro/realms/gilestro-lab/protocol/openid-connect/userinfo
29
+
30
+ # Username claim (Keycloak typically uses 'preferred_username')
31
+ OAUTH_USERNAME_CLAIM=preferred_username
32
+
33
+ # OAuth scopes
34
+ OAUTH_SCOPE=openid profile email
35
+
36
+ # Provider-specific (not used for Keycloak, but needed for env validation)
37
+ GITHUB_ORG=
38
+ GOOGLE_HOSTED_DOMAIN=
39
+ GITLAB_URL=
@@ -0,0 +1,39 @@
1
+ # Keycloak OAuth Configuration for JupyterHub
2
+ # To use: cp .env.keycloak .env && docker compose restart
3
+
4
+ # Image versions
5
+ JUPYTER_HUB_TAG=5.3.0
6
+ ETHOSCOPE_LAB_TAG=1.1
7
+
8
+ # Authentication
9
+ AUTHENTICATOR_CLASS=generic
10
+ DUMMY_PASSWORD=ethoscope
11
+
12
+ # User configuration
13
+ ALLOWED_USERS=amadabhushi,ggilestro,mjoyce,lguo,labguest1,labguest2,labguest3,labguest4,labguest5,labguest6,labguest7,ethoscopelab
14
+ ADMIN_USERS=ggilestro
15
+
16
+ # User/Group IDs (must match your host system)
17
+ UID=1000
18
+ GID=1000
19
+
20
+ # Keycloak OAuth Settings
21
+ OAUTH_CLIENT_ID=jupyter-lab
22
+ OAUTH_CLIENT_SECRET=pBUaqP6b8bO5IamJ7jw4lD3l5EyKJaKq
23
+ OAUTH_CALLBACK_URL=https://jupyter.lab.gilest.ro/hub/oauth_callback
24
+
25
+ # Keycloak endpoints (realm: gilestro-lab)
26
+ OAUTH_AUTHORIZE_URL=https://auth.gilest.ro/realms/gilestro-lab/protocol/openid-connect/auth
27
+ OAUTH_TOKEN_URL=https://auth.gilest.ro/realms/gilestro-lab/protocol/openid-connect/token
28
+ OAUTH_USERDATA_URL=https://auth.gilest.ro/realms/gilestro-lab/protocol/openid-connect/userinfo
29
+
30
+ # Username claim (Keycloak typically uses 'preferred_username')
31
+ OAUTH_USERNAME_CLAIM=preferred_username
32
+
33
+ # OAuth scopes
34
+ OAUTH_SCOPE=openid profile email
35
+
36
+ # Provider-specific (not used for Keycloak, but needed for env validation)
37
+ GITHUB_ORG=
38
+ GOOGLE_HOSTED_DOMAIN=
39
+ GITLAB_URL=
@@ -0,0 +1,108 @@
1
+ # Dockerfile for jupyter-rethomics
2
+ ARG JUPYTER_HUB_TAG=5.3.0
3
+ FROM jupyterhub/jupyterhub:${JUPYTER_HUB_TAG}
4
+
5
+ # ============================================================================
6
+ # SYSTEM DEPENDENCIES AND TOOLS
7
+ # ============================================================================
8
+
9
+ # Install system prerequisites and build tools
10
+ RUN apt-get update && \
11
+ apt-get install -y --no-install-recommends \
12
+ fonts-dejavu \
13
+ apt-utils \
14
+ nano \
15
+ jq \
16
+ git \
17
+ gfortran \
18
+ file \
19
+ gcc \
20
+ cmake \
21
+ libcurl4-openssl-dev \
22
+ libfontconfig1-dev \
23
+ libharfbuzz-dev \
24
+ libfribidi-dev \
25
+ libtiff-dev \
26
+ libxml2-dev \
27
+ libpam0g-dev \
28
+ wget \
29
+ lsb-release \
30
+ software-properties-common \
31
+ dirmngr \
32
+ jupyter && \
33
+ apt-get clean && \
34
+ rm -rf /var/lib/apt/lists/*
35
+
36
+ # ============================================================================
37
+ # R INSTALLATION AND SETUP
38
+ # ============================================================================
39
+
40
+ # Add CRAN repository for latest R version
41
+ RUN wget -qO- https://cloud.r-project.org/bin/linux/ubuntu/marutter_pubkey.asc | tee -a /etc/apt/trusted.gpg.d/cran_ubuntu_key.asc && \
42
+ add-apt-repository "deb https://cloud.r-project.org/bin/linux/ubuntu $(lsb_release -cs)-cran40/" -y
43
+
44
+ # Install R from CRAN repository
45
+ RUN apt-get update && \
46
+ apt-get install -y r-base r-base-dev && \
47
+ apt-get clean && \
48
+ rm -rf /var/lib/apt/lists/*
49
+
50
+ # Install R packages and rethomics
51
+ COPY install_r_packages.r /root/install_r_packages.r
52
+ RUN ln -s /bin/tar /bin/gtar && \
53
+ Rscript /root/install_r_packages.r
54
+
55
+ # ============================================================================
56
+ # JUPYTER INSTALLATION AND CONFIGURATION
57
+ # ============================================================================
58
+
59
+ # Install JupyterLab (version 3.6.4)
60
+ RUN pip3 install jupyterlab --ignore-installed
61
+
62
+ # To upgrade to version 4.0.2 (commented out)
63
+ # RUN pip3 install jupyterlab --upgrade
64
+
65
+ # Install Jupyter extensions (compatible with 3.x only)
66
+ RUN pip3 install jupyterlab-spreadsheet-editor
67
+
68
+ # ============================================================================
69
+ # PYTHON PACKAGES AND ETHOSCOPE SETUP
70
+ # ============================================================================
71
+
72
+ # Install Python data science packages
73
+ RUN pip3 install \
74
+ pandas \
75
+ seaborn \
76
+ bokeh \
77
+ lifelines \
78
+ opencv-python \
79
+ mysql-connector \
80
+ ethoscopy
81
+ # pycatch22
82
+
83
+ # Install Ethoscope from source
84
+ RUN git clone https://github.com/gilestrolab/ethoscope.git /opt/ethoscope && \
85
+ cd /opt/ethoscope/ && git checkout dev && \
86
+ cd /opt/ethoscope/src/ethoscope && pip install .
87
+
88
+ # ============================================================================
89
+ # USER SETUP
90
+ # ============================================================================
91
+
92
+ # Add default user ethoscopelab with password ethoscopelab
93
+ RUN useradd -m ethoscopelab && \
94
+ echo 'ethoscopelab:ethoscope' | chpasswd
95
+
96
+ # ============================================================================
97
+ # FINAL CONFIGURATION
98
+ # ============================================================================
99
+
100
+ WORKDIR /srv/jupyterhub/
101
+ # JupyterHub config will be mounted via docker-compose
102
+
103
+ EXPOSE 8000
104
+
105
+ LABEL maintainer="Giorgio Gilestro <giorgio@gilest.ro>" \
106
+ org.jupyter.service="ethoscope-lab"
107
+
108
+ CMD ["jupyterhub"]