Annie Voigt commited on
Commit ·
9c88c1e
1
Parent(s): 25b085e
refactor: move writable-dir constants to core.paths, fix workflow->tools layer violation
Browse filesOUTPUT_DIR/INPUT_DIR/GEO_CACHE_DIR + _resolve_dir lived in src/tools/rna/_base.py,
so src/workflows/integration.py imported upward from the tools layer to reach
OUTPUT_DIR -- a dependency-direction violation (tools sits above workflows).
These are shared infrastructure (env-resolved writable dirs) both layers need, so
they belong in core. Move them to src/core/paths.py; _base.py re-exports them
(unchanged for tool submodules) and integration.py imports from core.paths. Path
resolution is byte-for-byte identical (same base dir <root>/src, same env-var/tmp
fallback). No functional change. repo-quality-monitor architecture check: 0 findings.
- src/core/paths.py +43 -0
- src/tools/rna/_base.py +8 -26
- src/workflows/integration.py +1 -1
src/core/paths.py
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""
|
| 2 |
+
Writable directory resolution for the agent.
|
| 3 |
+
|
| 4 |
+
These are shared infrastructure constants — an env-resolved input/output/cache
|
| 5 |
+
location — needed by both the ``tools`` layer (which writes analysis artifacts)
|
| 6 |
+
and the ``workflows`` layer (which writes combined datasets). They live in
|
| 7 |
+
``core`` so both layers can import them downward without violating the layering
|
| 8 |
+
contract (``tools`` and ``workflows`` both build on ``core``).
|
| 9 |
+
"""
|
| 10 |
+
|
| 11 |
+
from __future__ import annotations
|
| 12 |
+
|
| 13 |
+
import os
|
| 14 |
+
from pathlib import Path
|
| 15 |
+
|
| 16 |
+
# core/paths.py lives at <root>/src/core/, so two levels up is <root>/src —
|
| 17 |
+
# the same base directory the tool package historically resolved against.
|
| 18 |
+
PROJECT_ROOT = Path(__file__).parent.parent.resolve()
|
| 19 |
+
_DEFAULT_INPUT = PROJECT_ROOT / "tmp" / "inputs"
|
| 20 |
+
_DEFAULT_OUTPUT = PROJECT_ROOT / "tmp" / "outputs"
|
| 21 |
+
_DEFAULT_GEO_CACHE = PROJECT_ROOT / "tmp" / "geo_cache"
|
| 22 |
+
|
| 23 |
+
|
| 24 |
+
def _resolve_dir(env_var: str, project_default: Path, hf_fallback: Path) -> Path:
|
| 25 |
+
"""Return a writable directory: env var > project default > /tmp fallback."""
|
| 26 |
+
env_val = os.environ.get(env_var)
|
| 27 |
+
if env_val:
|
| 28 |
+
p = Path(env_val)
|
| 29 |
+
p.mkdir(parents=True, exist_ok=True)
|
| 30 |
+
return p
|
| 31 |
+
try:
|
| 32 |
+
project_default.mkdir(parents=True, exist_ok=True)
|
| 33 |
+
return project_default
|
| 34 |
+
except PermissionError:
|
| 35 |
+
hf_fallback.mkdir(parents=True, exist_ok=True)
|
| 36 |
+
return hf_fallback
|
| 37 |
+
|
| 38 |
+
|
| 39 |
+
INPUT_DIR = _resolve_dir("RNA_INPUT_DIR", _DEFAULT_INPUT, Path("/tmp/decoupleRpy/inputs"))
|
| 40 |
+
OUTPUT_DIR = _resolve_dir("RNA_OUTPUT_DIR", _DEFAULT_OUTPUT, Path("/tmp/decoupleRpy/outputs"))
|
| 41 |
+
GEO_CACHE_DIR = _resolve_dir(
|
| 42 |
+
"RNA_GEO_CACHE_DIR", _DEFAULT_GEO_CACHE, Path("/tmp/decoupleRpy/geo_cache")
|
| 43 |
+
)
|
src/tools/rna/_base.py
CHANGED
|
@@ -28,32 +28,14 @@ from pydeseq2.ds import DeseqStats
|
|
| 28 |
matplotlib.use("Agg")
|
| 29 |
import matplotlib.pyplot as plt
|
| 30 |
|
| 31 |
-
# Project structure
|
| 32 |
-
|
| 33 |
-
|
| 34 |
-
|
| 35 |
-
|
| 36 |
-
|
| 37 |
-
|
| 38 |
-
|
| 39 |
-
"""Return a writable directory: env var > project default > /tmp fallback."""
|
| 40 |
-
env_val = os.environ.get(env_var)
|
| 41 |
-
if env_val:
|
| 42 |
-
p = Path(env_val)
|
| 43 |
-
p.mkdir(parents=True, exist_ok=True)
|
| 44 |
-
return p
|
| 45 |
-
try:
|
| 46 |
-
project_default.mkdir(parents=True, exist_ok=True)
|
| 47 |
-
return project_default
|
| 48 |
-
except PermissionError:
|
| 49 |
-
hf_fallback.mkdir(parents=True, exist_ok=True)
|
| 50 |
-
return hf_fallback
|
| 51 |
-
|
| 52 |
-
|
| 53 |
-
INPUT_DIR = _resolve_dir("RNA_INPUT_DIR", _DEFAULT_INPUT, Path("/tmp/decoupleRpy/inputs"))
|
| 54 |
-
OUTPUT_DIR = _resolve_dir("RNA_OUTPUT_DIR", _DEFAULT_OUTPUT, Path("/tmp/decoupleRpy/outputs"))
|
| 55 |
-
GEO_CACHE_DIR = _resolve_dir(
|
| 56 |
-
"RNA_GEO_CACHE_DIR", _DEFAULT_GEO_CACHE, Path("/tmp/decoupleRpy/geo_cache")
|
| 57 |
)
|
| 58 |
|
| 59 |
# Timestamp for unique outputs
|
|
|
|
| 28 |
matplotlib.use("Agg")
|
| 29 |
import matplotlib.pyplot as plt
|
| 30 |
|
| 31 |
+
# Project structure. Writable directories now live in core.paths (shared
|
| 32 |
+
# infrastructure both tools and workflows build on); re-exported here so tool
|
| 33 |
+
# submodules keep importing them from _base unchanged.
|
| 34 |
+
from src.core.paths import ( # noqa: E402
|
| 35 |
+
GEO_CACHE_DIR,
|
| 36 |
+
INPUT_DIR,
|
| 37 |
+
OUTPUT_DIR,
|
| 38 |
+
PROJECT_ROOT,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 39 |
)
|
| 40 |
|
| 41 |
# Timestamp for unique outputs
|
src/workflows/integration.py
CHANGED
|
@@ -38,7 +38,7 @@ from typing import TYPE_CHECKING
|
|
| 38 |
import anndata as ad
|
| 39 |
import numpy as np
|
| 40 |
|
| 41 |
-
from src.
|
| 42 |
|
| 43 |
if TYPE_CHECKING:
|
| 44 |
from anndata import AnnData
|
|
|
|
| 38 |
import anndata as ad
|
| 39 |
import numpy as np
|
| 40 |
|
| 41 |
+
from src.core.paths import OUTPUT_DIR
|
| 42 |
|
| 43 |
if TYPE_CHECKING:
|
| 44 |
from anndata import AnnData
|