Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 84 additions & 0 deletions .coveragerc
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
# Coverage.py configuration file
# https://coverage.readthedocs.io/en/latest/config.html

[run]
# The source code directories to measure
source = cellmap_flow

# Files to omit from coverage
omit =
*/tests/*,
*/test_*,
*/__pycache__/*,
*/.*,
*/venv/*,
*/virtualenv/*,
*/site-packages/*,
setup.py,
conftest.py,
*/migrations/*,
*/node_modules/*,

# Enable branch coverage
branch = True

# Disable parallel mode to avoid file conflicts
parallel = False

# Specify data file location
data_file = .coverage

[report]
# Regexes for lines to exclude from consideration
exclude_lines =
# Have to re-enable the standard pragma
pragma: no cover

# Don't complain about missing debug-only code:
def __repr__
if self\.debug

# Don't complain if tests don't hit defensive assertion code:
raise AssertionError
raise NotImplementedError

# Don't complain if non-runnable code isn't run:
if 0:
if __name__ == .__main__.:
if TYPE_CHECKING:

# Don't complain about abstract methods
@(abc\.)?abstractmethod

# Ignore warnings about missing files
ignore_errors = True

# Show line numbers of missing statements
show_missing = True

# Set precision for percentage display
precision = 2

# Sort by name for consistent output
sort = Name

[html]
# Directory for HTML coverage report
directory = htmlcov

# Title for HTML report
title = cellmap-flow Coverage Report

# Show contexts for each covered line
show_contexts = True

[xml]
# Output file for XML report (for CI/CD systems)
output = coverage.xml

[json]
# Output file for JSON report
output = coverage.json

# Show contexts in JSON report
show_contexts = True
122 changes: 122 additions & 0 deletions .github/workflows/test-coverage.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
name: Tests and Coverage

on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main, develop ]

jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: [3.11, 3.12]

steps:
- uses: actions/checkout@v4

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}

- name: Cache pip packages
uses: actions/cache@v3
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ hashFiles('**/pyproject.toml') }}
restore-keys: |
${{ runner.os }}-pip-

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -e ".[test]"

- name: Run tests with coverage
run: |
python -m pytest tests/ \
--cov=cellmap_flow \
--cov-report=xml \
--cov-report=term-missing \
--cov-branch \
-v

- name: Upload coverage to Codecov
uses: codecov/codecov-action@v3
with:
file: ./coverage.xml
flags: unittests
name: codecov-umbrella
fail_ci_if_error: false

coverage-report:
runs-on: ubuntu-latest
needs: test
if: github.event_name == 'pull_request'

steps:
- uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: 3.11

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -e ".[test]"
pip install coverage-badge

- name: Run coverage
run: |
python -m pytest tests/ \
--cov=cellmap_flow \
--cov-report=json \
--cov-report=html \
--cov-branch

- name: Generate coverage badge
run: |
coverage-badge -o coverage.svg

- name: Upload coverage reports as artifacts
uses: actions/upload-artifact@v4
with:
name: coverage-reports
path: |
htmlcov/
coverage.svg
coverage.json
retention-days: 30

coverage-comment:
runs-on: ubuntu-latest
needs: test
if: github.event_name == 'pull_request'

steps:
- uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: 3.11

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -e ".[test]"

- name: Run coverage
run: |
python -m pytest tests/ \
--cov=cellmap_flow \
--cov-report=json

- name: Coverage comment
uses: py-cov-action/python-coverage-comment-action@v3
with:
GITHUB_TOKEN: ${{ github.token }}
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -162,4 +162,4 @@ cython_debug/
#.idea/

# Misc
.vscode/
.vscode/
19 changes: 19 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Simple Makefile for cellmap-flow project

.PHONY: test test-cov clean install install-dev

test:
python -m pytest tests/ -v

test-cov:
python tests/coverage_utils.py

clean:
python tests/coverage_utils.py --clean
rm -rf .pytest_cache __pycache__ htmlcov

install:
pip install -e .

install-dev:
pip install -e ".[dev]"
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ Please feel free to explore and contribute, but note that there may be frequent

<p align="center">
<a href="#"><img src="https://img.shields.io/badge/Status-Under_Construction-orange.svg" alt="Under Construction" /></a>
<a href="https://github.com/janelia-cellmap/cellmap-flow/actions/workflows/test-coverage.yml"><img src="https://github.com/janelia-cellmap/cellmap-flow/workflows/Tests%20and%20Coverage/badge.svg" alt="Tests" /></a>
<a href="https://codecov.io/gh/janelia-cellmap/cellmap-flow"><img src="https://codecov.io/gh/janelia-cellmap/cellmap-flow/branch/main/graph/badge.svg" alt="Coverage Status" /></a>
</p>

<p align="center">
Expand Down Expand Up @@ -125,3 +127,5 @@ To run TensorFlow models, we suggest installing TensorFlow via conda: `conda ins
cellmap_flow_multiple --script -s /groups/cellmap/cellmap/zouinkhim/cellmap-flow/example/model_spec.py -n script_base --dacapo -r 20241204_finetune_mito_affs_task_datasplit_v3_u21_kidney_mito_default_cache_8_1 -i 700000 -n using_dacapo -d /nrs/cellmap/data/jrc_ut21-1413-003/jrc_ut21-1413-003.zarr/recon-1/em/fibsem-uint8/s0
```

See [tests/README.md](tests/README.md) for detailed information about the test structure and coverage goals.

14 changes: 3 additions & 11 deletions cellmap_flow/dashboard/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,19 +27,11 @@
import time

logger = logging.getLogger(__name__)
# Explicitly set template and static folder paths for package installation
template_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), "templates")
static_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), "static")
app = Flask(__name__, template_folder=template_dir, static_folder=static_dir)
app = Flask(__name__)
CORS(app)
NEUROGLANCER_URL = None
INFERENCE_SERVER = None
CUSTOM_CODE_FOLDER = os.path.expanduser(
os.environ.get(
"CUSTOM_CODE_FOLDER",
"~/Desktop/cellmap/cellmap-flow/example/example_norm",
)
)
CustomCodeFolder = "/Users/zouinkhim/Desktop/cellmap/cellmap-flow/example/example_norm"
Copy link

Copilot AI Jul 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This hardcoded path should not be committed to production code. It contains a specific user's home directory path that won't work for other users or deployment environments.

Suggested change
CustomCodeFolder = "/Users/zouinkhim/Desktop/cellmap/cellmap-flow/example/example_norm"
CustomCodeFolder = os.getenv("CUSTOM_CODE_FOLDER", "./example/example_norm")

Copilot uses AI. Check for mistakes.
Copy link

Copilot AI Jul 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This appears to be a hardcoded personal path that should not be committed to the repository. Consider using an environment variable or configuration file instead.

Suggested change
CustomCodeFolder = "/Users/zouinkhim/Desktop/cellmap/cellmap-flow/example/example_norm"
CustomCodeFolder = os.getenv(
"CUSTOM_CODE_FOLDER", "/path/to/default/example_norm"
)

Copilot uses AI. Check for mistakes.
Copy link

Copilot AI Jul 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hardcoded absolute path contains a username which could expose sensitive information and will not work in different environments. This should use environment variables or relative paths.

Suggested change
CustomCodeFolder = "/Users/zouinkhim/Desktop/cellmap/cellmap-flow/example/example_norm"
CustomCodeFolder = os.getenv("CUSTOM_CODE_FOLDER", "./example/example_norm")

Copilot uses AI. Check for mistakes.


@app.route("/")
Expand Down Expand Up @@ -155,7 +147,7 @@ def process():
# Save custom code to a file with date and time
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
filename = f"custom_code_{timestamp}.py"
filepath = os.path.join(CUSTOM_CODE_FOLDER, filename)
filepath = os.path.join(CustomCodeFolder, filename)

with open(filepath, "w") as file:
file.write(custom_code)
Expand Down
2 changes: 1 addition & 1 deletion cellmap_flow/utils/data.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ def _get_config(self):
config.output_channels = len(
config.channels
) # 0:all_mem,1:organelle,2:mito,3:er,4:nucleus,5:pm,6:vs,7:ld
Copy link

Copilot AI Jul 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line uses config.channels instead of the previously defined channels variable. This will cause a NameError since config.channels is defined on line 115, but the variable channels is used in the comment on line 117.

Suggested change
) # 0:all_mem,1:organelle,2:mito,3:er,4:nucleus,5:pm,6:vs,7:ld
) # config.channels: 0:all_mem,1:organelle,2:mito,3:er,4:nucleus,5:pm,6:vs,7:ld

Copilot uses AI. Check for mistakes.
config.block_shape = np.array(tuple(out_shape) + (len(channels),))
config.block_shape = np.array(tuple(out_shape) + (len(config.channels),))

return config

Expand Down
Loading
Loading