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.
Files changed (400) hide show
  1. cellpy-2.0.0a2/.issueflows/03-solved-issues/issue375_original.md +53 -0
  2. cellpy-2.0.0a2/.issueflows/03-solved-issues/issue375_plan.md +123 -0
  3. cellpy-2.0.0a2/.issueflows/03-solved-issues/issue375_status.md +17 -0
  4. cellpy-2.0.0a2/.issueflows/04-designs-and-guides/otherpath-upath.md +19 -0
  5. cellpy-2.0.0a2/.issueflows/04-designs-and-guides/release-procedure.md +179 -0
  6. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/04-designs-and-guides/testing-and-coverage.md +11 -0
  7. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/HISTORY.md +8 -0
  8. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/PKG-INFO +3 -2
  9. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/config/types.py +3 -0
  10. cellpy-2.0.0a2/cellpy/internals/__init__.py +11 -0
  11. cellpy-2.0.0a2/cellpy/internals/connections.py +116 -0
  12. cellpy-2.0.0a2/cellpy/internals/otherpath.py +469 -0
  13. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/__init__.py +0 -1
  14. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/cellreader.py +5 -0
  15. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/filefinder.py +29 -78
  16. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/utils/batch.py +6 -2
  17. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/utils/batch_tools/batch_journals.py +3 -1
  18. cellpy-2.0.0a2/docker/sftp-test/README.md +21 -0
  19. cellpy-2.0.0a2/docker/sftp-test/compose.yml +23 -0
  20. cellpy-2.0.0a2/docker/sftp-test/data/hello.txt +1 -0
  21. cellpy-2.0.0a2/docker/sftp-test/data/nested/sample.txt +1 -0
  22. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/pyproject.toml +3 -1
  23. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/uv.lock +35 -82
  24. cellpy-2.0.0a1/.issueflows/04-designs-and-guides/release-procedure.md +0 -128
  25. cellpy-2.0.0a1/cellpy/internals/__init__.py +0 -10
  26. cellpy-2.0.0a1/cellpy/internals/connections.py +0 -172
  27. cellpy-2.0.0a1/cellpy/internals/otherpath.py +0 -1358
  28. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.aliases +0 -0
  29. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.cursor/commands/build.md +0 -0
  30. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.cursor/commands/create-original-issue-file.md +0 -0
  31. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.cursor/rules/cellpy-core-migration.mdc +0 -0
  32. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.cursor/rules/cellpy-workspace.mdc +0 -0
  33. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.cursor/rules/graphify.mdc +0 -0
  34. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.cursor/rules/issueflow-rules.mdc +0 -0
  35. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.cursor/rules/kiss.mdc +0 -0
  36. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.cursor/rules/this-project.mdc +0 -0
  37. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.cursor/skills/caveman/SKILL.md +0 -0
  38. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.cursor/skills/grill-me/SKILL.md +0 -0
  39. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.cursor/skills/iflow/SKILL.md +0 -0
  40. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.cursor/skills/iflow-archive/SKILL.md +0 -0
  41. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.cursor/skills/iflow-cleanup/SKILL.md +0 -0
  42. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.cursor/skills/iflow-close/SKILL.md +0 -0
  43. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.cursor/skills/iflow-comments/SKILL.md +0 -0
  44. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.cursor/skills/iflow-cycle/SKILL.md +0 -0
  45. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.cursor/skills/iflow-epic/SKILL.md +0 -0
  46. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.cursor/skills/iflow-fix/SKILL.md +0 -0
  47. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.cursor/skills/iflow-graphify/SKILL.md +0 -0
  48. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.cursor/skills/iflow-history-update/SKILL.md +0 -0
  49. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.cursor/skills/iflow-init/SKILL.md +0 -0
  50. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.cursor/skills/iflow-pause/SKILL.md +0 -0
  51. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.cursor/skills/iflow-pick/SKILL.md +0 -0
  52. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.cursor/skills/iflow-plan/SKILL.md +0 -0
  53. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.cursor/skills/iflow-start/SKILL.md +0 -0
  54. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.cursor/skills/iflow-status/SKILL.md +0 -0
  55. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.cursor/skills/iflow-version-bump/SKILL.md +0 -0
  56. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.cursor/skills/iflow-yolo/SKILL.md +0 -0
  57. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.cursor/skills/issueflow-build/SKILL.md +0 -0
  58. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.dockerignore +0 -0
  59. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.editorconfig +0 -0
  60. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.env_example +0 -0
  61. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.gitattributes +0 -0
  62. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.gitignore +0 -0
  63. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/00-tools/.gitkeep +0 -0
  64. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/00-tools/README.md +0 -0
  65. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/00-tools/migrate_prms_calls.py +0 -0
  66. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/00-tools/scan_hardcoded_headers.py +0 -0
  67. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/00-tools/scan_member_usage.py +0 -0
  68. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/01-current-issues/.gitkeep +0 -0
  69. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/02-partly-solved-issues/.gitkeep +0 -0
  70. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/02-partly-solved-issues/issue453_original.md +0 -0
  71. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/02-partly-solved-issues/issue453_plan.md +0 -0
  72. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/02-partly-solved-issues/issue453_status.md +0 -0
  73. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/02-partly-solved-issues/issue459_original.md +0 -0
  74. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/.gitkeep +0 -0
  75. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/2026-07-09_archived_issues.md +0 -0
  76. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue372_original.md +0 -0
  77. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue372_plan.md +0 -0
  78. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue372_status.md +0 -0
  79. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue381_original.md +0 -0
  80. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue381_plan.md +0 -0
  81. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue381_status.md +0 -0
  82. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue391_original.md +0 -0
  83. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue391_plan.md +0 -0
  84. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue391_status.md +0 -0
  85. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue407_original.md +0 -0
  86. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue407_plan.md +0 -0
  87. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue407_status.md +0 -0
  88. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue415_original.md +0 -0
  89. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue415_plan.md +0 -0
  90. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue415_status.md +0 -0
  91. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue425_original.md +0 -0
  92. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue425_status.md +0 -0
  93. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue428_original.md +0 -0
  94. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue428_plan.md +0 -0
  95. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue428_status.md +0 -0
  96. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue429_original.md +0 -0
  97. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue429_plan.md +0 -0
  98. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue429_status.md +0 -0
  99. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue430_original.md +0 -0
  100. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue430_plan.md +0 -0
  101. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue430_status.md +0 -0
  102. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue431_original.md +0 -0
  103. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue431_plan.md +0 -0
  104. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue431_status.md +0 -0
  105. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue432_original.md +0 -0
  106. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue432_plan.md +0 -0
  107. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue432_status.md +0 -0
  108. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue433_original.md +0 -0
  109. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue433_plan.md +0 -0
  110. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue433_status.md +0 -0
  111. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue434_original.md +0 -0
  112. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue434_plan.md +0 -0
  113. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue434_status.md +0 -0
  114. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue435_original.md +0 -0
  115. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue435_plan.md +0 -0
  116. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue435_status.md +0 -0
  117. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue436_original.md +0 -0
  118. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue436_plan.md +0 -0
  119. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue436_status.md +0 -0
  120. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue437_original.md +0 -0
  121. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue437_plan.md +0 -0
  122. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue437_status.md +0 -0
  123. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue438_original.md +0 -0
  124. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue438_plan.md +0 -0
  125. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue438_status.md +0 -0
  126. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue439_original.md +0 -0
  127. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue439_plan.md +0 -0
  128. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue439_status.md +0 -0
  129. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue446_original.md +0 -0
  130. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue446_plan.md +0 -0
  131. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue446_status.md +0 -0
  132. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue447_original.md +0 -0
  133. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue447_plan.md +0 -0
  134. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue447_status.md +0 -0
  135. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue449_original.md +0 -0
  136. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue449_plan.md +0 -0
  137. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue449_status.md +0 -0
  138. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue450_original.md +0 -0
  139. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue450_plan.md +0 -0
  140. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue450_status.md +0 -0
  141. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue451_original.md +0 -0
  142. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue451_plan.md +0 -0
  143. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue451_status.md +0 -0
  144. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue452_original.md +0 -0
  145. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue452_plan.md +0 -0
  146. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue452_status.md +0 -0
  147. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue454_original.md +0 -0
  148. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue454_plan.md +0 -0
  149. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue454_status.md +0 -0
  150. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue455_original.md +0 -0
  151. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue455_plan.md +0 -0
  152. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue455_status.md +0 -0
  153. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue457_original.md +0 -0
  154. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue457_plan.md +0 -0
  155. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue457_status.md +0 -0
  156. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue458_original.md +0 -0
  157. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue458_plan.md +0 -0
  158. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue458_status.md +0 -0
  159. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue465_original.md +0 -0
  160. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue465_plan.md +0 -0
  161. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue465_status.md +0 -0
  162. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue466_original.md +0 -0
  163. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue466_plan.md +0 -0
  164. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue466_status.md +0 -0
  165. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue467_original.md +0 -0
  166. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue476_original.md +0 -0
  167. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue476_plan.md +0 -0
  168. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue476_status.md +0 -0
  169. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue479_original.md +0 -0
  170. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue479_plan.md +0 -0
  171. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue479_status.md +0 -0
  172. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue491_original.md +0 -0
  173. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue491_status.md +0 -0
  174. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue510_original.md +0 -0
  175. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue510_plan.md +0 -0
  176. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/03-solved-issues/issue510_status.md +0 -0
  177. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/04-designs-and-guides/.gitkeep +0 -0
  178. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/04-designs-and-guides/bdf-export.md +0 -0
  179. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/04-designs-and-guides/build-and-versioning.md +0 -0
  180. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/04-designs-and-guides/cellpy-v2-architecture.excalidraw +0 -0
  181. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/04-designs-and-guides/cellpy-v2-branching.md +0 -0
  182. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/04-designs-and-guides/cellpy-v2-epic.md +0 -0
  183. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/04-designs-and-guides/cellpy-workspace-repos.md +0 -0
  184. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/04-designs-and-guides/cellpycell-di-restructuring.md +0 -0
  185. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/04-designs-and-guides/ci-tiers.md +0 -0
  186. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/04-designs-and-guides/filters-and-plot-filtering.md +0 -0
  187. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/04-designs-and-guides/this-project.md +0 -0
  188. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/04-designs-and-guides/v2-cellpycore-pin-gate.md +0 -0
  189. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.issueflows/05-epics/.gitkeep +0 -0
  190. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/.readthedocs.yaml +0 -0
  191. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/AGENTS.md +0 -0
  192. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/AUTHORS.md +0 -0
  193. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/CODE_OF_CONDUCT.md +0 -0
  194. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/CONTRIBUTING.md +0 -0
  195. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/DEPRECATIONS.md +0 -0
  196. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/LICENSE.md +0 -0
  197. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/README.md +0 -0
  198. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/_old_docs/_developers_guide/dev_cellpy_data_structure.md +0 -0
  199. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/_old_docs/_developers_guide/dev_cellpy_folder_structure.md +0 -0
  200. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/_old_docs/_developers_guide/dev_cellpy_packaging_pypi.md +0 -0
  201. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/_old_docs/_developers_guide/dev_cellpy_setup.md +0 -0
  202. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/_old_docs/_developers_guide/dev_conda_package.md +0 -0
  203. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/_old_docs/_developers_guide/dev_docs.md +0 -0
  204. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/_old_docs/_developers_guide/dev_loaders_and_instruments.md +0 -0
  205. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/_old_docs/_developers_guide/dev_various.md +0 -0
  206. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/_old_docs/_developers_guide/index.md +0 -0
  207. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/_old_docs/_examples_and_tutorials/basic_interactions/01_getting_started_tutorial.md +0 -0
  208. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/_old_docs/_examples_and_tutorials/basic_interactions/02_read_cell_data.md +0 -0
  209. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/_old_docs/_examples_and_tutorials/basic_interactions/03_more_about_get.md +0 -0
  210. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/_old_docs/_examples_and_tutorials/basic_interactions/04_other_interactions.md +0 -0
  211. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/_old_docs/_examples_and_tutorials/basic_interactions/05_configuring.md +0 -0
  212. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/_old_docs/_examples_and_tutorials/basic_interactions/06_pandas.md +0 -0
  213. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/_old_docs/_examples_and_tutorials/basic_interactions/07_data_mining.md +0 -0
  214. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/_old_docs/_examples_and_tutorials/basic_interactions/08_the_cellpy_cmd.md +0 -0
  215. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/_old_docs/_examples_and_tutorials/basics.md +0 -0
  216. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/_old_docs/_examples_and_tutorials/examples.md +0 -0
  217. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/_old_docs/_examples_and_tutorials/index.md +0 -0
  218. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/_old_docs/_examples_and_tutorials/loaders/01_arbin.md +0 -0
  219. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/_old_docs/_examples_and_tutorials/loaders/02_maccor.md +0 -0
  220. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/_old_docs/_examples_and_tutorials/loaders/03_PEC.md +0 -0
  221. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/_old_docs/_examples_and_tutorials/loaders/04_Neware.md +0 -0
  222. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/_old_docs/_examples_and_tutorials/loaders/05_biologics.md +0 -0
  223. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/_old_docs/_examples_and_tutorials/loaders/06_custom.md +0 -0
  224. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/_old_docs/_examples_and_tutorials/loaders.md +0 -0
  225. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/_old_docs/_examples_and_tutorials/notebooks/images/templates_jupyterlab_001.png +0 -0
  226. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/_old_docs/_examples_and_tutorials/notebooks/images/templates_jupyterlab_002.png +0 -0
  227. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/_old_docs/_examples_and_tutorials/notebooks/tutorial_get_cap.ipynb +0 -0
  228. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/_old_docs/_examples_and_tutorials/notebooks/tutorial_simple_plot.ipynb +0 -0
  229. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/_old_docs/_examples_and_tutorials/notebooks/tutorial_templates.ipynb +0 -0
  230. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/_old_docs/_examples_and_tutorials/notebooks/tutorial_xxx-checkpoint.ipynb +0 -0
  231. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/_old_docs/_examples_and_tutorials/notebooks.md +0 -0
  232. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/_old_docs/_examples_and_tutorials/tips_and_tricks.md +0 -0
  233. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/_old_docs/_examples_and_tutorials/utils/batch.md +0 -0
  234. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/_old_docs/_examples_and_tutorials/utils/collectors.md +0 -0
  235. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/_old_docs/_examples_and_tutorials/utils/custom_file_loaders.md +0 -0
  236. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/_old_docs/_examples_and_tutorials/utils/easyplot.md +0 -0
  237. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/_old_docs/_examples_and_tutorials/utils/figures/tutorials_utils_plotting_fig1.png +0 -0
  238. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/_old_docs/_examples_and_tutorials/utils/figures/tutorials_utils_plotting_fig2.png +0 -0
  239. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/_old_docs/_examples_and_tutorials/utils/ica.md +0 -0
  240. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/_old_docs/_examples_and_tutorials/utils/plotting.md +0 -0
  241. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/_old_docs/_examples_and_tutorials/utils/templates.md +0 -0
  242. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/_old_docs/_examples_and_tutorials/utils/tut_ocv_rlx.md +0 -0
  243. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/_old_docs/_examples_and_tutorials/utils.md +0 -0
  244. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/_old_docs/_main_description/formats.md +0 -0
  245. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/_old_docs/_main_description/index.md +0 -0
  246. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/_old_docs/_main_description/installation.md +0 -0
  247. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/_old_docs/_main_description/usage.md +0 -0
  248. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/_old_docs/index.md +0 -0
  249. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/benchmarks/README.md +0 -0
  250. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/benchmarks/__init__.py +0 -0
  251. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/benchmarks/baselines/v1x_ubuntu_py313.json +0 -0
  252. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/benchmarks/check_baseline.py +0 -0
  253. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/benchmarks/conftest.py +0 -0
  254. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/benchmarks/paths.py +0 -0
  255. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/benchmarks/test_performance.py +0 -0
  256. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/__init__.py +0 -0
  257. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/_deprecation.py +0 -0
  258. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/_version.py +0 -0
  259. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/cli.py +0 -0
  260. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/config/__init__.py +0 -0
  261. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/config/legacy.py +0 -0
  262. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/config/loader.py +0 -0
  263. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/config/migrate.py +0 -0
  264. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/config/models.py +0 -0
  265. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/config/session.py +0 -0
  266. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/config/sources.py +0 -0
  267. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/exceptions.py +0 -0
  268. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/exporters/__init__.py +0 -0
  269. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/exporters/bdf.py +0 -0
  270. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/exporters/tabular.py +0 -0
  271. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/filters/__init__.py +0 -0
  272. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/filters/cycles.py +0 -0
  273. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/filters/summary.py +0 -0
  274. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/libs/__init__.py +0 -0
  275. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/libs/apipkg/__init__.py +0 -0
  276. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/libs/apipkg/_alias_module.py +0 -0
  277. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/libs/apipkg/_importing.py +0 -0
  278. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/libs/apipkg/_module.py +0 -0
  279. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/libs/apipkg/_syncronized.py +0 -0
  280. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/libs/apipkg/_version.py +0 -0
  281. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/libs/apipkg/py.typed +0 -0
  282. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/libs/local_fastnda/LICENSE +0 -0
  283. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/libs/local_fastnda/__init__.py +0 -0
  284. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/libs/local_fastnda/btsda.py +0 -0
  285. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/libs/local_fastnda/cli.py +0 -0
  286. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/libs/local_fastnda/dicts.py +0 -0
  287. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/libs/local_fastnda/formats.py +0 -0
  288. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/libs/local_fastnda/main.py +0 -0
  289. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/libs/local_fastnda/nda.py +0 -0
  290. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/libs/local_fastnda/ndax.py +0 -0
  291. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/libs/local_fastnda/utils.py +0 -0
  292. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/libs/local_fastnda/version.py +0 -0
  293. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/log.py +0 -0
  294. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/logging.json +0 -0
  295. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/parameters/.cellpy_prms_default.conf +0 -0
  296. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/parameters/__init__.py +0 -0
  297. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/parameters/_shim.py +0 -0
  298. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/parameters/internal_settings.py +0 -0
  299. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/parameters/legacy/__init__.py +0 -0
  300. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/parameters/legacy/update_headers.py +0 -0
  301. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/parameters/prmreader.py +0 -0
  302. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/parameters/prms.py +0 -0
  303. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/capacity_curves.py +0 -0
  304. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/cellpy_file/__init__.py +0 -0
  305. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/cellpy_file/dtype.py +0 -0
  306. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/cellpy_file/fids.py +0 -0
  307. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/cellpy_file/format.py +0 -0
  308. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/cellpy_file/keys.py +0 -0
  309. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/cellpy_file/legacy_read.py +0 -0
  310. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/cellpy_file/meta.py +0 -0
  311. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/cellpy_file/meta_archive.py +0 -0
  312. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/cellpy_file/read.py +0 -0
  313. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/cellpy_file/selectors.py +0 -0
  314. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/cellpy_file/translate.py +0 -0
  315. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/cellpy_file/v9.py +0 -0
  316. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/cellpy_file/write.py +0 -0
  317. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/data_structures.py +0 -0
  318. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/dbreader.py +0 -0
  319. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/do.py +0 -0
  320. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/instruments/SQL Table IDs.txt +0 -0
  321. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/instruments/__init__.py +0 -0
  322. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/instruments/arbin_res.py +0 -0
  323. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/instruments/arbin_sql.py +0 -0
  324. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/instruments/arbin_sql_7.py +0 -0
  325. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/instruments/arbin_sql_config.py +0 -0
  326. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/instruments/arbin_sql_csv.py +0 -0
  327. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/instruments/arbin_sql_h5.py +0 -0
  328. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/instruments/arbin_sql_xlsx.py +0 -0
  329. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/instruments/base.py +0 -0
  330. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/instruments/batmo_bdf.py +0 -0
  331. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/instruments/biologics_mpr.py +0 -0
  332. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/instruments/configurations/__init__.py +0 -0
  333. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/instruments/configurations/batmo_bdf_bdf.py +0 -0
  334. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/instruments/configurations/maccor_txt_one.py +0 -0
  335. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/instruments/configurations/maccor_txt_three.py +0 -0
  336. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/instruments/configurations/maccor_txt_two.py +0 -0
  337. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/instruments/configurations/maccor_txt_zero.py +0 -0
  338. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/instruments/configurations/neware_txt_one.py +0 -0
  339. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/instruments/configurations/neware_txt_two.py +0 -0
  340. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/instruments/configurations/neware_txt_zero.py +0 -0
  341. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/instruments/custom.py +0 -0
  342. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/instruments/ext_nda_reader.py +0 -0
  343. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/instruments/loader_specific_modules/__init__.py +0 -0
  344. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/instruments/loader_specific_modules/biologic_file_format.py +0 -0
  345. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/instruments/local_instrument.py +0 -0
  346. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/instruments/maccor_txt.py +0 -0
  347. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/instruments/neware_nda.py +0 -0
  348. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/instruments/neware_txt.py +0 -0
  349. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/instruments/neware_xlsx.py +0 -0
  350. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/instruments/pec_csv.py +0 -0
  351. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/instruments/processors/__init__.py +0 -0
  352. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/instruments/processors/post_processors.py +0 -0
  353. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/instruments/processors/pre_processors.py +0 -0
  354. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/json_dbreader.py +0 -0
  355. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/merger.py +0 -0
  356. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/native_core.py +0 -0
  357. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/slicing.py +0 -0
  358. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/sql_dbreader.py +0 -0
  359. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/readers/test_meta.py +0 -0
  360. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/utils/__init__.py +0 -0
  361. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/utils/batch_tools/__init__.py +0 -0
  362. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/utils/batch_tools/batch_analyzers.py +0 -0
  363. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/utils/batch_tools/batch_core.py +0 -0
  364. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/utils/batch_tools/batch_experiments.py +0 -0
  365. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/utils/batch_tools/batch_exporters.py +0 -0
  366. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/utils/batch_tools/batch_helpers.py +0 -0
  367. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/utils/batch_tools/batch_plotters.py +0 -0
  368. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/utils/batch_tools/batch_reporters.py +0 -0
  369. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/utils/batch_tools/dumpers.py +0 -0
  370. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/utils/batch_tools/engines.py +0 -0
  371. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/utils/batch_tools/sqlite_from_excel_db.py +0 -0
  372. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/utils/collectors.py +0 -0
  373. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/utils/diagnostics.py +0 -0
  374. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/utils/easyplot.py +0 -0
  375. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/utils/example_data.py +0 -0
  376. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/utils/helpers.py +0 -0
  377. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/utils/ica.py +0 -0
  378. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/utils/live.py +0 -0
  379. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/utils/ocv_rlx.py +0 -0
  380. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/utils/plotutils.py +0 -0
  381. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/utils/processor.py +0 -0
  382. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/cellpy/utils/template_registry.py +0 -0
  383. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/dev/conda-recipes/README.md +0 -0
  384. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/dev/conda-recipes/cellpy/meta.yaml +0 -0
  385. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/dev/conda-recipes/cellpycore/meta.yaml +0 -0
  386. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/dev/regenerate_goldens.py +0 -0
  387. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/docker/Dockerfile.build-test +0 -0
  388. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/environment.yml +0 -0
  389. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/environment_dev.yml +0 -0
  390. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/github_actions_environment.yml +0 -0
  391. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/noxfile.py +0 -0
  392. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/paper/.github/workflows/draft-pdf.yml +0 -0
  393. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/paper/.gitignore +0 -0
  394. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/paper/Figures/Cellpy-Utils.jpg +0 -0
  395. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/paper/Figures/CellpyCell.jpg +0 -0
  396. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/paper/Figures/CellpyData.jpg +0 -0
  397. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/paper/paper.bib +0 -0
  398. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/paper/paper.md +0 -0
  399. {cellpy-2.0.0a1 → cellpy-2.0.0a2}/scripts/build_test.sh +0 -0
  400. {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.0a1
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,11 @@
1
+ """Internal helpers (paths, lazy optional deps)."""
2
+
3
+ # Kept for historical import compatibility; Fabric is no longer a dependency.
4
+ from cellpy.libs.apipkg import initpkg
5
+
6
+ initpkg(
7
+ __name__,
8
+ {
9
+ "externals": {},
10
+ },
11
+ )
@@ -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