cellpy 2.0.0a1__tar.gz → 2.0.0a2__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.
- cellpy-2.0.0a2/.issueflows/03-solved-issues/issue375_original.md +53 -0
- cellpy-2.0.0a2/.issueflows/03-solved-issues/issue375_plan.md +123 -0
- cellpy-2.0.0a2/.issueflows/03-solved-issues/issue375_status.md +17 -0
- cellpy-2.0.0a2/.issueflows/04-designs-and-guides/otherpath-upath.md +19 -0
- cellpy-2.0.0a2/.issueflows/04-designs-and-guides/release-procedure.md +179 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/04-designs-and-guides/testing-and-coverage.md +11 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/HISTORY.md +8 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/PKG-INFO +3 -2
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/config/types.py +3 -0
- cellpy-2.0.0a2/cellpy/internals/__init__.py +11 -0
- cellpy-2.0.0a2/cellpy/internals/connections.py +116 -0
- cellpy-2.0.0a2/cellpy/internals/otherpath.py +469 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/__init__.py +0 -1
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/cellreader.py +5 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/filefinder.py +29 -78
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/utils/batch.py +6 -2
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/utils/batch_tools/batch_journals.py +3 -1
- cellpy-2.0.0a2/docker/sftp-test/README.md +21 -0
- cellpy-2.0.0a2/docker/sftp-test/compose.yml +23 -0
- cellpy-2.0.0a2/docker/sftp-test/data/hello.txt +1 -0
- cellpy-2.0.0a2/docker/sftp-test/data/nested/sample.txt +1 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/pyproject.toml +3 -1
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/uv.lock +35 -82
- cellpy-2.0.0a1/.issueflows/04-designs-and-guides/release-procedure.md +0 -128
- cellpy-2.0.0a1/cellpy/internals/__init__.py +0 -10
- cellpy-2.0.0a1/cellpy/internals/connections.py +0 -172
- cellpy-2.0.0a1/cellpy/internals/otherpath.py +0 -1358
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.aliases +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.cursor/commands/build.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.cursor/commands/create-original-issue-file.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.cursor/rules/cellpy-core-migration.mdc +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.cursor/rules/cellpy-workspace.mdc +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.cursor/rules/graphify.mdc +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.cursor/rules/issueflow-rules.mdc +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.cursor/rules/kiss.mdc +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.cursor/rules/this-project.mdc +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.cursor/skills/caveman/SKILL.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.cursor/skills/grill-me/SKILL.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.cursor/skills/iflow/SKILL.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.cursor/skills/iflow-archive/SKILL.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.cursor/skills/iflow-cleanup/SKILL.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.cursor/skills/iflow-close/SKILL.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.cursor/skills/iflow-comments/SKILL.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.cursor/skills/iflow-cycle/SKILL.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.cursor/skills/iflow-epic/SKILL.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.cursor/skills/iflow-fix/SKILL.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.cursor/skills/iflow-graphify/SKILL.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.cursor/skills/iflow-history-update/SKILL.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.cursor/skills/iflow-init/SKILL.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.cursor/skills/iflow-pause/SKILL.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.cursor/skills/iflow-pick/SKILL.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.cursor/skills/iflow-plan/SKILL.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.cursor/skills/iflow-start/SKILL.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.cursor/skills/iflow-status/SKILL.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.cursor/skills/iflow-version-bump/SKILL.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.cursor/skills/iflow-yolo/SKILL.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.cursor/skills/issueflow-build/SKILL.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.dockerignore +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.editorconfig +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.env_example +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.gitattributes +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.gitignore +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/00-tools/.gitkeep +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/00-tools/README.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/00-tools/migrate_prms_calls.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/00-tools/scan_hardcoded_headers.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/00-tools/scan_member_usage.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/01-current-issues/.gitkeep +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/02-partly-solved-issues/.gitkeep +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/02-partly-solved-issues/issue453_original.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/02-partly-solved-issues/issue453_plan.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/02-partly-solved-issues/issue453_status.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/02-partly-solved-issues/issue459_original.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/.gitkeep +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/2026-07-09_archived_issues.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue372_original.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue372_plan.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue372_status.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue381_original.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue381_plan.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue381_status.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue391_original.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue391_plan.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue391_status.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue407_original.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue407_plan.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue407_status.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue415_original.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue415_plan.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue415_status.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue425_original.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue425_status.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue428_original.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue428_plan.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue428_status.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue429_original.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue429_plan.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue429_status.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue430_original.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue430_plan.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue430_status.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue431_original.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue431_plan.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue431_status.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue432_original.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue432_plan.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue432_status.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue433_original.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue433_plan.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue433_status.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue434_original.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue434_plan.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue434_status.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue435_original.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue435_plan.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue435_status.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue436_original.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue436_plan.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue436_status.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue437_original.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue437_plan.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue437_status.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue438_original.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue438_plan.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue438_status.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue439_original.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue439_plan.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue439_status.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue446_original.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue446_plan.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue446_status.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue447_original.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue447_plan.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue447_status.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue449_original.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue449_plan.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue449_status.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue450_original.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue450_plan.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue450_status.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue451_original.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue451_plan.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue451_status.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue452_original.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue452_plan.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue452_status.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue454_original.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue454_plan.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue454_status.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue455_original.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue455_plan.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue455_status.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue457_original.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue457_plan.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue457_status.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue458_original.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue458_plan.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue458_status.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue465_original.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue465_plan.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue465_status.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue466_original.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue466_plan.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue466_status.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue467_original.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue476_original.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue476_plan.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue476_status.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue479_original.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue479_plan.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue479_status.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue491_original.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue491_status.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue510_original.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue510_plan.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue510_status.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/04-designs-and-guides/.gitkeep +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/04-designs-and-guides/bdf-export.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/04-designs-and-guides/build-and-versioning.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/04-designs-and-guides/cellpy-v2-architecture.excalidraw +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/04-designs-and-guides/cellpy-v2-branching.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/04-designs-and-guides/cellpy-v2-epic.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/04-designs-and-guides/cellpy-workspace-repos.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/04-designs-and-guides/cellpycell-di-restructuring.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/04-designs-and-guides/ci-tiers.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/04-designs-and-guides/filters-and-plot-filtering.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/04-designs-and-guides/this-project.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/04-designs-and-guides/v2-cellpycore-pin-gate.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/05-epics/.gitkeep +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.readthedocs.yaml +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/AGENTS.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/AUTHORS.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/CODE_OF_CONDUCT.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/CONTRIBUTING.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/DEPRECATIONS.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/LICENSE.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/README.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/_old_docs/_developers_guide/dev_cellpy_data_structure.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/_old_docs/_developers_guide/dev_cellpy_folder_structure.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/_old_docs/_developers_guide/dev_cellpy_packaging_pypi.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/_old_docs/_developers_guide/dev_cellpy_setup.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/_old_docs/_developers_guide/dev_conda_package.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/_old_docs/_developers_guide/dev_docs.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/_old_docs/_developers_guide/dev_loaders_and_instruments.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/_old_docs/_developers_guide/dev_various.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/_old_docs/_developers_guide/index.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/_old_docs/_examples_and_tutorials/basic_interactions/01_getting_started_tutorial.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/_old_docs/_examples_and_tutorials/basic_interactions/02_read_cell_data.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/_old_docs/_examples_and_tutorials/basic_interactions/03_more_about_get.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/_old_docs/_examples_and_tutorials/basic_interactions/04_other_interactions.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/_old_docs/_examples_and_tutorials/basic_interactions/05_configuring.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/_old_docs/_examples_and_tutorials/basic_interactions/06_pandas.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/_old_docs/_examples_and_tutorials/basic_interactions/07_data_mining.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/_old_docs/_examples_and_tutorials/basic_interactions/08_the_cellpy_cmd.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/_old_docs/_examples_and_tutorials/basics.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/_old_docs/_examples_and_tutorials/examples.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/_old_docs/_examples_and_tutorials/index.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/_old_docs/_examples_and_tutorials/loaders/01_arbin.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/_old_docs/_examples_and_tutorials/loaders/02_maccor.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/_old_docs/_examples_and_tutorials/loaders/03_PEC.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/_old_docs/_examples_and_tutorials/loaders/04_Neware.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/_old_docs/_examples_and_tutorials/loaders/05_biologics.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/_old_docs/_examples_and_tutorials/loaders/06_custom.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/_old_docs/_examples_and_tutorials/loaders.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/_old_docs/_examples_and_tutorials/notebooks/images/templates_jupyterlab_001.png +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/_old_docs/_examples_and_tutorials/notebooks/images/templates_jupyterlab_002.png +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/_old_docs/_examples_and_tutorials/notebooks/tutorial_get_cap.ipynb +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/_old_docs/_examples_and_tutorials/notebooks/tutorial_simple_plot.ipynb +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/_old_docs/_examples_and_tutorials/notebooks/tutorial_templates.ipynb +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/_old_docs/_examples_and_tutorials/notebooks/tutorial_xxx-checkpoint.ipynb +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/_old_docs/_examples_and_tutorials/notebooks.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/_old_docs/_examples_and_tutorials/tips_and_tricks.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/_old_docs/_examples_and_tutorials/utils/batch.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/_old_docs/_examples_and_tutorials/utils/collectors.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/_old_docs/_examples_and_tutorials/utils/custom_file_loaders.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/_old_docs/_examples_and_tutorials/utils/easyplot.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/_old_docs/_examples_and_tutorials/utils/figures/tutorials_utils_plotting_fig1.png +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/_old_docs/_examples_and_tutorials/utils/figures/tutorials_utils_plotting_fig2.png +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/_old_docs/_examples_and_tutorials/utils/ica.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/_old_docs/_examples_and_tutorials/utils/plotting.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/_old_docs/_examples_and_tutorials/utils/templates.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/_old_docs/_examples_and_tutorials/utils/tut_ocv_rlx.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/_old_docs/_examples_and_tutorials/utils.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/_old_docs/_main_description/formats.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/_old_docs/_main_description/index.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/_old_docs/_main_description/installation.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/_old_docs/_main_description/usage.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/_old_docs/index.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/benchmarks/README.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/benchmarks/__init__.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/benchmarks/baselines/v1x_ubuntu_py313.json +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/benchmarks/check_baseline.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/benchmarks/conftest.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/benchmarks/paths.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/benchmarks/test_performance.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/__init__.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/_deprecation.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/_version.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/cli.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/config/__init__.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/config/legacy.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/config/loader.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/config/migrate.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/config/models.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/config/session.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/config/sources.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/exceptions.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/exporters/__init__.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/exporters/bdf.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/exporters/tabular.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/filters/__init__.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/filters/cycles.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/filters/summary.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/libs/__init__.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/libs/apipkg/__init__.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/libs/apipkg/_alias_module.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/libs/apipkg/_importing.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/libs/apipkg/_module.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/libs/apipkg/_syncronized.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/libs/apipkg/_version.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/libs/apipkg/py.typed +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/libs/local_fastnda/LICENSE +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/libs/local_fastnda/__init__.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/libs/local_fastnda/btsda.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/libs/local_fastnda/cli.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/libs/local_fastnda/dicts.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/libs/local_fastnda/formats.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/libs/local_fastnda/main.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/libs/local_fastnda/nda.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/libs/local_fastnda/ndax.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/libs/local_fastnda/utils.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/libs/local_fastnda/version.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/log.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/logging.json +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/parameters/.cellpy_prms_default.conf +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/parameters/__init__.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/parameters/_shim.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/parameters/internal_settings.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/parameters/legacy/__init__.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/parameters/legacy/update_headers.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/parameters/prmreader.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/parameters/prms.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/capacity_curves.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/cellpy_file/__init__.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/cellpy_file/dtype.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/cellpy_file/fids.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/cellpy_file/format.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/cellpy_file/keys.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/cellpy_file/legacy_read.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/cellpy_file/meta.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/cellpy_file/meta_archive.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/cellpy_file/read.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/cellpy_file/selectors.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/cellpy_file/translate.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/cellpy_file/v9.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/cellpy_file/write.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/data_structures.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/dbreader.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/do.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/instruments/SQL Table IDs.txt +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/instruments/__init__.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/instruments/arbin_res.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/instruments/arbin_sql.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/instruments/arbin_sql_7.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/instruments/arbin_sql_config.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/instruments/arbin_sql_csv.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/instruments/arbin_sql_h5.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/instruments/arbin_sql_xlsx.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/instruments/base.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/instruments/batmo_bdf.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/instruments/biologics_mpr.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/instruments/configurations/__init__.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/instruments/configurations/batmo_bdf_bdf.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/instruments/configurations/maccor_txt_one.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/instruments/configurations/maccor_txt_three.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/instruments/configurations/maccor_txt_two.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/instruments/configurations/maccor_txt_zero.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/instruments/configurations/neware_txt_one.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/instruments/configurations/neware_txt_two.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/instruments/configurations/neware_txt_zero.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/instruments/custom.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/instruments/ext_nda_reader.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/instruments/loader_specific_modules/__init__.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/instruments/loader_specific_modules/biologic_file_format.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/instruments/local_instrument.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/instruments/maccor_txt.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/instruments/neware_nda.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/instruments/neware_txt.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/instruments/neware_xlsx.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/instruments/pec_csv.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/instruments/processors/__init__.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/instruments/processors/post_processors.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/instruments/processors/pre_processors.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/json_dbreader.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/merger.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/native_core.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/slicing.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/sql_dbreader.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/test_meta.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/utils/__init__.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/utils/batch_tools/__init__.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/utils/batch_tools/batch_analyzers.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/utils/batch_tools/batch_core.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/utils/batch_tools/batch_experiments.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/utils/batch_tools/batch_exporters.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/utils/batch_tools/batch_helpers.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/utils/batch_tools/batch_plotters.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/utils/batch_tools/batch_reporters.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/utils/batch_tools/dumpers.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/utils/batch_tools/engines.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/utils/batch_tools/sqlite_from_excel_db.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/utils/collectors.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/utils/diagnostics.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/utils/easyplot.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/utils/example_data.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/utils/helpers.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/utils/ica.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/utils/live.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/utils/ocv_rlx.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/utils/plotutils.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/utils/processor.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/utils/template_registry.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/dev/conda-recipes/README.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/dev/conda-recipes/cellpy/meta.yaml +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/dev/conda-recipes/cellpycore/meta.yaml +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/dev/regenerate_goldens.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/docker/Dockerfile.build-test +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/environment.yml +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/environment_dev.yml +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/github_actions_environment.yml +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/noxfile.py +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/paper/.github/workflows/draft-pdf.yml +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/paper/.gitignore +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/paper/Figures/Cellpy-Utils.jpg +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/paper/Figures/CellpyCell.jpg +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/paper/Figures/CellpyData.jpg +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/paper/paper.bib +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/paper/paper.md +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/scripts/build_test.sh +0 -0
- {cellpy-2.0.0a1 → cellpy-2.0.0a2}/scripts/dev_sync.sh +0 -0
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# Issue #375: Add support for remote paths for raw data and cellpy data access
|
|
2
|
+
|
|
3
|
+
Source: https://github.com/jepegit/cellpy/issues/375
|
|
4
|
+
|
|
5
|
+
## Original issue text
|
|
6
|
+
|
|
7
|
+
- Loading raw data from remote locations
|
|
8
|
+
- Searching/listing remote raw-data directories
|
|
9
|
+
- Reading and possibly writing cellpy files stored remotely
|
|
10
|
+
- handling of authentication and credentials
|
|
11
|
+
- when direct remote access is not possible: Predictable local caching / temporary copy behavior
|
|
12
|
+
|
|
13
|
+
## Questions to resolve
|
|
14
|
+
- Which remote schemes do we want to support initially?
|
|
15
|
+
- ssh://
|
|
16
|
+
- sftp://
|
|
17
|
+
- scp://
|
|
18
|
+
- others?
|
|
19
|
+
- What happens if the remote connection isn't accessible to the user? Additional permissions necessary?
|
|
20
|
+
- Should support be limited to raw data first?
|
|
21
|
+
- How should credentials be provided?
|
|
22
|
+
- environment variables
|
|
23
|
+
- SSH config / agent
|
|
24
|
+
- key file path
|
|
25
|
+
- password fallback
|
|
26
|
+
- What should the expected behavior be for:
|
|
27
|
+
- exists()
|
|
28
|
+
- is_file()
|
|
29
|
+
- glob() / rglob()
|
|
30
|
+
- copying to local temp storage
|
|
31
|
+
- saving back to remote
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
## Acceptance criteria
|
|
36
|
+
|
|
37
|
+
- A user can configure a remote raw-data directory and load supported raw files from it.
|
|
38
|
+
- Remote raw-file discovery works in a documented and tested way.
|
|
39
|
+
- Credential handling is documented and tested.
|
|
40
|
+
- Behavior for remote cellpy file loading/saving is explicitly supported or explicitly rejected with a clear error.
|
|
41
|
+
- The supported remote-path workflows are covered by tests and documented in the user docs.
|
|
42
|
+
|
|
43
|
+
Notes
|
|
44
|
+
|
|
45
|
+
This issue is about remote path support as a feature. Refactoring the internal path abstraction should be treated as a separate issue unless it is
|
|
46
|
+
strictly necessary to complete this work.
|
|
47
|
+
|
|
48
|
+
## Comments (curated summary)
|
|
49
|
+
|
|
50
|
+
- **Clarifications / constraints**:
|
|
51
|
+
- Linked to / related work: jepegit/cellpy#371
|
|
52
|
+
|
|
53
|
+
_Note: this section is an interpretive summary of the comment thread, not a verbatim dump. Source comments: 1, last comment by @jepegit on 2026-06-14._
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
# Plan: Issue #375 (+ #371) — Remote paths via `universal_pathlib`
|
|
2
|
+
|
|
3
|
+
**Status:** Accepted (2026-07-17) — ready for `/iflow-start`.
|
|
4
|
+
|
|
5
|
+
## Goal
|
|
6
|
+
|
|
7
|
+
Ship usable remote raw/cellpy path workflows (`ssh`/`sftp`/`scp`) by replacing the Fabric-heavy `OtherPath` implementation with a thin cellpy API wrapper around [`universal_pathlib.UPath`](https://github.com/fsspec/universal_pathlib) (issue [#371](https://github.com/jepegit/cellpy/issues/371)), then documenting and testing the acceptance criteria from [#375](https://github.com/jepegit/cellpy/issues/375).
|
|
8
|
+
|
|
9
|
+
This **combines #375 and #371** in one delivery: UPath is the remote backend *and* the way we get real `exists`/`is_file`/`glob`/copy semantics.
|
|
10
|
+
|
|
11
|
+
## Constraints
|
|
12
|
+
|
|
13
|
+
- **Preserve the cellpy `OtherPath` public surface** used by config, filefinder, loaders, and batch: `is_external`, `uri_prefix`, `location`, `original` / `full_path`, `raw_path`, `copy()` → local `pathlib.Path`, plus pathlib-like ops callers already use (`/`, `name`, `parent`, `glob`, `exists`, `is_file`, `is_dir`, …). Prefer delegation over rewriting call sites.
|
|
14
|
+
- **Copy-then-load stays.** Instrument loaders and HDF5 still receive a **local** `pathlib.Path` after `OtherPath.copy()` / `resolve_hdf5_path` / `copy_to_temporary`. Do not teach readers remote open.
|
|
15
|
+
- **URI / env back-compat:** `ssh://`, `sftp://`, `scp://` strings and `CELLPY_KEY_FILENAME` / `CELLPY_PASSWORD` (+ host/user where used) keep working; map into UPath/fsspec `storage_options` (Paramiko kwargs).
|
|
16
|
+
- **Architecture G7 update:** Prior note said “keep Fabric OtherPath, fsspec later” ([`cellpy2-configuration-and-parameters-plan.md`](../../../architecture-plan/cellpy2-configuration-and-parameters-plan.md) §5b). **This work supersedes that:** wrap UPath now; keep a single external→local seam so backends can still change later. Record the decision in `.issueflows/04-designs-and-guides/` during `/iflow-start` (short note + link to #375/#371).
|
|
17
|
+
- **No broad loader rewrite.** Touch other packages only where `isinstance(..., pathlib.Path)` / Fabric assumptions break.
|
|
18
|
+
- **KISS:** One wrapper module; delete Fabric path helpers once tests pass; do not add S3/GCS/etc. product support in this issue even if UPath can open them.
|
|
19
|
+
|
|
20
|
+
### Prior art
|
|
21
|
+
|
|
22
|
+
| Hit | Role | Plan |
|
|
23
|
+
| --- | --- | --- |
|
|
24
|
+
| [`cellpy/internals/otherpath.py`](../../cellpy/internals/otherpath.py) | Fabric `OtherPathNew`/`Legacy`; stub external `exists`/`is_file` | **Replace guts** with UPath wrapper; drop dual New/Legacy if possible |
|
|
25
|
+
| [#371 body sketch](https://github.com/jepegit/cellpy/issues/371) | Thin `OtherPath` → `_upath`; `copy` via `fs.get` | **Adopt** as implementation outline |
|
|
26
|
+
| [`cellpy/internals/connections.py`](../../cellpy/internals/connections.py) | `OtherPath` export, `check_connection` | Retarget probe to UPath/`exists` or thin fs ping |
|
|
27
|
+
| [`cellpy/readers/filefinder.py`](../../cellpy/readers/filefinder.py) | Remote discovery (SSH `find` / glob) | Prefer UPath `glob`/`iterdir`; remove Fabric `find` if redundant |
|
|
28
|
+
| [`…/instruments/base.py`](../../cellpy/readers/instruments/base.py) `copy_to_temporary`, [`cellpy_file/read.py`](../../cellpy/readers/cellpy_file/read.py) `resolve_hdf5_path` | External → local | Keep call shape; ensure `OtherPath.copy()` still returns local `Path` |
|
|
29
|
+
| [`cellpy_file/write.py`](../../cellpy/readers/cellpy_file/write.py) / `CellpyCell.save` | Local write | **Reject** remote save targets |
|
|
30
|
+
| Config `OtherPathField` + `CELLPY_*` env | Path coercion / secrets | Wire credentials into UPath `storage_options`; docs |
|
|
31
|
+
| [`tests/test_otherpaths.py`](../../tests/test_otherpaths.py) | Characterization + Fabric monkeypatches | **Expand first** (API contract), then retarget mocks to fsspec/UPath |
|
|
32
|
+
| `isinstance(..., pathlib.Path)` call sites (`batch_journals`, `prmreader`, `config/types`, …) | Assume Path subclass | Audit + fix — UPath wrapper likely **not** a `pathlib.Path` subclass (#371 note) |
|
|
33
|
+
| `fabric` in `pyproject.toml` | Current remote transport | **Remove** once UPath+Paramiko path is green (Paramiko already transitive / explicit) |
|
|
34
|
+
| `universal-pathlib` | Not yet a dependency | **Add** (+ ensure `paramiko` for ssh/sftp) |
|
|
35
|
+
|
|
36
|
+
## Approach
|
|
37
|
+
|
|
38
|
+
### Product decisions (recommended)
|
|
39
|
+
|
|
40
|
+
1. **Schemes in scope for “supported”:** `ssh://`, `sftp://`, and `scp://` (alias `scp` → `sftp`/`ssh` for UPath if needed). Other URI prefixes: either clear “not supported by cellpy” error **or** pass through to UPath only if zero extra deps — **default: supported set only** for documented workflows; unknown schemes raise clearly.
|
|
41
|
+
2. **Auth:** `CELLPY_KEY_FILENAME` → Paramiko `key_filename`; `CELLPY_PASSWORD` → `password`; host/user from URI and/or `CELLPY_HOST`/`CELLPY_USER`. Document SSH agent / `~/.ssh/config` as Paramiko default behavior.
|
|
42
|
+
3. **Unreachable remote:** Fail fast (no always-True stubs).
|
|
43
|
+
4. **Cellpy files:** remote **read** via temp copy; remote **save** rejected with clear error.
|
|
44
|
+
5. **`isinstance(x, pathlib.Path)`:** Prefer fixing call sites to accept `OtherPath` / `os.PathLike` / explicit conversion over pretending to subclass `pathlib.Path` (UPath’s model). Keep `isinstance(x, OtherPath)` working everywhere it already does.
|
|
45
|
+
|
|
46
|
+
### Implementation order (matches #371 guidance)
|
|
47
|
+
|
|
48
|
+
1. **Characterization tests** — lock current public `OtherPath` behavior (URI parse, properties, local ops, external `copy`/`glob` contracts, credential env errors) with mocks; note which tests encode Fabric-specific internals.
|
|
49
|
+
2. **Add deps** — `universal-pathlib` (+ pin policy consistent with project); ensure `paramiko` available for ssh/sftp.
|
|
50
|
+
3. **Rewrite `otherpath.py`** — thin wrapper around `UPath` preserving cellpy properties/methods; `_credentials_from_env()` → `storage_options`; `copy()` uses `fs.get` (or equivalent) to temp local path.
|
|
51
|
+
4. **Call-site audit** — fix `isinstance(..., Path)` / pickle / pydantic `OtherPathField` / `check_connection` / filefinder remote search to work with wrapper (minimal diffs).
|
|
52
|
+
5. **Remove Fabric path** — delete `_*_with_fabric` helpers; drop `fabric` dependency if nothing else needs it; simplify `get_otherpath_class()` (no 3.12 Legacy/New split if wrapper is version-agnostic).
|
|
53
|
+
6. **#375 productization** — remote save rejection; user docs (URI, env, rawdatadir, temp-copy model, save policy); HISTORY note (backend change + truthful `exists`/`is_file`).
|
|
54
|
+
7. **Close linkage** — PR references both #375 and #371; close #371 when merged (or mark duplicate of #375).
|
|
55
|
+
|
|
56
|
+
### Out of scope
|
|
57
|
+
|
|
58
|
+
- Product support for S3/HTTP/SMB/GCS as rawdatadir (even if UPath can open them)
|
|
59
|
+
- Remote upload / save-back
|
|
60
|
+
- Teaching instrument readers to open remote file handles
|
|
61
|
+
- Full redesign of filefinder / batch path layout
|
|
62
|
+
- Migrating Secrets into a new pydantic model beyond wiring env → `storage_options` (config plan Step 6 can refine later)
|
|
63
|
+
|
|
64
|
+
### Scope / split check
|
|
65
|
+
|
|
66
|
+
One issue-branch / one PR is the intent (user: combine with #371). Internally keep commits ordered: tests → wrapper → call sites → drop Fabric → docs. If the PR becomes unreviewable, split **docs/AC polish** only — do **not** ship Fabric hardening without UPath.
|
|
67
|
+
|
|
68
|
+
## Files to touch
|
|
69
|
+
|
|
70
|
+
| Path | Change |
|
|
71
|
+
| --- | --- |
|
|
72
|
+
| `pyproject.toml` / lock | Add `universal-pathlib`; drop `fabric` when unused; ensure `paramiko` |
|
|
73
|
+
| `cellpy/internals/otherpath.py` | UPath-backed `OtherPath`; remove Fabric implementation |
|
|
74
|
+
| `cellpy/internals/connections.py` | `check_connection` / exports |
|
|
75
|
+
| `cellpy/readers/filefinder.py` | Discovery via UPath APIs; drop SSH `find` if obsolete |
|
|
76
|
+
| `cellpy/readers/cellreader.py` and/or `cellpy_file/write.py` | Reject remote save |
|
|
77
|
+
| `cellpy/config/types.py` (and related) | Coercion / isinstance fixes |
|
|
78
|
+
| Other isinstance call sites (as found) | Accept `OtherPath` without requiring `pathlib.Path` subclass |
|
|
79
|
+
| `tests/test_otherpaths.py` (+ filefinder / cell_readers as needed) | Contract tests; fsspec/UPath mocks |
|
|
80
|
+
| `docs/source/…` | Remote path user docs |
|
|
81
|
+
| `HISTORY.rst` (or project changelog) | User-visible notes |
|
|
82
|
+
| `.issueflows/04-designs-and-guides/` | Short G7 decision: OtherPath wraps UPath |
|
|
83
|
+
|
|
84
|
+
## Test strategy
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
uv run pytest tests/test_otherpaths.py -q
|
|
88
|
+
uv run pytest tests/test_filefinder.py tests/test_cell_readers.py -q
|
|
89
|
+
uv run pytest -m essential
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
- CI: mock fsspec/UPath filesystem (or monkeypatch `OtherPath._upath` / `fs.get`) — **no live SSH**.
|
|
93
|
+
- Optional live tests remain env-gated (`CELLPY_TEST_*`).
|
|
94
|
+
- Explicit tests: URI parse; env credentials → storage_options; external `exists`/`is_file` True/False; `copy` returns local `Path`; remote save raises; unsupported scheme error.
|
|
95
|
+
|
|
96
|
+
## Open questions
|
|
97
|
+
|
|
98
|
+
Confirm or revise:
|
|
99
|
+
|
|
100
|
+
1. **Combine #371 into this branch/PR?**
|
|
101
|
+
**Recommended (per your revise):** Yes — UPath first, then #375 ACs on top.
|
|
102
|
+
|
|
103
|
+
2. **Drop `fabric` in the same PR?**
|
|
104
|
+
**Recommended:** Yes, once tests pass on UPath+Paramiko.
|
|
105
|
+
|
|
106
|
+
3. **`scp://` handling?**
|
|
107
|
+
**Recommended:** Accept as alias to `sftp`/`ssh` for UPath (document alias).
|
|
108
|
+
|
|
109
|
+
4. **Cellpy remote save?**
|
|
110
|
+
**Recommended:** Reject with clear error (unchanged).
|
|
111
|
+
|
|
112
|
+
5. **`isinstance(..., pathlib.Path)` strategy?**
|
|
113
|
+
**Recommended:** Do **not** subclass `pathlib.Path`; fix call sites / use `OtherPath` or `PathLike` (matches #371 warning).
|
|
114
|
+
|
|
115
|
+
6. **Docs?**
|
|
116
|
+
**Recommended:** User-facing remote-paths section + HISTORY + design note under `04-designs-and-guides/`.
|
|
117
|
+
|
|
118
|
+
7. **Close #371 how?**
|
|
119
|
+
**Recommended:** Same PR `Closes #375` and `Closes #371` (or “Fixes #371 as part of #375”).
|
|
120
|
+
|
|
121
|
+
---
|
|
122
|
+
|
|
123
|
+
**Branch preflight (plan time):** `375-add-support-for-remote-paths-for-raw-data-and-cellpy-data-access`; sync with `origin/master` before `/iflow-start` as needed.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Status: Issue #375 (+ #371)
|
|
2
|
+
|
|
3
|
+
- [x] Done
|
|
4
|
+
|
|
5
|
+
## What's done
|
|
6
|
+
|
|
7
|
+
- Plan accepted; UPath-backed `OtherPath` (combines #371); Fabric removed.
|
|
8
|
+
- Deps: `universal-pathlib`, `paramiko`; `fabric` dropped.
|
|
9
|
+
- Truthful remote `exists` / `is_file` / `is_dir`; `scp://` → sftp; unsupported schemes error.
|
|
10
|
+
- `check_connection` / `filefinder` on UPath; remote `CellpyCell.save` rejected.
|
|
11
|
+
- Unit/mock tests + Docker SFTP property tests (`onlylocal`).
|
|
12
|
+
- Docs: `remote_paths.md`, config link, `HISTORY.md`, G7 note `otherpath-upath.md`.
|
|
13
|
+
- Essential + otherpaths/filefinder green at close.
|
|
14
|
+
|
|
15
|
+
## Remaining work
|
|
16
|
+
|
|
17
|
+
- None (landing via PR).
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# OtherPath wraps universal_pathlib (G7)
|
|
2
|
+
|
|
3
|
+
**Decision (issues #375 / #371):** `cellpy.internals.otherpath.OtherPath` is a thin
|
|
4
|
+
compatibility wrapper around `upath.UPath` (fsspec backends). Remote raw/cellpy
|
|
5
|
+
*reads* still go through a single external → local temp copy seam; loaders never
|
|
6
|
+
speak SSH/SFTP.
|
|
7
|
+
|
|
8
|
+
**Supersedes:** architecture-plan “keep Fabric OtherPath, revisit fsspec later”
|
|
9
|
+
(configuration plan §5b, 2026-07-09). Fabric is removed once the wrapper is green.
|
|
10
|
+
|
|
11
|
+
**Supported product schemes:** `ssh://`, `sftp://`, `scp://` (`scp` aliased to
|
|
12
|
+
`sftp`). Other schemes are rejected with a clear error even if UPath could open them.
|
|
13
|
+
|
|
14
|
+
**Credentials:** `CELLPY_KEY_FILENAME` / `CELLPY_PASSWORD` (and host/user env where
|
|
15
|
+
used) map into fsspec/Paramiko `storage_options`. SSH agent / `~/.ssh/config` follow
|
|
16
|
+
Paramiko defaults.
|
|
17
|
+
|
|
18
|
+
**Not a `pathlib.Path` subclass:** call sites must accept `OtherPath` / `PathLike`
|
|
19
|
+
explicitly; do not rely on `isinstance(x, pathlib.Path)`.
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
# Release procedure — GitHub release → PyPI
|
|
2
|
+
|
|
3
|
+
**Context.** cellpy publishes to **PyPI as `cellpy`**. A published GitHub release
|
|
4
|
+
triggers `.github/workflows/release.yml`: validate tag/branch → test → build →
|
|
5
|
+
PyPI trusted publishing.
|
|
6
|
+
|
|
7
|
+
**Authoritative companions (do not contradict these):**
|
|
8
|
+
|
|
9
|
+
| Doc | Owns |
|
|
10
|
+
|-----|------|
|
|
11
|
+
| [`cellpy-v2-branching.md`](cellpy-v2-branching.md) | Branch layout after the 2026-07-16 flip |
|
|
12
|
+
| `architecture-plan/cellpy2-release-and-branching-plan.md` (sibling repo) | Support matrix, cross-repo merge order (F9), final-legacy gates |
|
|
13
|
+
| [`build-and-versioning.md`](build-and-versioning.md) | Tag-derived versioning (`uv-dynamic-versioning`) |
|
|
14
|
+
|
|
15
|
+
> **Scheme (post-v1.1):** **`master` = v2 development**; **`v1.x` = 1.x
|
|
16
|
+
> maintenance**. Old long-lived `v2` branch is retired — do not release from it.
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## The moving parts
|
|
21
|
+
|
|
22
|
+
- **Version** comes from the **git tag** via `uv-dynamic-versioning`. No
|
|
23
|
+
hand-edited `project.version`. Tag `vX.Y.Z` → PyPI `X.Y.Z`.
|
|
24
|
+
- **Cut a release** with `gh release create --target <branch>`. CI checks that
|
|
25
|
+
the tagged commit is on that branch.
|
|
26
|
+
- **`.github/workflows/release.yml`** on `release: published`:
|
|
27
|
+
- **validate** — `v1.*` on `origin/v1.x`; `v2.*` on `origin/master`; else fail
|
|
28
|
+
- **test** — `UV_NO_SOURCES=1 uv sync` → `pytest -m essential`
|
|
29
|
+
- **publish** — `uv build` → PyPI trusted publishing (`pypi` env)
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## Which branch to release from
|
|
34
|
+
|
|
35
|
+
| Tag pattern | Branch | PyPI channel |
|
|
36
|
+
|-------------|--------|--------------|
|
|
37
|
+
| `v1.x.y` / `v1.x.y.postN` | **`v1.x`** | stable |
|
|
38
|
+
| `v1.x.yaN` / `bN` / `rcN` | **`v1.x`** | pre-release (`--pre`) |
|
|
39
|
+
| `v2.0.0aN` / `bN` / `rcN` | **`master`** | pre-release only |
|
|
40
|
+
| `v2.0.0` and later `v2.x.y` | **`master`** | stable |
|
|
41
|
+
|
|
42
|
+
As of 2026-07-17: 1.x line at **`v1.1.0.post1`** on `v1.x`; v2 pre-releases from
|
|
43
|
+
`master` (e.g. **`v2.0.0a1`**).
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## Do this before any tag (hygiene)
|
|
48
|
+
|
|
49
|
+
Releases tag **whatever commit is at HEAD**. Unrelated files on that commit ship
|
|
50
|
+
with the release (and pollute `master` / `v1.x` history).
|
|
51
|
+
|
|
52
|
+
1. **Be on the release branch**, not a feature branch.
|
|
53
|
+
2. **`git status` must be empty** — no staged/unstaged changes **and no
|
|
54
|
+
untracked files**. Stray `.issueflows/01-current-issues/*` on `master` is a
|
|
55
|
+
common trap; those belong on the issue branch only.
|
|
56
|
+
3. **Never `git add .` as release prep.** If you need a pin/HISTORY commit,
|
|
57
|
+
stage those paths explicitly.
|
|
58
|
+
4. **Do not merge `master` into a feature branch** just to “get the release doc”
|
|
59
|
+
or move focus-issue files. Cherry-pick or recreate the file on the issue
|
|
60
|
+
branch instead.
|
|
61
|
+
5. Prefer a **PR into the release line** for pin/HISTORY changes; direct pushes
|
|
62
|
+
to `master` bypass required checks (repo allows admin bypass — avoid it).
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
## Cutting a release (happy path)
|
|
67
|
+
|
|
68
|
+
### A. 1.x maintenance (`v1.x`)
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
git switch v1.x && git pull --ff-only
|
|
72
|
+
|
|
73
|
+
# Only if this release needs a pin / HISTORY commit — stage those files by name
|
|
74
|
+
UV_NO_SOURCES=1 uv lock && UV_NO_SOURCES=1 uv sync
|
|
75
|
+
uv run pytest # full suite before a real 1.x ship
|
|
76
|
+
|
|
77
|
+
git status # must show a clean tree (no untracked)
|
|
78
|
+
|
|
79
|
+
gh release create v1.1.1 --target v1.x --generate-notes
|
|
80
|
+
|
|
81
|
+
gh run list --workflow release.yml --limit 1
|
|
82
|
+
gh run watch <run-id> # ID from first column; not the workflow filename
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### B. v2 pre-release or stable (`master`)
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
git switch master && git pull --ff-only
|
|
89
|
+
|
|
90
|
+
UV_NO_SOURCES=1 uv lock && UV_NO_SOURCES=1 uv sync
|
|
91
|
+
uv run pytest -m essential # full suite before v2.0.0 stable
|
|
92
|
+
|
|
93
|
+
git status # must show a clean tree (no untracked)
|
|
94
|
+
|
|
95
|
+
# Pre-release while v2 is unfinished:
|
|
96
|
+
gh release create v2.0.0a2 --target master --generate-notes
|
|
97
|
+
# Stable only when flip + gates are done:
|
|
98
|
+
# gh release create v2.0.0 --target master --generate-notes
|
|
99
|
+
|
|
100
|
+
gh run list --workflow release.yml --limit 1
|
|
101
|
+
gh run watch <run-id>
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
**Optional:** check out the tag, `uv build`, inspect `dist/` metadata.
|
|
105
|
+
|
|
106
|
+
### Failure modes
|
|
107
|
+
|
|
108
|
+
- **Validate red (wrong branch):** delete the GitHub release **and** the tag;
|
|
109
|
+
recreate with the correct `--target`. Fix the tree first if the commit was wrong.
|
|
110
|
+
- **Test job red:** fix on the release line, merge, cut a **new** tag — never reuse.
|
|
111
|
+
- **Publish red but release exists:** PyPI may lack that version; ship the next tag.
|
|
112
|
+
- **Accidental files in the tagged commit:** next patch/pre tag from a clean
|
|
113
|
+
commit; remove the stray paths on the release line via a normal PR (do not
|
|
114
|
+
rewrite published tags).
|
|
115
|
+
|
|
116
|
+
---
|
|
117
|
+
|
|
118
|
+
## Pre-release checklist (both lines)
|
|
119
|
+
|
|
120
|
+
- [ ] On the **correct branch** (`v1.x` or `master`), not a feature branch.
|
|
121
|
+
- [ ] `git status` clean — **including no untracked** issue-flow / scratch files.
|
|
122
|
+
- [ ] Exact **`cellpycore==…`** pin for the release commit (see
|
|
123
|
+
`cellpy-v2-branching.md` for per-line policy).
|
|
124
|
+
- [ ] `UV_NO_SOURCES=1 uv lock && UV_NO_SOURCES=1 uv sync`.
|
|
125
|
+
- [ ] Release build does not depend on a local `[tool.uv.sources]` path.
|
|
126
|
+
- [ ] Tests green (`-m essential` min; full suite before stable).
|
|
127
|
+
- [ ] **`HISTORY.md`** updated.
|
|
128
|
+
- [ ] Tag is **`vX.Y.Z`** (or `aN` / `bN` / `rcN` / `.postN` as appropriate).
|
|
129
|
+
|
|
130
|
+
### Extra gates — final legacy 1.x ship
|
|
131
|
+
|
|
132
|
+
Architecture plan §1 / §6.1 and
|
|
133
|
+
`architecture-plan/cellpy-v103-vs-v104a3-observations.md`: CE /
|
|
134
|
+
coulombic-difference, dropped columns, step classification must be intended
|
|
135
|
+
**and** release-noted (or fixed). User notes:
|
|
136
|
+
`architecture-plan/cellpy-v104-migration-notes.md`.
|
|
137
|
+
|
|
138
|
+
### Extra gates — `v2.0.0` stable
|
|
139
|
+
|
|
140
|
+
`cellpy-v2-branching.md` “At v2.0 release” + architecture release plan (support
|
|
141
|
+
matrix, benchmarks, dependency budget). No stable 2.x until flip criteria pass.
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
## cellpy-core coordination (F9)
|
|
146
|
+
|
|
147
|
+
**Additions:** core PR → core PyPI release → cellpy re-pin on the line → cellpy
|
|
148
|
+
PR → cellpy GitHub release.
|
|
149
|
+
|
|
150
|
+
**Removals:** cellpy migrates off first; then core deletes.
|
|
151
|
+
|
|
152
|
+
After a core release a line needs:
|
|
153
|
+
|
|
154
|
+
1. Bump `cellpycore` in that line’s `[project.dependencies]`
|
|
155
|
+
2. `UV_NO_SOURCES=1 uv lock && UV_NO_SOURCES=1 uv sync`
|
|
156
|
+
3. `uv run pytest -m essential`
|
|
157
|
+
4. Merge, then include in the next cellpy release on that line
|
|
158
|
+
|
|
159
|
+
`v1.x` stays on a conservative pin; `master` tracks newer core as v2 needs.
|
|
160
|
+
See `cellpy-core` migration guide §2.
|
|
161
|
+
|
|
162
|
+
---
|
|
163
|
+
|
|
164
|
+
## One-time GitHub setup (maintainers)
|
|
165
|
+
|
|
166
|
+
1. PyPI trusted publisher for `cellpy` → `jepegit/cellpy`, workflow `release.yml`,
|
|
167
|
+
environment `pypi`.
|
|
168
|
+
2. Optional approval gate on the `pypi` environment.
|
|
169
|
+
3. Branch protection on **`master`** and **`v1.x`** (`cellpy-v2-branching.md`).
|
|
170
|
+
|
|
171
|
+
---
|
|
172
|
+
|
|
173
|
+
## Tracking
|
|
174
|
+
|
|
175
|
+
- Workflow: `.github/workflows/release.yml`
|
|
176
|
+
- Branching: [`cellpy-v2-branching.md`](cellpy-v2-branching.md)
|
|
177
|
+
- Build/versioning: [`build-and-versioning.md`](build-and-versioning.md)
|
|
178
|
+
- Architecture: `architecture-plan/cellpy2-release-and-branching-plan.md`
|
|
179
|
+
- Epic: [#402](https://github.com/jepegit/cellpy/issues/402)
|
|
@@ -45,10 +45,21 @@ The default `addopts` in `pyproject.toml` deselects slow/local/unfinished tests:
|
|
|
45
45
|
|
|
46
46
|
### Marker policy
|
|
47
47
|
- `slowtest` - benchmarks and network/GitHub/cookiecutter pulls; deselected by default.
|
|
48
|
+
- `onlylocal` - needs local resources (Docker SFTP for `tests/test_otherpaths_sftp.py`, live SSH, etc.); deselected by default `addopts`.
|
|
48
49
|
- `skip(reason="only run locally")` - needs local resources (sftp, mdbtools, real raw data).
|
|
49
50
|
- `skip(reason="...not needed in CI/CD...")` - downloads example data; run manually when needed.
|
|
50
51
|
- `skip_on_macos` - macOS CI flakiness.
|
|
51
52
|
- `xfail` - documents deprecated / not-implemented behavior; expected to fail.
|
|
53
|
+
|
|
54
|
+
### Docker SFTP (`OtherPath`)
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
uv run pytest tests/test_otherpaths_sftp.py -m onlylocal
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Uses `docker/sftp-test/compose.yml` (`atmoz/sftp` on `127.0.0.1:2223`). The
|
|
61
|
+
session fixture starts/stops compose when the Docker daemon is up; otherwise
|
|
62
|
+
the tests skip.
|
|
52
63
|
- CI additionally `--ignore=tests/test_plotutils_summary_plot.py`; that file runs fine locally once
|
|
53
64
|
the `[all]` extras (plotly/seaborn/kaleido) are installed.
|
|
54
65
|
|
|
@@ -2,6 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
* Remote paths via `universal_pathlib` (#375, #371): `OtherPath` is now a thin
|
|
6
|
+
wrapper around `UPath` (fsspec/Paramiko) instead of Fabric. Supported schemes
|
|
7
|
+
remain `ssh://` / `sftp://` / `scp://` (scp aliased to sftp). Remote
|
|
8
|
+
`exists` / `is_file` / `is_dir` are truthful (no longer stubbed as always
|
|
9
|
+
true). Saving a cellpy file to a remote URI raises a clear error. Credentials
|
|
10
|
+
still come from `CELLPY_KEY_FILENAME` / `CELLPY_PASSWORD`. See
|
|
11
|
+
`docs/getting_started/remote_paths.md`.
|
|
12
|
+
|
|
5
13
|
* Units are per-cell now (#427): `get_cellpy_units` returns a fresh
|
|
6
14
|
`CellpyUnits` per call (optionally seeded from its argument, which used to
|
|
7
15
|
be silently ignored), so changing units on one `CellpyCell` — directly, via
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: cellpy
|
|
3
|
-
Version: 2.0.
|
|
3
|
+
Version: 2.0.0a2
|
|
4
4
|
Summary: Extract and manipulate data from battery data testers.
|
|
5
5
|
Project-URL: Homepage, https://github.com/jepegit/cellpy
|
|
6
6
|
Project-URL: Repository, https://github.com/jepegit/cellpy
|
|
@@ -20,7 +20,6 @@ Requires-Dist: click
|
|
|
20
20
|
Requires-Dist: cookiecutter
|
|
21
21
|
Requires-Dist: dateparser
|
|
22
22
|
Requires-Dist: defusedxml
|
|
23
|
-
Requires-Dist: fabric
|
|
24
23
|
Requires-Dist: ipykernel
|
|
25
24
|
Requires-Dist: isal
|
|
26
25
|
Requires-Dist: jinja2-time
|
|
@@ -28,6 +27,7 @@ Requires-Dist: matplotlib
|
|
|
28
27
|
Requires-Dist: numpy
|
|
29
28
|
Requires-Dist: openpyxl
|
|
30
29
|
Requires-Dist: pandas<4,>=3.0.3
|
|
30
|
+
Requires-Dist: paramiko>=5.0.0
|
|
31
31
|
Requires-Dist: pint
|
|
32
32
|
Requires-Dist: platformdirs>=4.10.0
|
|
33
33
|
Requires-Dist: polars
|
|
@@ -47,6 +47,7 @@ Requires-Dist: sqlalchemy>=2.0.0
|
|
|
47
47
|
Requires-Dist: tables
|
|
48
48
|
Requires-Dist: tqdm
|
|
49
49
|
Requires-Dist: typer
|
|
50
|
+
Requires-Dist: universal-pathlib>=0.3.10
|
|
50
51
|
Requires-Dist: xmltodict
|
|
51
52
|
Provides-Extra: all
|
|
52
53
|
Requires-Dist: ipython; extra == 'all'
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
+
import os
|
|
5
6
|
from pathlib import Path
|
|
6
7
|
from typing import Annotated, Any
|
|
7
8
|
|
|
@@ -33,6 +34,8 @@ OtherPathField = Annotated[
|
|
|
33
34
|
def _coerce_path(value: Any) -> Path:
|
|
34
35
|
if isinstance(value, Path):
|
|
35
36
|
return value
|
|
37
|
+
if isinstance(value, OtherPath):
|
|
38
|
+
return Path(os.fspath(value))
|
|
36
39
|
return Path(value)
|
|
37
40
|
|
|
38
41
|
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
"""Connection helpers and the public ``OtherPath`` export."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import logging
|
|
6
|
+
import os
|
|
7
|
+
import pathlib
|
|
8
|
+
import time
|
|
9
|
+
from typing import Any, Dict, Optional, Union
|
|
10
|
+
|
|
11
|
+
from cellpy.exceptions import UnderDefined
|
|
12
|
+
from cellpy.internals.otherpath import (
|
|
13
|
+
ENV_VAR_CELLPY_KEY_FILENAME,
|
|
14
|
+
ENV_VAR_CELLPY_PASSWORD,
|
|
15
|
+
IMPLEMENTED_PROTOCOLS,
|
|
16
|
+
OtherPath,
|
|
17
|
+
URI_PREFIXES,
|
|
18
|
+
get_otherpath_class,
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
__all__ = [
|
|
22
|
+
"OtherPath",
|
|
23
|
+
"URI_PREFIXES",
|
|
24
|
+
"IMPLEMENTED_PROTOCOLS",
|
|
25
|
+
"ENV_VAR_CELLPY_KEY_FILENAME",
|
|
26
|
+
"ENV_VAR_CELLPY_PASSWORD",
|
|
27
|
+
"check_connection",
|
|
28
|
+
"get_otherpath_class",
|
|
29
|
+
]
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def check_connection(
|
|
33
|
+
p: Optional[Union[str, pathlib.Path, OtherPath]] = None,
|
|
34
|
+
) -> Dict[str, Any]:
|
|
35
|
+
"""Probe a remote ``OtherPath`` (or configured ``rawdatadir``).
|
|
36
|
+
|
|
37
|
+
Uses UPath/fsspec instead of Fabric. Intended as a user-facing diagnostic.
|
|
38
|
+
"""
|
|
39
|
+
logging.debug("checking connection")
|
|
40
|
+
if p is None:
|
|
41
|
+
print("No path given. Checking rawdatadir from prms.")
|
|
42
|
+
import cellpy.config as config
|
|
43
|
+
|
|
44
|
+
p = config.paths.rawdatadir
|
|
45
|
+
|
|
46
|
+
# Recreate so isinstance checks work even if the object crossed import boundaries.
|
|
47
|
+
p = OtherPath(p)
|
|
48
|
+
logging.debug("p: %s", p)
|
|
49
|
+
|
|
50
|
+
print("\nCollecting connection information:")
|
|
51
|
+
|
|
52
|
+
if not p.is_external:
|
|
53
|
+
print(f" - {p} is not external. Returning.")
|
|
54
|
+
return {}
|
|
55
|
+
|
|
56
|
+
info: Dict[str, Any] = {
|
|
57
|
+
"is_external": p.is_external,
|
|
58
|
+
"uri_prefix": p.uri_prefix,
|
|
59
|
+
"location": p.location,
|
|
60
|
+
"raw_path": p.raw_path,
|
|
61
|
+
"full_path": p.full_path,
|
|
62
|
+
"host": p.location,
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
scheme = p.uri_prefix.replace("//", "")
|
|
66
|
+
info["uri_prefix"] = scheme
|
|
67
|
+
if scheme not in URI_PREFIXES:
|
|
68
|
+
print(f" - uri_prefix {scheme} not recognized")
|
|
69
|
+
if scheme not in IMPLEMENTED_PROTOCOLS:
|
|
70
|
+
print(f" - uri_prefix {scheme.replace(':', '')} not implemented yet")
|
|
71
|
+
|
|
72
|
+
password = os.getenv(ENV_VAR_CELLPY_PASSWORD, None)
|
|
73
|
+
info["password"] = "********" if password is not None else None
|
|
74
|
+
|
|
75
|
+
key_filename = os.getenv(ENV_VAR_CELLPY_KEY_FILENAME, None)
|
|
76
|
+
if password is None and key_filename is None:
|
|
77
|
+
print(
|
|
78
|
+
f" - You must define either {ENV_VAR_CELLPY_PASSWORD} "
|
|
79
|
+
f"or {ENV_VAR_CELLPY_KEY_FILENAME} environment variables."
|
|
80
|
+
)
|
|
81
|
+
if key_filename is not None:
|
|
82
|
+
key_path = pathlib.Path(key_filename).expanduser().resolve()
|
|
83
|
+
info["key_filename"] = str(key_path)
|
|
84
|
+
if not key_path.is_file():
|
|
85
|
+
print(f" - Could not find key file {key_path}")
|
|
86
|
+
else:
|
|
87
|
+
print(" - Using password")
|
|
88
|
+
|
|
89
|
+
for key, value in info.items():
|
|
90
|
+
print(f" {key}: {value}")
|
|
91
|
+
|
|
92
|
+
print("\nChecking connection:")
|
|
93
|
+
t0 = time.perf_counter()
|
|
94
|
+
try:
|
|
95
|
+
connect_kwargs, host = p.connection_info()
|
|
96
|
+
info["connect_kwargs_keys"] = sorted(connect_kwargs)
|
|
97
|
+
exists = p.exists()
|
|
98
|
+
print(f" exists() [{time.perf_counter() - t0:.2f} seconds] {'OK' if exists else 'MISSING'}")
|
|
99
|
+
info["exists"] = exists
|
|
100
|
+
if exists and p.is_dir():
|
|
101
|
+
children = list(p.listdir(levels=0))
|
|
102
|
+
n_files = sum(1 for c in children if c.is_file())
|
|
103
|
+
n_dirs = sum(1 for c in children if c.is_dir())
|
|
104
|
+
info["number_of_files"] = n_files
|
|
105
|
+
info["number_of_sub_directories"] = n_dirs
|
|
106
|
+
print(f" listing [{time.perf_counter() - t0:.2f} seconds] OK")
|
|
107
|
+
print(f" found {n_files} files and {n_dirs} sub directories")
|
|
108
|
+
elif not exists:
|
|
109
|
+
print(f" - Path does not exist on {host}: {p.raw_path}")
|
|
110
|
+
except UnderDefined as exc:
|
|
111
|
+
print(f" - UnderDefined: {exc}")
|
|
112
|
+
except Exception as exc: # noqa: BLE001 - diagnostic helper should surface any failure
|
|
113
|
+
print(f" - Could not connect to {p.location}")
|
|
114
|
+
print(f" {exc}")
|
|
115
|
+
|
|
116
|
+
return info
|